From which domain name the post request comes from? - php

I've built an API for providing some data a user needs to get. So every time a user hits the server with a curl post request and the server checks the header auth token and provides the data. Now I want to
check the domain from where the post request comes from
. How could I check this?

That isn't feasible as far as I can tell.
Browsers may send a Referer (sic) HTTP header, but Curl clients don't normally care. In any case the information is provided by the client so it isn't something you can trust.
The IP address of the incoming request may or may not be the actual client address. Even if it is, an IP address can resolve to zero, one or several domains.

Related

Restrict the requests coming to my webpage based on their url in PHP

I have to restrict the users accessing my webpage based on the url from where the request is coming to my webpage. I am able to get the url from where the request is coming using
$_SERVER['HTTP_REFERER']
As i know the HTTP_REFERER is a header which is sent by the client, most browsers default behavior is to send it, but users can disable it or even send a different referer header. So is there any way to do the proper validation of request based on their url.
Unfortunately, if the user has set the browser to modify the referrer header, there's no way for PHP to discern whether or not the request has come from a certain website.
Blocking traffic from a URL, although easy to do - cannot ever be 100% accurate.

How to secure Cross-Domain request; allowing third website to POST data

I have done some researches on how to prevent fake cross-origin requests and have found a lot of useful information. However, none of them seems to directly resolve my concerns, and because my application has to deal with this specific situation, I would like to understand it completely.
I have a simple php mailing website: mailsite.com
This site will allow other pre-defined addresses, for instance, user.com, to send POST data to it, and process the information that contains to and mesaage; then send them an E-mail from mailsite.com to to with the message message.
Currently, I am using $_SERVER[ "HTTP_ORIGIN" ] and $_SERVER[ "HTTP_REFERER" ] to check where the requests come from; and process them if it is from the pre-defined domains. However, I've read some articles that say:
HTTP_ORIGIN is not even indexed in PHP documentation, because it is pretty much per-browser sort of thing, so browsers that refuse to send those information will not work. HTTP_REFERER is easy to fake.
Tokens are good in preventing CSRF.
However, the request I allow is coming from a third pre-defined website, how does Tokens work in this situation?
My question is: If I allow specific domains to POST data to my site, how can I make sure (or the most secured way) that those requests are coming from the sites I expected? Is HTTP_ORIGIN not even safe enough to use? I dare to think about allowing third website to POST data to my site because I've seen Facebook allowing people to access their database. There must be some possible solutions for checking where the requests come from.
It sounds like you have multiple solutions possible:
Use a token permission system. Give user.com a private token to add as a hidden value to the input form. Upon submitting this form, the browser will give your server the token, and the user shouldn't have to know about the token. You check the token against your own database. If you find the token, allow the mail to be sent.
Use CORS (Cross-Origin Resource Sharing). When an Ajax request is sent to your server from user.com, there should be multiple Access-Control headers. You check if these exist and what their values are using $_SERVER['HTTP_ACCESS_CONTROL_header'] where header is one of the Access-Control header names. If these values match up to your expectations, respond with multiple header('Access-Control-header: value'); calls so that the browser knows you accepted the preflight request, otherwise don't add any extra headers. The browser will send another request after the preflight, and this is when you'll actually send the mail.
If this is being sent from user.com's server rather than a visitor of user.com, most likely the server's IP address won't change (though it may or may not use a defined range of IPs, so be mindful of that.), so you could verify that the $_SERVER['REMOTE_ADDR'] matches a value in your database. You can keep a table of approved IP addresses in your database for this purpose. If you find the IP address in your table, allow the mail to be sent.
Hope this helps.

how to find out which website is requesting my webpage?

