How to set a cookie for another domain - javascript

Say I have a website called a.com, and when a specific page of this site is loaded, say page link, I like to set a cookie for another site called b.com, then redirect the user to b.com.
I mean, on load of a.com/link I want to set a cookie for b.com and redirect user to b.com.
I tested it, and browser actually received the cookie from a.com/link, but it didn't send that cookie on the redirection request to b.com. Is it normal?
Can we set cookies for other domains?

You cannot set cookies for another domain. Allowing this would present an enormous security flaw.
You need to get b.com to set the cookie. If a.com redirect the user to b.com/setcookie.php?c=value
The setcookie script could contain the following to set the cookie and redirect to the correct page on b.com
<?php
setcookie('a', $_GET['c']);
header("Location: b.com/landingpage.php");
?>

Similar to the top answer, but instead of redirecting to the page and back again which will cause a bad user experience you can set an image on domain A.
<img src="http://www.example.com/cookie.php?val=123" style="display:none;">
And then on domain B that is example.com in cookie.php you'll have the following code:
<?php
setcookie('a', $_GET['val']);
?>
Hattip to Subin

Probaly you can use Iframe for this. Facebook probably uses this technique. You can read more on this here. Stackoverflow uses similar technique, but with HTML5 local storage, more on this on their blog

In case you have a.my-company.com and b.my-company.com instead of just a.com and b.com you can issue a cookie for .my-company.com domain - it will be accepted and sent to both of the domains.

You can't, at least not directly. That would be a nasty security risk.
While you can specify a Domain attribute, the specification says "The user agent will reject cookies unless the Domain attribute specifies a scope for the cookie that would include the origin server."
Since the origin server is a.com and that does not include b.com, it can't be set.
You would need to get b.com to set the cookie instead. You could do this via (for example) HTTP redirects to b.com and back.

Setting cookies for another domain is not possible.
If you want to pass data to another domain, you can encode this into the url.
a.com -> b.com/redirect?info=some+info (and set cookie) -> b.com/other+page

see RFC6265:
The user agent will reject cookies unless the Domain attribute
specifies a scope for the cookie that would include the origin
server. For example, the user agent will accept a cookie with a
Domain attribute of "example.com" or of "foo.example.com" from
foo.example.com, but the user agent will not accept a cookie with a
Domain attribute of "bar.example.com" or of "baz.foo.example.com".
NOTE: For security reasons, many user agents are configured to reject
Domain attributes that correspond to "public suffixes". For example,
some user agents will reject Domain attributes of "com" or "co.uk".
(See Section 5.3 for more information.)
But the above mentioned workaround with image/iframe works, though it's not recommended due to its insecurity.

You can't, but... If you own both pages then...
1) You can send the data via query params (http://siteB.com/?key=value)
2) You can create an iframe of Site B inside site A and you can send post messages from one place to the other. As Site B is the owner of site B cookies it will be able to set whatever value you need by processing the correct post message. (You should prevent other unwanted senders to send messages to you! that is up to you and the mechanism you decide to use to prevent that from happening)

