Access other site cookies using CORS - javascript

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

Related

Setting and getting a cookie back from a javascript tag request

I have the following situation:
Javascript tag with src=domain1.com in another_domain.com page
Javascript tag returns a cookie header and script content from domain1.com server
Script content collects data and send it via request to domain1.com
I want to be able to set a cookie in the point 2 and recover it in the point 3. I've been able to set the cookie by returning a Set-Cookie header like this:
set-cookie: cookieName="cookieValue";Version=1;Domain=domain1.com;Path=/;SameSite=None;Max-Age=600;Secure
But I am not able to recover it in the request in the point 3, as the cookie is not sent with the request.
So, two questions at this point:
Do I need to manually send the cookie in the second request? When tested doing redirects, the cookie header is "autoattached" to the second request and I'm able to recover it, but this is not happening with the requests from the javascript tag.
I am only able to set a cookie in https (Secure cookie) and with SameSite=None from the script? When tried without Secure and SameSite=None or in an http environment, the cookie was not set and a cross-site error was thrown by the developer console.
Thanks for reading.
There are several things to consider here. First of all we have to note that we are facing a case of cross domain communications.
If you need to send in the step 3 the Cookie set by the server in the step 2, you have to explicitly configure it when making the request. In case you are using XMLHTTPRequest you have to set up withCredentials to true, here is the docs.
If you are using fetch take a look at Request credentials.
As it's a cross domain communication, make sure your CORS headers are properly configured. When the request credentials mode is "include" you will need to set the Access-Control-Allow-Origin header to something valid and not a wildcard "*". You will also need Access-Control-Allow-Credentials to true, check it here.
With this configuration, the cookie will be "autoattached" (as per your words) in the third step. You can't set a cookie via JS on a cross-domain setting for security reasons, see this response.

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);

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

uploading images - do they have domain name in them - chrome not sending session id

For testing I downloaded images from the net and uploaded using valum file upload in chrome...chrome is not sending session cookie along with these request header( I dont see that in the server side/though I see it on developer tool)...does chrome know that these images are from different domain . what is happening...Is there work around for this to pass the session id (as cookie). It is also happening in IE10 which makes me belive it is some standard. and not just a chrome issue. This problem is not there with firefox/safari/opera
It is fine when uploading to localhost. only when uploading to different server with domain name there is this problem leading to creating a new session for this.
Update:
I have added xhr.withCredentials = true still no use.
Also added on the server side to the upload url...
res.setHeader 'Access-Control-Allow-Origin', '*'
res.setHeader 'Access-Control-Allow-Credentials', true
I dont know how helpful this would be, because I would have already sent the upload file and response header will not of much help.
basically the problem is I don't have access to the session variable at the server side, since the session id/sid cookie is not coming back /I am not able to save some of this upload details into the current session(because this is a new session) .
Update:
I tried creating an image in teh desktop using paint..even then chrome would not sent the cookies. Really drives me crazy...
First of all, to get the basics out of the way, this is unrelated to the origin of the image. Chrome or other browsers don't care where you get your images.
It's rather difficult to guess exactly what's going on, would have helped to see a jsfiddle or some more setup explanation, but based on what I'm guessing, you might be using different domains for the page where the upload button is hosted and the target url where you're sending your files (even using ssl for one and http for the other makes it different). Even different subdomains will not allow cookies to be passed if the cookies were not set with a base domain (yourdomain.com)
So, if sub-domains are the problem, you know what to do - set a base domain so you get your cookies to go on any sub domain.
If it's http vs. https you need to always use https (or http) because you can't switch cookies between those two.
If that's not it, or if you're using completely different domains, you can access your cookies locally via script (if they're not marked as http only) and add them to the upload request. Valum 2.0 (don't know about v1.0) lets you add parameters to the request like so:
var uploader = new qq.FileUploader({
element: document.getElementById('file-uploader'),
action: '/server-side.upload',
// additional data to send, name-value pairs
params: {
param1: 'value1',
param2: 'value2'
}
});
You can't set cookies on a domain which is not the page's domain via script so for using completely different domains your only choice is using request params.
It is possible that the uploader is using Flash under some circumstances to do the upload. There is a bug in Flash which prevents cookies being sent for these types of requests. This would explain the behaviour you are seeing. The workaround is to pass in the sessionId and transmit it in a different way eg. querystring.

How to set a cookie for another domain

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);

Categories

Resources