For my example , i'll use this variables :
first_site.com = my website where i will execute the cookie get commands
specified_site.com = my second website that the client is already logged in
my_server.com = my server adress where i have a php script to handle the received data
the user is already connected to first_site.com and specified_site.com
and i want to get cookies from "first_site.com" and save them to "my_server.com"
Any way to do that , with php or javascript ?!
Regards
If both sites are yours and you have access to the server-side code on both sites, then you can have the first server forward the cookies to the second server using server-to-server communication.
The "same origin" protections built into a browser try to prevent you from doing what you want to do from purely client code (without involving both servers).
This is because you can only retrieve cookies when your page is on the domain that the cookie belongs to. And, you can only send the cookie (using ajax) to a server on the same domain as the page. So, you can't send one domain's cookie to another server. This is an obvious security violation which the browser intends to block with its "same origin" protections. You can read about those protections here.
If, you have a cooperating server from the first site, you can have that server retrieve the cookie when it is sent along with the original page request and then that server could send the cookie along to your second site using server-to-server communications. If the first domain is not yours where you can modify the server-side code, then obviously you can't run code on that server to do this.
There is no way to do that, as it would be a hudge security flaw.
Imagine if I made a website saving all your PHPSESSIDs, I could access your profile on many websites...
These are few of the options. Not the best ones though. Some general pointers to get you started:
a. You can also consider setting up VPN. This whitelist the IPS from both the servers.
You can create a REST API containing your cookie info(not public though)!!
Make your cookie data available on App1;
Make your cookie available as a Cookie object that can be served through a Request/Response Object
using "same origin" policy; you can have app2 talk to app1
Related
I want to use post to update a database and don't want people doing it manually, i.e., it should only be possible through AJAX in a client. Is there some well known cryptographic trick to use in this scenario?
Say I'm issuing a GET request to insert a new user into my database at site.com/adduser/<userid>. Someone could overpopulate my database by issuing fake requests.
There is no way to avoid forged requests in this case, as the client browser already has everything necessary to make the request; it is only a matter of some debugging for a malicious user to figure out how to make arbitrary requests to your backend, and probably even using your own code to make it easier. You don't need "cryptographic tricks", you need only obfuscation, and that will only make forging a bit inconvenient, but still not impossible.
It can be achieved.
Whenever you render a page which is supposed to make such request. Generate a random token and store it in session (for authenticated user) or database (in case this request is publicly allowed).
and instead of calling site.com/adduser/<userid> call site.com/adduser/<userid>/<token>
whenever you receive such request if the token is valid or not (from session or database)
In case token is correct, process the request and remove used token from session / db
In case token is incorrect, reject the request.
I don't really need to restrict access to the server (although that would be great), I'm looking for a cryptographic trick that would allow the server to know when things are coming from the app and not forged by the user using a sniffed token.
You cannot do this. It's almost one of the fundamental problems with client/server applications. Here's why it doesn't work: Say you had a way for your client app to authenticate itself to the server - whether it's a secret password or some other method. The information that the app needs is necessarily accessible to the app (the password is hidden in there somewhere, or whatever). But because it runs on the user's computer, that means they also have access to this information: All they need is to look at the source, or the binary, or the network traffic between your app and the server, and eventually they will figure out the mechanism by which your app authenticates, and replicate it. Maybe they'll even copy it. Maybe they'll write a clever hack to make your app do the heavy lifting (You can always just send fake user input to the app). But no matter how, they've got all the information required, and there is no way to stop them from having it that wouldn't also stop your app from having it.
Prevent Direct Access To File Called By ajax Function seems to address the question.
You can (among other solutions, I'm sure)...
use session management (log in to create a session);
send a unique key to the client which needs to be returned before it expires (can't
be re-used, and can't be stored for use later on);
and/or set headers as in the linked answer.
But anything can be spoofed if people try hard enough. The only completely secure system is one which no-one can access at all.
This is the same problem as CSRF - and the solution is the same: use a token in the AJAX request which you've perviously stored eslewhere (or can regenerate, e.g. by encrypting the parameters using the sessin id as a key). Chriss Shiflett has some sensible notes on this, and there's an OWASP project for detecting CSRF with PHP
This is some authorization issue: only authorized requests should result in the creation of a new user. So when receiving such a request, your sever needs to check whether it’s from a client that is authorized to create new users.
Now the main issue is how to decide what request is authorized. In most cases, this is done via user roles and/or some ticketing system. With user roles, you’ll have additional problems to solve like user identification and user authentication. But if that is already solved, you can easily map the users onto roles like Alice is an admin and Bob is a regular user and only admins are authorized to create new users.
It works like any other web page: login authentication, check the referrer.
The solution is adding the bold line to ajax requests. Also you should look to basic authentication, this will not be the only protector. You can catch the incomes with these code from your ajax page
Ajax Call
function callit()
{
if(window.XMLHttpRequest){xmlhttp=new XMLHttpRequest();}else{xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
xmlhttp.onreadystatechange=function(){if(xmlhttp.readyState==4&&xmlhttp.status==200){document.getElementById('alp').innerHTML=xmlhttp.responseText;}}
xmlhttp.open("get", "call.asp", true);
**xmlhttp.setRequestHeader("X-Requested-With","XMLHttpRequest");**
xmlhttp.send();
}
PHP/ASP Requested Page Answer
ASP
If Request.ServerVariables("HTTP_X-Requested-With") = "XMLHttpRequest" Then
'Do stuff
Else
'Kill it
End If
PHP
if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && ( $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) )
{
//Do stuff
} else {
//Kill it
}
I have a slightly strange scenario, but a problem that needs solving all the same!
Please note, the websites described below are on different top level domains
I have two web applications, 1 ASP.NET MVC, and another in PHP, both on separate domains. Lets call them asp.com and php.com. Users authenticate on asp.com, and therefore have an authcookie set by ASP.NET.
Now the php.com website fetches data via a rest service from asp.com. This rest service authenticates via the same mechanism, so when I call this rest service via javascript JSONP from php.com it works fine. However I wish to call the same REST service from the server in PHP.
Is it possible to somehow get the asp.com website to copy and set an authcookie for php.com (the domain is known and trusted), and then in the PHP code pass this cookie on to athenticate against the REST service on asp.com?
It doesn't need to be the exact AUTH cookie, I could create a new cookie with the relevant session key, an long as a valid authcookie could be created and submitted to the REST service.
Questions
Is this possible?
How do I set the cookie for php.com in asp.com?
Short of one of the domains becoming compromised, are there any
security concerns?
No
The first site, asp.com, will have to redirect to a page in php.com. Then php.com can set the cookie itself, and redirect back to asp.com.
Yes, which is why you can't do it.
Also, see this answer.
Lets imagine that site A embeds a javascript file using a standard script tag pointing to server B. Next Site A makes a JSONP or AJAX request to a resource on server B. Is there anyway for Server B to definitively know that specific JSONP request originated from a user on Site A, and not a user on another site spoofing their HTTP REFERRER.
The only reason I think there is any realm of possibility is because site A started the communication with it's embedding of server B's javascript. In a way, couldn't this original communication act as a security handshake, allowing subsequent calls to pass through securely. But because the handshake was made through insecure means doesn't that prevent it from acting as a security handshake.
Any ideas of how this task can be accomplished? Every solution I can think up is broken by the notion that every element of an AJAX call can be faked.
I read http://www.codinghorror.com/blog/2008/10/preventing-csrf-and-xsrf-attacks.html and Detecting Ajax in PHP and making sure request was from my own website but as far as I could tell they focused on ensuring the veracity of the user and not the veracity of the referrer.
Ajax over https you could if you wanted configure your server to require mutual authentication.
You could use Hash_chain to verify origin.
On page load generate X times hash from random and send last hash with initial request (script tag) e.g. Hash[100]. every next request send with Hash[Last-1].
On server B check whether hash(resieved_hash) is same as last one.
two years ago I had to design a system to share authentication data across multiple domains, all of them shared the same server/db. I was able to pull this off with a complex system of cookie sharing which, to date still works.
I'm now in the process of redesigning the system and I was wondering if there are better ways to achieve this without having to write cross domain cookies.
Basically the system MUST do this.
Once logged in one site the user must be logged in all of the other site seamlessly, not only following a link, but even by directly writing the domain name on the address bar.
To my knowledge the only way to achieve this are cross-domain cookies, if there are alternatives please tell me.
Thank you very much
My Idea would be to include a login-Javascript from a third domain which gets includet in all sites. This javascript sets and reads the session-cookie and calls the current domains server via ajax with the result. (No validation should be done in the JS - this simply sets and reads the cookie)
If cross domain AJAX does not work, you can still call the thirds domain server which acts like a proxy and calls the current domains server.
The StackOverflow sites have implemented something similar to this. Check out the details at the following links.
Here is a post giving an outline of how they did it.
And here is even more detail.
For this you do have to use cookies, but you can vary what you store in the cookie. The cookie doesn't have to contain user credentials but can instead contain something more like a token that you use to "centralize" your sessions.
Easies way would be to let all hosts share a single memcached server and use the content of the users cookie as your key.
I have a Javascript widget that people can embed on their site.
I want to use a simple cross domain get request to pull in a hash.
However I need my PHP script to only allow this cross domain request from a series of domains I have stored in an array.
What can I do in my PHP script (not in .htaccessor iptables) to find out the source (hostname) of the get request?
Considering the client (user's browser) can send you whatever it wants, I would say there is no way to be sure which website your script is called from :
As you want to know the URL of the website embedding your widget, and not the address of the user, $_SERVER['REMOTE_HOST'] will not help
$_SERVER['HTTP_REFERER'] could seem OK, but actually is not :
The client doesn't have to send it (and it doesn't always do)
As it is sent by the client, it can be forged / faked Quite easily
So, I'd say there is no real solution to this problem, at least on your server's side (If I'm wrong, I'm interested to know !)
But maybe you can do something on the client's side : when writing all this, I thought about google maps, and it's system of API Key :
you have an (unique) API key four your domain
When you load the JS scripts from google, your send this key
if the key is not registered for the domain on which you are trying to display the map, there is an alert message, saying "The Google Maps API server rejected your request. This could be because the API key used on this site was registered for a different web site."
but the map seems to be displayed anyway -- at least on my test server
this alert is really anoying for the end-user, and I don't think anyone would want an alert displayed on their site because they are using your service withot authorisation...
Maybe you can have a look at how this is done for google maps :-)
You could use the $_SERVER variable. In particular the $_SERVER['REMOTE_HOST'] but see below for caveat:
However, your web server must be
configured to create this variable.
For example in Apache you'll need
HostnameLookups On inside httpd.conf
for it to exist. See also
gethostbyaddr().
If the requests are coming from JavaScript, you could check the HTTP referrer header ($_SERVER['HTTP_REFERER']). However, it's optional - some proxies or security programs strip the referrer header out of HTTP requests.