Send a POST request from A. Post requests are on the serverside only and can't be accessed by the client.
You can send a POST request from a.com to b.com using CURL (recommended, serverside) or a hidden method="POST" form (clientside). If you go for the latter, you might want to obfuscate your JavaScript so that the user won't be able to understand the algorithm and interfere with it.
Make a gateway on b.com to set cookies:
<?php
if (isset($_POST['data']) {
setcookie('a', $_POST['data']);
header("Location: b.com/landingpage");
}
?>
If you want to bring security a step further, implement a function on both sides (a.com and b.com) to encrypt (on a.com) and decrypt (on b.com) data using a cryptographic cypher.
If you're trying to do something that must be absolutely secure (e.g. transfer a login session) try oAuth or take some inspiration from https://api.cloudianos.com/docs#v2/auth

Here is what I've used. Note, this cookie is passed in the open (http) and is therefore insecure. I don't use it for anything which requires security.
Site A generates a token and passes as a URL parameter to site B.
Site B takes the token and sets it as a session cookie.
You could probably add encryption/signatures to make this secure. Do your research on how to do that correctly.

In this link, we will find the solution Link.
setcookie("TestCookie", "", time() - 3600, "/~rasmus/", "b.com", 1);

Related

Setting document.cookie for another site then redirecting [duplicate]

Say I have a website called a.com, and when a specific page of this site is loaded, say page link, I like to set a cookie for another site called b.com, then redirect the user to b.com.
I mean, on load of a.com/link I want to set a cookie for b.com and redirect user to b.com.
I tested it, and browser actually received the cookie from a.com/link, but it didn't send that cookie on the redirection request to b.com. Is it normal?
Can we set cookies for other domains?
You cannot set cookies for another domain. Allowing this would present an enormous security flaw.
You need to get b.com to set the cookie. If a.com redirect the user to b.com/setcookie.php?c=value
The setcookie script could contain the following to set the cookie and redirect to the correct page on b.com
<?php
setcookie('a', $_GET['c']);
header("Location: b.com/landingpage.php");
?>
Similar to the top answer, but instead of redirecting to the page and back again which will cause a bad user experience you can set an image on domain A.
<img src="http://www.example.com/cookie.php?val=123" style="display:none;">
And then on domain B that is example.com in cookie.php you'll have the following code:
<?php
setcookie('a', $_GET['val']);
?>
Hattip to Subin
Probaly you can use Iframe for this. Facebook probably uses this technique. You can read more on this here. Stackoverflow uses similar technique, but with HTML5 local storage, more on this on their blog
In case you have a.my-company.com and b.my-company.com instead of just a.com and b.com you can issue a cookie for .my-company.com domain - it will be accepted and sent to both of the domains.
You can't, at least not directly. That would be a nasty security risk.
While you can specify a Domain attribute, the specification says "The user agent will reject cookies unless the Domain attribute specifies a scope for the cookie that would include the origin server."
Since the origin server is a.com and that does not include b.com, it can't be set.
You would need to get b.com to set the cookie instead. You could do this via (for example) HTTP redirects to b.com and back.
Setting cookies for another domain is not possible.
If you want to pass data to another domain, you can encode this into the url.
a.com -> b.com/redirect?info=some+info (and set cookie) -> b.com/other+page
see RFC6265:
The user agent will reject cookies unless the Domain attribute
specifies a scope for the cookie that would include the origin
server. For example, the user agent will accept a cookie with a
Domain attribute of "example.com" or of "foo.example.com" from
foo.example.com, but the user agent will not accept a cookie with a
Domain attribute of "bar.example.com" or of "baz.foo.example.com".
NOTE: For security reasons, many user agents are configured to reject
Domain attributes that correspond to "public suffixes". For example,
some user agents will reject Domain attributes of "com" or "co.uk".
(See Section 5.3 for more information.)
But the above mentioned workaround with image/iframe works, though it's not recommended due to its insecurity.
You can't, but... If you own both pages then...
1) You can send the data via query params (http://siteB.com/?key=value)
2) You can create an iframe of Site B inside site A and you can send post messages from one place to the other. As Site B is the owner of site B cookies it will be able to set whatever value you need by processing the correct post message. (You should prevent other unwanted senders to send messages to you! that is up to you and the mechanism you decide to use to prevent that from happening)
Send a POST request from A. Post requests are on the serverside only and can't be accessed by the client.
You can send a POST request from a.com to b.com using CURL (recommended, serverside) or a hidden method="POST" form (clientside). If you go for the latter, you might want to obfuscate your JavaScript so that the user won't be able to understand the algorithm and interfere with it.
Make a gateway on b.com to set cookies:
<?php
if (isset($_POST['data']) {
setcookie('a', $_POST['data']);
header("Location: b.com/landingpage");
}
?>
If you want to bring security a step further, implement a function on both sides (a.com and b.com) to encrypt (on a.com) and decrypt (on b.com) data using a cryptographic cypher.
If you're trying to do something that must be absolutely secure (e.g. transfer a login session) try oAuth or take some inspiration from https://api.cloudianos.com/docs#v2/auth
Here is what I've used. Note, this cookie is passed in the open (http) and is therefore insecure. I don't use it for anything which requires security.
Site A generates a token and passes as a URL parameter to site B.
Site B takes the token and sets it as a session cookie.
You could probably add encryption/signatures to make this secure. Do your research on how to do that correctly.
In this link, we will find the solution Link.
setcookie("TestCookie", "", time() - 3600, "/~rasmus/", "b.com", 1);

Access other site cookies using CORS

I have two servers with separate domains let say first websiteA.com and second one websiteB.com.
Now user comes to websiteA.com and some cookies from this website are set on the user machine.
websiteA loads some javascript resources from websiteB and the user have some cookies from websiteB.
websiteB webserver has some headers like this.
Access-Control-Allow-Origin: "websiteA.com"
access-control-allow-credentials: True
At this moment URL page is from websiteA and websiteA client wants to send all cookies to websiteA server (include websiteB cookies), Is that possible?
Before asking this question I search to find a solution and I find this link, so I'm runing some script like this on browser that this page is from webisteA that previously includes websiteB scripts:
fetch('websiteB.com', {mode:'cors'})
fetch('websiteA.com', {
mode: 'cors',
credentials: 'include'
})
But cookies of websiteB not sent to websiteA, It seems If websiteB allows websiteA to access cookies, It might be a way to access them. Is there any way to do this?
you only can read cross-cookie from same domain.
it's mean you can only read cookie sub1.sample.com from sub2.sample.com if allow from sub2.
but you can send some request contain cookies from A to B.
https://dev.to/zubairmohsin33/sending-cookies-with-cross-origin-cors-request-44m

How to use CloudFront signed cookies in the browser?

So I have a private CDN (can't access data through S3, only by signed URL & cookies) using CloudFront that holds some files for a web application.
One of the pages on my site displays an image whose source lives on the cdn.
<img src="cdn.example.com/images/file.jpg">
Now when I generate a signed URL on the server I can just pass it to the client and set it as source...Easy
But when I try to do the same thing using signed cookies I run into 2 problems:
After generating the signed cookies server-side, I set them using res.cookie but I'm not sure how to find them in response on the client side.
In the event of actually getting the cookie on the client side (in angular/javascript), how to I "set" it so that when the browser tries to grab the image in the above mentioned html it allows access?
I'm using node, express, and cookie-parser.
I'm fairly new to this stuff so any help is appreciated
Have you checked that the domain for the cookie is the same or a subdomain of the CloudFront CDN?
The cookie will be included in the request to the CloudFront distribution only if it is coming from a related domain. For example, if you are testing locally using "localhost" that won't work as the cookie domain is "localhost" but the signed cookie domain is "cdn.example.com".
To ensure that the domain is correct:
Set up a CNAME for the CloudFront Distribution e.g.
http://cdn.example.com
Make sure the signed cookie has the correct
domain e.g. domain:'*.example.com' will match against the domain.
There's a good article here:
https://www.spacevatican.org/2015/5/1/using-cloudfront-signed-cookies/
There's also a good node module for creating signed cookies:
https://github.com/jasonsims/aws-cloudfront-sign
Using this module you would do something like:
const options = {
keypairId: YOUR_ACCESS_ID,
privateKeyPath: PATH_TO_PEM_FILE
};
const signedCookies = cf.getSignedCookies("http://cdn.example.com/*", options);
for (const cookieId in signedCookies) {
res.cookie(cookieId, signedCookies[cookieId], {domain: ".example.com"});
}
Note the way I set the domain. If not explicitly set it will default to the one that made the request, which is probably not what you want.
Last thing, to test this locally, I set up port-forwarding on my home network and created a CNAME in GoDaddy to point to my home IP e.g. "test.example.com". I then used "http://test.example.com" instead of "http://localhost". This created a cookie with the subdomain "test.example.com". Finally, I created another CNAME in GoDaddy called "cdn.example.com", pointing it to the CloudFront URL. I used the wildcard domain in my signed cookie, ".example.com" and because I now have the signed cookie on the same domain "example.com" it's passed to CloudFront and boom we have liftoff!
For those trying to access a protected resource in CloudFront from a different domain you can not set the cookies cross domain so you're limited to using Signed URLs instead. However you can use javascript on the CloudFront site to use the parameters in the Signed URL to create a Signed Cookie directly in CloudFront. I put together a simple JS script that does just that.
aws-signed-cookie-from-signed-url.js
build signed url in www.mysite.com that points to CloudFront url www.cloudfronturl.com/sample/index.html
included the JS in the CloudFront resource "sample/index.html"
upon the user using the signed URL, index.html will create the SignedCookie which will allow all additional navigation within www.cloudfronturl.com/sample to work based on the cookie

Verifying iframe post request from other domain

I need to create a click to call widget(using iframe). clients will add the widget on their websites. iframe will have an input box where some customer of the client will enter their mobile number and when customer clicks on submit button a request will be made to our server directly from the customer's browser.
How we can identify that a request was made from a valid website? Is there any way to hack this post request?
Also is there any better way?
Screenshot of widget:
To clarify, the widget will be on other domain and post request will be sent directly to our server.
you can set the Access-Control-Allow-Origin header on your server headers and specify the exact domains, to allow them to send requests from their browsers like this:
Access-Control-Allow-Origin: http://domain1.com http://domain2.com
check this link for more info.
the other way is to read the Origin header from the client then check it if it is one of the list of allowed domains, and if it is, write the response and set the Access-Control-Allow-Origin header.
The detection could be done server side. For example, with php
$origin = $_SERVER['HTTP_REFERER'];
in your destination script, gives you the originating domain. You can validate with that.
Hope this helps. Cheers

Can jQuery.getJSON put a domain's cookies in the header of the request it makes?

(Note: See also the related question Can browsers react to Set-Cookie specified in headers in an XSS jquery.getJSON() request?)
I can't seem to set a cookie (whose name is mwLastWriteTime) in the request header of a JSON operation. The request itself is a simple one from the Freebase MQL tutorials, and it is working fine otherwise:
// Invoke mqlread and call the function below when it is done.
// Adding callback=? to the URL makes jQuery do JSONP instead of XHR.
jQuery.getJSON("http://api.sandbox-freebase.com/api/service/mqlread?callback=?",
{query: JSON.stringify(envelope)}, // URL parameters
displayResults); // Callback function
I'd hoped that I could set this cookie with something along the lines of:
$.cookie('mwLastWriteTime', value, {domain: ".sandbox-freebase.com"});
Unfortunately, looking in FireBug at the outgoing request header I see only:
Host api.sandbox-freebase.com
User-Agent [...]
Accept */*
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive 115
Connection keep-alive
Referer [...]
But if I don't specify the domain (or if I explicitly specify the domain of the requesting site) I can get mwLastWriteTime to show up in the headers for local requests. Since the .sandbox-freebase.com domain owns these cookies, shouldn't they be traveling along with the GET? Or does one need a workaround of some sort?
My code is all JavaScript, and I would like to set this cookie and then call the getJSON immediately afterward.
You cannot set a cross-domain cookie, because that would open the browser (and therefore the user) to XSS attacks.
To quote from the QuirksMode.org article that I reference above:
Please note that the purpose of the
domain is to allow cookies to cross
sub-domains. My cookie will not be
read by search.quirksmode.org because
its domain is www.quirksmode.org .
When I set the domain to
quirksmode.org, the search sub-domain
may also read the cookie. I cannot set
the cookie domain to a domain I'm not
in, I cannot make the domain
www.microsoft.com . Only
quirksmode.org is allowed, in this
case.
If you want to make cross-site request with cookie values you will need to set up a special proxy on a server you control that will let you pass in values to be sent as cookie values (probably via POST parameters). You'll also want to make sure that you properly secure it, lest your proxy become the means by which someone else's private information is "liberated".
Are you running all of your tests through localhost? Are you using IE? If so it will be enforcing its own special brand of security requirements and likely dumping your cookies. Open fiddler and use http://ipv4.fiddler to bypass that.
If that type of trickery is not going on (as it appears you are using FireFox) , it may also be the case that you do need to explicitely set the cookie's domain to be the same as the domain of your JSON request. A browser won't send cookies set for domain A to a request to domain B. I am not 100% sure this is the case though.

Categories

Resources