I can't access any cookie from JavaScript. I need to read some value and send them via JSON for my custom checks.
I've tried to access cookies from JS, like it was described at:
http://www.w3schools.com/js/js_cookies.asp
Get cookie by name
As you can see at the code, it's seen as clear as a crystal the next:
var c_value = document.cookie;
When I'm trying to access the document.cookie value from the Chrome's web-debugger, I see only the empty string at the Watch expressions:
So I can't read cookies value, which I need.
I've checked the cookie name, which I'm sending to get an associated value IS correct.
Also, I'm using the W3Schools source code for getting cookies, if you're interested (but from the 2nd link, the technique is similar).
How can I fix my issue?
You are most likely dealing with httponly cookies. httponly is a flag you can set on cookies meaning they can not be accessed by JavaScript. This is to prevent malicious scripts stealing cookies with sensitive data or even entire sessions.
So you either have to disable the httponly flag or you need to find another way to get the data to your javascript.
By looking at your code it should be easy to disable the http only flag:
Response.AddHeader("Set-Cookie", "CookieName=CookieValue; path=/;");
Response.SetCookie(new HttpCookie("session-id") { Value = Guid.NewGuid().ToString(), HttpOnly = false });
Response.SetCookie(new HttpCookie("user-name") { Value = data.Login, HttpOnly = false });
Now you should be able to access the cookie information from JavaScript. However I don't know exactly what kind of data you are trying to get so maybe you can go for another approach instead and for example render some data attribute on the page with the information you need instead of trying to read the cookie:
<div id="example" data-info="whatever data you are trying to retrieve"></div>
console.log(document.getElementById('example').getAttribute('data-info'));
keep an eye also to the cookie's Path attribute, as the cookie is only visible to subdirectories under Path. I had your issue and I solved setting Path "/"
I would say http only is your first culprit but this can also occur by not setting the scope of your cookie.
If the site has been redirected from another domain, you will need to look into setting the scope of the cookie. Domain and Path defines the scope of the cookie, which URLs the cookie should be sent to. Depending on this, you might not see the cookie in your response.
I ran across this issue when setting a cookie on a successful SAML SSO login and couldn't retrieve the cookie from the Document because it was never send as part of the request.
I had the same problem several times. And every time, it was for a different reason.
Different reasons:
problem of httpOnly field. It was set to false and I was trying to access it from the console. Setting it to true or accessing it from the source code did the trick.
problem of secure field. It was true and I was using only http.
problem of Expires / Max-Age. The cookie was outdated and it was not visible in document.cookie.
If your cookie is set as Set-Cookie or Set-Cookie2 it's not part of the response headers collection: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders%28%29-method
Returns all headers from the response, with the exception of those whose field name is Set-Cookie or Set-Cookie2.
If you are using some secure authentication then that case you could not access cookies directly because of secure. you have to change some response attribute in server side using below code .
Response.AddHeader("Set-Cookie", "CookieName=CookieValue; path=/;");
Response.SetCookie(new HttpCookie("session-id") { Value = Guid.NewGuid().ToString(), HttpOnly = false });
Response.SetCookie(new HttpCookie("user-name") { Value = data.Login, HttpOnly = false });
But you should not because it may change secure to un-secure, so you have to find out solution that be done in server side to delete cookies and allow to you do some operations.
Its possible to do changes in server side.
Related
I am using js.cookie CDN to get cookie .In my browser there is a Cookie with name sessionid ,(set by django backend itself) ,having some value , but
Cookie.get('sessionid') is giving undefined
//CDN : <script src="https://cdn.jsdelivr.net/npm/js-cookie#rc/dist/js.cookie.min.js"></script>
You can not get value of that cookie (sessionid) because it has set HttpOnly to true. That means, that cookie is only received and send through http, but is not accessible by javascript. That is for security reason to prevent stealing session.
If you really need this, maybe you can change the HttpOnly setting on server side - somewhere in django, or write it on page and then access it with jquery. But that would compromise security.
in Django you can get the session_id by using => request.session.session_key . You are new to SO, check the older questions it is easier.
In Django, how can I find out the request.session sessionid and use it as a variable?
since we sending on client side ,In django we can also set a key in settings.py
SESSION_COOKIE_HTTPONLY = False
Javascript not reading cookies set by Laravel in the same domain and returning undefined.
It's only reading the XSRF-Token but not any other cookies whether be it encrypted or unencrypted.
The URL is: http://localhost:8000/myaccount
and here is the cookie screenshot
I'm using JS Cookie library .. It's not reading either using document.cookie or Cookies.get('user_id') only the XSRF-TOKEN is reading.
Cookie user-id has http-only flag set to true.
It is not therefore accessible by javascript.
Try and set http-only flag to false.
edit: check this other SO answer it might get you started
The cookie is HttpOnly, therefore cannot be read by Javascript. You have to set the cookie as $httpOnly = false
See the last parameter of CookieJar::make method - which is mirrored in facade Cookie::make method.
I have tried to set a cookie using document.cookie = "tagname = test; secure" but this does not set the secure flag. Am I setting it wrong? Can you only set it from a server response? I am also wondering that, because I have had a difficult time finding an example of its use, that it probably is not commonly used?
Thanks a bunch!
TL:DR
document.cookie = "tagname = test;secure";
You have to use HTTPS to set a secure attribute
The normal (or formal, maybe) name is attribute. Since the flag refers to other things.
More Info
Cookie attributes:
Secure - Cookie will be sent in HTTPS transmission only.
HttpOnly- Don't allow scripts to access cookie. You can set both of the Secure and HttpOnly.
Domain- specify the hosts to which the cookie will be sent.
Path - create scopes, cookie will be sent only if the path matches.
Expires - indicates the maximum lifetime of the cookie.
More details and practical usages. Check Testing_for_cookies_attributes_(OTG-SESS-002)
UPDATES
The following contents expire in June 2, 2016.
Cookie Flags
Cookie flags are prefixes. At the moment, they are described in the RFC draft as a update to the RFC6265
These flags are used with the 'secure' attribute.
__Secure-
The dash is a part of the prefix. This flag tells the browser, the cookie should only be included in 'https'.
__Host-
A cookie with this flag
must not have 'domain' attribute, it will be only sent to the host which set it.
Must have a 'path' attribute, that is set to '/', because it will be sent to the host in every request from the host.
because the flag is called secure, not security:
document.cookie = "tagname = test;secure";
This cookie package is easy to use # https://www.npmjs.com/package/js-cookie
//to set cookie use
Cookies.set('name', 'value', { expires: 7, path: '' });
//to read the cookie, use
Cookies.get('name'); // => 'value'
//to delete cookie this
Cookies.remove('name')
//to set secure cookie this
Cookies.set('name', 'value', { secure: true });
Although the server responded with Upper case, and separate with space:
set-cookie: x = y; Secure
The client javascript needs to lowercase the secure and delete the whitespace after ;, like so:
document.cookie = `x=y;secure`;
Otherwise, it will be no effect.
This is an example for ExpressJs users:
Set secure cookie
res.cookie("name", "value", { secure: true });
Read this cookie
req.cookies["name"];
When the Secure attribute is set on a cookie, the browser will include it in
the request only when the request is made through HTTPS and not through
HTTP .
It's a best practice to use this attribute for sensitive cookies as it will
protect them from being sent over insecure connection.
Is it possible to make a request from a browser, preferably using the built-in XMLHttpRequest API, "WITHOUT" sending any cookies in the request headers?
As far as I understand setting the "allowCredentials" property to false will only disable cookies for CORS requests, where I want to make a request to the same server while not sending a "Cookie" header.
I know this sounds a bit strange, but because of current project constrains I do not have the ability to alter the Server to change the "path" in the "Set-Cookie" response header.
I'm not sure if there is a way to exclude cookies for a single request.
If you know the names of the cookies and they will not be needed by other requests later, you can delete their values like this:
document.cookie="COOKIENAME=";
The cookie names will still be there though.
If you need the values later, you can save the cookies to a variable:
var cookie = document.cookie;
// Delete the cookie values like above.
// Make a request without cookie values.
document.cookie=cookie;
But if you need to make requests with and without cookie values at the same time, this will obviously not work. And if the cookies have the HTTPOnly attribute, you will not be able to read them or change their values.
As the question says can you find out if a cookie exists within Javascript if it is a HttpOnly? I don't need to access the information inside of it, just know it has one.
A little more information on the situation is that there was originally a web server which used a cookie as an authentication token, and it was set to httponly as it was not used by the client so it added to the security.
However now there is a change needed where the client needs to know if it has the cookie (as the site can work without the user being logged in, but if they are logged in (the auth cookie would exist) the site needs to display certain things and hide others.
There are other security precautions in place on the web server so there is no harm in the scenario where the client has an incorrect auth cookie, but the site makes it look like they are logged in, as it would delete the cookie and reject the user.
You can indirectly check to see if it exists by trying to set it to a value with javascript if it can't be set, then the HTTP Only Cookie must be there (or the user is blocking cookies).
function doesHttpOnlyCookieExist(cookiename) {
var d = new Date();
d.setTime(d.getTime() + (1000));
var expires = "expires=" + d.toUTCString();
document.cookie = cookiename + "=new_value;path=/;" + expires;
return document.cookie.indexOf(cookiename + '=') == -1;
}
I had the same problem. I solved it with the server setting another cookie, not httponly, every time it refreshed the httponly session cookie, with the same max-age and no sensitive data. Now, if one of them is present, the same goes for the other, and the client can know if the httponly counterpart is there.
No. And see Rob's comments below.
See this, which you probably already saw - http://en.wikipedia.org/wiki/HTTP_cookie#Secure_and_HttpOnly
An HttpOnly cookie is not accessible via non-HTTP methods, such as
calls via JavaScript (e.g., referencing "document.cookie")...
Edit: Removed undefined response, I wrote a script that you may not be using :)
Whenever you need to check whether the cookie exists or not, you can send a request to the server that requires authentication & check the response. If its something like 401 Unauthorized or 403 Forbidden, then the cookie probably doesn't exist & you can prompt the user for login.
On the other hand, if the cookie exists, it'll be automatically sent by the browser resulting in a 200 OK response.