Checking PHP referrer
Other answers' checks' are good but are not strictly bound to your website. So for example referer with value http://attacker.com/www.example.com/
will pass almost all the checks. And it is very easy to make such site and just send a cross-domain request.
There is a reliable and secure method to check if referer is really your domain. Of course referer can be spoofed, but a victim of an attacker site will send correct referer.
The trick is in ^
special character. Here is the magic regex:
^https?://(([a-z0-9-]+)\.)*example\.com/
^
- ensures that we are at the starthttps?
- protocol - http or https(([a-z0-9-]+)\.)*
- matches subdomains, also of higher levels, if anyexample\.com
- matches main domain/
- ensures start of path so domain name cannot continue
PHP: How to get referrer URL?
$_SERVER['HTTP_REFERER']
will give you the referrer page's URL if there exists any. If users use a bookmark or directly visit your site by manually typing in the URL, http_referer will be empty. Also if the users are posting to your page programatically (CURL) then they're not obliged to set the http_referer as well. You're missing all _
, is that a typo?
Inspect the referrer in PHP
Yes, but keep in mind some proxies and other things strip this information out, and it can be easily forged. So never rely on it. For example, don't think your web app is secure from CSRF because you check the referrer to match your own server.
$referringSite = $_SERVER['HTTP_REFERER']; // is that spelt wrong in PHP ?
If you want to only allow requests from a specific domain you'll need to parse some of the URL to get the top level domain. As I've learned more, this can be done with PHP's parse_url().
As andyk points out in the comments, you will also have to allow for www.example.com and example.com.
Determining Referer in PHP
The REFERER is sent by the client's browser as part of the HTTP protocol, and is therefore unreliable indeed. It might not be there, it might be forged, you just can't trust it if it's for security reasons.
If you want to verify if a request is coming from your site, well you can't, but you can verify the user has been to your site and/or is authenticated. Cookies are sent in AJAX requests so you can rely on that.
How to know which page sent the form action with PHP
$_SERVER['HTTP_REFERER']
will give you the referrer page's URL if there exists any. More information here: PHP: How to get referrer URL?
Please note that using HTTP_REFERER isn't reliable, it's value is dependent on the HTTP Referer header sent by the browser or client application to the server. More information here: How reliable is HTTP_REFERER? In other words it can't be trusted but it can help you :).
PHP: Checking domain referrer with an API
There is nothing built into HTTP that allows you to detect the "context" of a request, apart from voluntary (and therefore trivially spoofable) information from the client, such as the Referer
header.
If this is a server-to-server API (rather than something which will be requested directly by a user's browser), you could check the source IP address, using $_SERVER['REMOTE_ADDR']
. This is much trickier to fake, particularly if you're whitelisting rather than blacklisting IPs. (It's easy to find another IP, to avoid a blacklist, but near-impossible to choose your IP, to avoid a whitelist).
This is often used in e-commerce and e-payment APIs, where the owner of an account provides a list of IP addresses on setup, or in a customer control panel, to make it harder for third parties to use a stolen username and password.
PHP Form Security With Referer
Actually yes, according to the OWASP CSRF Prevention Cheat Sheet in most cases checking the referer is enough to patch a CSRF vulnerability. Although it is trivial to spoof the referer on your OWN BROWSER it is impossible to spoof it on another browser (via CSRF) because it breaks the rules.
In fact checking the referer is very common to see on embedded network hardware where Memory is scarce. Motorola does this for their Surfboard Cable Modems. I know this first hand, because I hacked them with csrf and then they patched it using a referer check. This vulnerability received a severity metric of 13.5 and according to the Department of Homeland Security this is the most dangerous CSRF vulnerability ever discovered and in the top 1,000 most dangerous software flaws of all time.
Related Topics
Codeigniter Activerecord: Join Backticking
Php: Re Order Associative Array
Set Multiple='False' in a Form in a Many to Many Relation Symfony2
Google Calendar API Batch Request PHP
Seems Like Post Values Are Lost When .Htaccess Rewriterule Used. Get Values Are Ok. How to Fix
Laravel Get Route Name from Given Url
Pass Base64 Jpeg Image to Og:Image
Session Share Across Multiple Domains on Same Server
Switch of PHP Versions Not Working on MAC
Need to Merge Multiple PDF's into a Single PDF with Table of Contents Sections
How to Run PHP Code from File_Get_Contents or File in a Function
Mysql: Get Total in Last Row of MySQL Result
Why Ob_Start() Must Come Ahead of Session_Start() to Work in PHP
How to Use Multiple PHP Header Content Types on the Same Page? Is This Possible