samba 访客访问
When building an awesome web app or website, we sometimes want people to be able to embed parts of our web app/website into their own. That could be an iframe holding a ‘like’ button, a simple image that they want to reuse or even our entire app embedded in an iframe.
在构建出色的Web应用程序或网站时,有时我们希望人们能够将我们的Web应用程序/网站的一部分嵌入到自己的网站中。 这可能是持有“喜欢”按钮的iframe,他们想要重用的简单图像,甚至是嵌入在iframe中的整个应用。
But how do we control who has access, who is allowed to use up our bandwidth and query our service?
但是,我们如何控制谁可以访问,谁可以用尽我们的带宽并查询我们的服务呢?
We define the problem as controlling access to assets
我们将问题定义为控制对资产的 访问
By assets we mean: anything that can be queried from our site.
资产是指:可以从我们的网站查询的任何内容。
When talking about access control, we enter the domain of security. And when talking security, whitelisting should be the approach taken to tackle the problem. It is easier to control who is allowed to access your assets than it is to control who is not. It is simply impossible to know all the boogie monsters of the internet.
在谈论访问控制时,我们进入了安全领域。 在谈论安全性时,白名单应该是解决该问题的方法。 控制谁被允许访问您的资产比控制谁不被访问更容易。 根本不可能知道互联网上所有的布吉怪物。
To protect our assets, we hire a gatekeeper to only let the ones we trust in. Once hired, we give him access to a whitelist we control, and let him do all the heavy lifting. Problem solved. But how should the gatekeeper lift?
为了保护我们的资产 ,我们雇用了一个看门人,只让我们信任的人看守。雇用后,我们让他访问我们控制的白名单,并让他完成所有繁重的工作。 问题解决了。 但是看门人应该如何举起呢?
Depending on how secure you want the gatekeeper to be and what the client asked for, different tactics can be used.
根据您希望网守的安全性以及客户的要求,可以使用不同的策略。
A common approach used is checking the Referer header. That method has 3 big drawbacks:
常用的方法是检查Referer标头。 该方法有3个大缺点:
However, for static assets such as images, js and css, those drawbacks are not an issue. Your assets should only be loaded when users are visiting our website directly (or from a trusted site). The general idea is to block others hotlinking them. The referer will thus always be on your whitelist. Unless you don’t trust yourself – but then you have bigger issues.
但是,对于静态资产(例如图像,js和CSS),这些缺点不是问题。 仅当用户直接(或从受信任的站点)访问我们的网站时,才加载您的资产。 总体思路是阻止其他人对其进行热链接。 因此,引荐来源将始终在您的白名单上。 除非您不信任自己-否则您将面临更大的问题。
Depending on the setup used, the query made passes through a series of gates. The simple setup is: Client -> HTTP server -> application code
根据使用的设置,查询通过一系列的Gates传递。 简单的设置是:客户端-> HTTP服务器->应用程序代码
So where does your gatekeeper sit? The client is a de facto no go for access control because he is an unreliable lying piece of human. The HTTP server and the application code on the other hand are useful options. Both give us strong tools to check the HTTP_HOST
.
那你的网守坐在哪儿呢? 客户实际上是无法进行访问控制的,因为他是一个不可靠的说谎者。 另一方面,HTTP服务器和应用程序代码是有用的选项。 两者都为我们提供了强大的工具来检查HTTP_HOST
。
The strength in having your HTTP server handle your access control is speed. There is no need to fire up the application code for every request. This can drastically improve performance because we do not need to load an entire application stack/thread (e.g. mod_php) into memory.
让HTTP服务器处理访问控制的优势在于速度。 无需为每个请求启动应用程序代码。 这可以大大提高性能,因为我们不需要将整个应用程序堆栈/线程(例如mod_php)加载到内存中。
Depending on your HTTP server, different solutions are available.
根据您的HTTP服务器,可以使用不同的解决方案。
In Apache, there are two different methods. We can use mod_rewrite or Allow/Deny.
在Apache中,有两种不同的方法。 我们可以使用mod_rewrite或Allow / Deny。
The mod_rewrite method:
mod_rewrite方法:
# Turn mod_rewrite on
RewriteEngine On
# if it is not trusted.domain.tld block it
RewriteCond %{HTTP_REFERER} !^trusted\.domain\.tld$ [NC]
RewriteCond %{HTTP_REFERER} !^trusted\.tld$ [NC]
RewriteRule ^ - [F]
mod_rewrite is supported by most hosting providers.
大多数托管服务提供商都支持mod_rewrite。
The Allow/Deny method:
允许/拒绝方法:
#specify the files to guard, block all the assets
#block everyone
Deny from all
#allow trusted ones
Allow from trusted.tld trusted.domain.tld
Not all hosts support those settings.
并非所有主机都支持这些设置。
The HttpRefererModule in nginx gives us the really cool valid_referers
: So all that we need to do is, return http code 444 when a non-trusted domain tries to access our assets:
nginx中的HttpRefererModule为我们提供了非常酷的valid_referers
:因此,我们要做的就是,当非受信任的域尝试访问我们的资产时,返回http代码444:
… nonstandard code 444 closes the connection without sending any headers…
…非标准代码444在不发送任何标头的情况下关闭了连接…
location / {
valid_referers trusted.tld trusted.domain.tld;
if ($invalid_referer) {
return 444;
}
}
The big problem here is scalability: what if we have 1000 domains that need to be able to access our assets? What if the list of domains changes frequently?
这里最大的问题是可伸缩性:如果我们有1000个需要访问我们资产的域怎么办? 如果域列表经常更改怎么办?
For every little edit, we would need to dive into our configuration files – and the more you change manually, the more can go wrong.
对于每个小小的编辑,我们都需要深入研究我们的配置文件-手动更改的次数越多,出错的可能性就越大。
Having your access control on your application code level means a lot more flexibility. One could have his gatekeeper up and running in no time:
在应用程序代码级别上具有访问控制意味着更大的灵活性。 可以立即让他的网守启动并运行:
As mentioned, relying on the referer isn’t always a good idea. It is not only data from our unreliable human, it also gives us no clue as to whether we are in an iframe or not. There is simply no way of knowing.
如前所述,依靠引用者并不总是一个好主意。 这不仅是来自我们不可靠人类的数据,也没有提供关于我们是否处于iframe中的任何线索。 根本没有办法知道。
We could however hire a hitman to help our GateKeeper. Our hitman will be dispatched to the humans that look suspicious (e.g. the ones with an untrusted referer). The hitman will use JS as his weapon:
但是,我们可以雇用杀手来帮助GateKeeper。 我们的杀手将被派往看似可疑的人(例如,具有不可靠引荐来源的人)。 杀手将使用JS作为他的武器:
document.getElementById('container').innerHTML = '';
alert('You just got killed');
Sadly enough, someone arriving from an untrusted domain has the same referer as someone else that accesses us using an iframe from that untrusted domain. Assets, however, will have the referer set to our domain (even in an iframe situation) – so sending a hitman here is overkill. Simply denying access is enough – or you could send a random kitten image.
令人遗憾的是,来自不受信任域的某人与使用来自该不受信任域的iframe访问我们的其他人具有相同的引荐来源。 但是,资产将把引荐来源设置为我们的域(即使在iframe情况下),因此在此处派出杀手实在是太过分了。 只需拒绝访问就足够了,或者您可以发送随机的小猫图像 。
That is why we have our hitman check if we are in an iframe. If so, we have him kill our target:
这就是为什么我们要让杀手检查是否在iframe中。 如果是这样,我们让他杀死我们的目标:
if (top.location.href != self.location.href) {
//kill the target
}
The only thing we need to do know is to have our GateKeeper add the hitman to the payload sent to the client. Easy!
我们唯一需要知道的是让GateGeeper将杀手添加到发送给客户端的有效负载中。 简单!
//template.tpl
If ( Gatekeeper::doesNotApprove() )
{
Gatekeeper::sendHitman();
}
//gatekeeper
class Gatekeeper
{
private static $whitelist = array();
public static function doesNotApprove()
{
return !in_array(
parse_url($_SERVER["HTTP_REFERER"], PHP_URL_HOST),
self::$whitelist
);
}
public static function sendHitman()
{
print '';
}
}
This code is not production proof. It serves as an example.
该代码不是生产证明。 以此为例。
The solutions supplied here will guard you against most boogie monsters. But both solutions are not fool proof. The first uses data from the client, the second is javascript that is run by the client.
这里提供的解决方案将保护您免受大多数布吉怪物的侵害。 但是,这两种解决方案都不是万无一失的。 第一个使用来自客户端的数据,第二个使用由客户端运行的javascript。
The secure way is to use a token-based GateKeeper. OAuth is probably the guy you want for the job here, but that is outside of the scope of this article.
安全的方法是使用基于令牌的GateKeeper。 OAuth可能是您想要在此工作的人,但这超出了本文的范围。
翻译自: https://www.sitepoint.com/asset-access-restriction-methods-block-unwanted-visitors/
samba 访客访问