How can I check whether a request being received is sent from the same server??
如何检查收到的请求是否从同一服务器发送?
Say, I've my domain at www.domain.com. Now I've php processing files which will process forms hosted through this domain. This processes will be executed only if the requests are sent from within the domain ie. www.domain.com and any other requests sent from other domains will be discarded.
说,我的域名是www.domain.com。现在我有php处理文件,它们将处理通过这个域托管的表单。只有在域内发送请求时才会执行此过程,即。 www.domain.com以及从其他域发送的任何其他请求将被丢弃。
3 个解决方案
#1
51
Basically : you cannot.
With the HTTP protocol, each request is independent from the others.
基本上:你不能。使用HTTP协议,每个请求都独立于其他请求。
A first idea would be to check the Referer HTTP header, but note that :
第一个想法是检查Referer HTTP标头,但请注意:
- It can be faked (it's sent by the browser)
- It is not always present.
它可以是伪造的(它是由浏览器发送的)
它并不总是存在。
So : not a reliable solution.
所以:不是可靠的解决方案。
A possible, and far better than the Referer idea, solution could be to use a nonce :
一个可能的,远比Referer想法更好的解决方案可能是使用一个nonce:
- When displaying the form, put a hidden input field in it, containing a random value
- At the same time, store that random value into the session that correspond to the user.
- When the form is submitted, check that the hidden field has the same value as the one that's stored in session.
显示表单时,在其中放入一个包含随机值的隐藏输入字段
同时,将该随机值存储到与用户对应的会话中。
提交表单时,请检查隐藏字段是否与存储在会话中的字段具有相同的值。
If those two values are not the same, refuse to use the submitted data.
如果这两个值不相同,则拒绝使用提交的数据。
Note : this idea is often used to help fight against CSRF -- and integrated in the "Form" component of some Frameworks (Zend Framework, for instance).
注意:这个想法通常用于帮助对抗CSRF - 并集成在某些框架(例如Zend框架)的“表单”组件中。
#2
5
this will check if there is a referer, then it will compare it with current domain, if different then it is from outside referer
这将检查是否有引用,然后它将它与当前域进行比较,如果不同则它来自外部引用
if ((isset($_SERVER['HTTP_REFERER']) && !empty($_SERVER['HTTP_REFERER']))) {
if (strtolower(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST)) != strtolower($_SERVER['HTTP_HOST'])) {
// referer not from the same domain
}
}
#3
0
I know this is an old thread, but some one else can probably find it relevant.
我知道这是一个旧线程,但其他人可能会发现它相关。
The answer is: Yes you can. But it depends if your Apache/nginx server is set to populate the $_SERVER variable with the required information. Most the server are, so probably you can use this approach.
答案是:是的,你可以。但这取决于您的Apache / nginx服务器是否设置为使用所需信息填充$ _SERVER变量。大多数服务器都是,所以可能你可以使用这种方法。
What you need to do is to extract the HTTP_REFERER from the $_SERVER variable and compare with your domain.
您需要做的是从$ _SERVER变量中提取HTTP_REFERER并与您的域进行比较。
<?php
function requestedByTheSameDomain() {
$myDomain = $_SERVER['SCRIPT_URI'];
$requestsSource = $_SERVER['HTTP_REFERER'];
return parse_url($myDomain, PHP_URL_HOST) === parse_url($requestsSource, PHP_URL_HOST);
}
#1
51
Basically : you cannot.
With the HTTP protocol, each request is independent from the others.
基本上:你不能。使用HTTP协议,每个请求都独立于其他请求。
A first idea would be to check the Referer HTTP header, but note that :
第一个想法是检查Referer HTTP标头,但请注意:
- It can be faked (it's sent by the browser)
- It is not always present.
它可以是伪造的(它是由浏览器发送的)
它并不总是存在。
So : not a reliable solution.
所以:不是可靠的解决方案。
A possible, and far better than the Referer idea, solution could be to use a nonce :
一个可能的,远比Referer想法更好的解决方案可能是使用一个nonce:
- When displaying the form, put a hidden input field in it, containing a random value
- At the same time, store that random value into the session that correspond to the user.
- When the form is submitted, check that the hidden field has the same value as the one that's stored in session.
显示表单时,在其中放入一个包含随机值的隐藏输入字段
同时,将该随机值存储到与用户对应的会话中。
提交表单时,请检查隐藏字段是否与存储在会话中的字段具有相同的值。
If those two values are not the same, refuse to use the submitted data.
如果这两个值不相同,则拒绝使用提交的数据。
Note : this idea is often used to help fight against CSRF -- and integrated in the "Form" component of some Frameworks (Zend Framework, for instance).
注意:这个想法通常用于帮助对抗CSRF - 并集成在某些框架(例如Zend框架)的“表单”组件中。
#2
5
this will check if there is a referer, then it will compare it with current domain, if different then it is from outside referer
这将检查是否有引用,然后它将它与当前域进行比较,如果不同则它来自外部引用
if ((isset($_SERVER['HTTP_REFERER']) && !empty($_SERVER['HTTP_REFERER']))) {
if (strtolower(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST)) != strtolower($_SERVER['HTTP_HOST'])) {
// referer not from the same domain
}
}
#3
0
I know this is an old thread, but some one else can probably find it relevant.
我知道这是一个旧线程,但其他人可能会发现它相关。
The answer is: Yes you can. But it depends if your Apache/nginx server is set to populate the $_SERVER variable with the required information. Most the server are, so probably you can use this approach.
答案是:是的,你可以。但这取决于您的Apache / nginx服务器是否设置为使用所需信息填充$ _SERVER变量。大多数服务器都是,所以可能你可以使用这种方法。
What you need to do is to extract the HTTP_REFERER from the $_SERVER variable and compare with your domain.
您需要做的是从$ _SERVER变量中提取HTTP_REFERER并与您的域进行比较。
<?php
function requestedByTheSameDomain() {
$myDomain = $_SERVER['SCRIPT_URI'];
$requestsSource = $_SERVER['HTTP_REFERER'];
return parse_url($myDomain, PHP_URL_HOST) === parse_url($requestsSource, PHP_URL_HOST);
}