i have a webpage ... sorto like an api ... basically it prints out some data in form of json .
other website can use this data via php by simply using file_get_contents
or
javascript/jquery ajax request (jsonp)
anyway i want to be able to black list some unwanted websites , so i have to know where this request are coming from
i've tried
$url = $_SERVER['HTTP_REFERER'];
$domain = parse_url($url, PHP_URL_HOST);
but i get
Undefined index: HTTP_REFERER
so unless i'm mistaken and this was an wierd exception , HTTP_REFERER doesn't work here .
so how can i get the referee in case of file_get_contents page request ?
Note that Ajax request are usually sent through the client's browser, while usually a server would call file_get_contents() or a similar tool, to fetch your page.
So in the case of a server, you can check the REMOTE_ADDR HTTP header (which contains the caller's IP) against a blacklist.
In the case of an Ajax request, probably from a user agent you can't really say from which website the originated from.
Though I am not sure, but the HTTP_REFERER header might contain exactly that, but again I have not checked it.
UPDATE (Ajax Requests):
After looking up a little bit, I turn out that browsers don't send referrer data with XHR requests, so you can only blacklist the IPs of the servers you don't want to be accessed from.
If the server request it directly then you can use $_SERVER 'REMOTE_ADDR' and 'REMOTE_HOST'.
If they use javascript then you will only get the clients ip. You can use strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') to disallow jquery requests.
Isn't what you're looking for a $_SERVER['REMOTE_ADDR']? AJAX calls probably won't have a Referer header and that's why you are getting that error.
The HTTP Referrer gets sent by a browser, probably not by file_get_contents()!
You can use $_SERVER['REMOTE_ADDR']. This will give you the raw IP address from the TCP stack.
In the case of a server-side API call, you get the server's IP (assuming the client does not use any proxies).
However if the client is an AJAX request, you'll get the IP address of the user viewing that page.
HTTP_REFERER is not going to be reliable. You might try $_SERVER['REMOTE_ADDR'] to inspect IP address of remote client.
I would however think that you would have a better time whitelisting approved clients rather then blacklisting, as an attacker could easily proxy a request to get around an IP/host-based blacklist.
There are a number of approaches for whiltelisting:
whitelist known IP's
HTTP Authentication
Your own custom API keys
Third party authentication (i.e. OAuth)
and so forth.

How to controll access for a response to a http request ? (server side & client side)

Excluding the same origin policy that all major browsers have and the syncrhronised token pattern (would be a pain in the ass to tokenise all requests), how would you check if the request is sent directly from my user interface and not through a third party.
For example , sending a request from an iframe to youtube (by that i mean the src=... not xmlhttprequest object), the response would be a blank page (how do they do it?) , send a request to facebook ajax.hovercard (its a simple get content request) from an iframe , adress bar will also give you a blank page (no content). SO response is normal content from an iframe request .
Like i said before how would you check (preferably some server side code) if the request is coming from a trusted source?
P.S. : Don't rely on headers , idk why origin im not receiving from requests , altho i see they all implemented the origin header in all major browsers . Refereer can be modified by some ati spyware programs . And anyway the headers can't really be trusted. But yes that showld be a layer for checking.
Check $_SERVER['HTTP_REFERER'] and see if it's coming from your own site.
You can't really be sure of the origin of the user. The user agent can be spoofed easily.
I think you can create some csrf tokens in your user interface and allow only clients that have those tokens

Can we ever determine if the request was sent from another domain?

I've read these webpages:
PHP Form Security With Referer and http://www.mustap.com/phpzone_post_62_how-to-bypass-the-referer-se
So basically my question is how do we determine for certain that the request was sent from our own domain? Or is there no way at all?
(Question targeted at any server side language including but not limited to PHP/JSP/ASP.Net etc)
My Problem: I have a page at http://me.com/login and on form submit, it will post to itself the login particulars. So far so good. until someone else can simply do this
<form action="http://me.com/login">
<input name="password" value="p">
<input name="username" value="u">
</form>
and they can send a request to login to my application through their domain. I do not want this. I need a way to make sure that if my page receives a post, its from my domain. Else i will reject it.
Besides, I'm abit shock when i read this: There are plugins for Firefox that allow the user to specify whatever value they want to be supplied as the REFERER. source: http://www.phpbuilder.com/board/showthread.php?t=10324100
So we don't even need a hacker to break it now. Just about anyone could do it.
I need a solution to make sure that i reject ALL requests not from my domain.
So basically my question is how do we determine for certain that the request was sent from our own domain? Or is there no way at all?
You are asking the impossible. There is no way to know for certain that a submit button on a page on your domain generated the request.
You say it's not about CSRF, so I don't know why you are concerned. But the solutions are the same.
Check the HTTP_REFERER header anyway. If it isn't your domain, then reject the request. You'll probably need to accept missing headers though since some people disable it. This doesn't prevent people who mess with their browser settings from spoofing the value though. But it does prevent people who are tricked into submitting the form from another site (assuming they haven't disabled HTTP_REFERER).
Use a "nonce" or temporary token that is only valid for one request. Hence, the person who submits the request must visit your website at least once per request. This is basically the same thing as ensuring that the request originated from your website. You can also tie a nonce to an IP address or session to prevent people from querying your site and relying the token along to another computer.
There's no way to make sure where's the origin of the request. This is the nature of HTTP state-less protocol.
In common Referrer HTTP header is used as the source of request, but it can be manipulated easily.
Use a hidden input with an encrypted key that is held on your server, and make it change frequently (I give 30 seconds before it changes!). This wont stop it but will minimise the risk, also, log the failed attempts per IP and block that IP/user after the 4th failed attempt until re-verified via email.
If the username that had the failed attempts doesn't match the DB after the 4th time, block the IP and give an email to contact.

Categories