EDIT
What one means by "a secure cookie" is ambiguous. To clarify:
Secure as in sent over the https:// protocol — ie. cookie is not sent in plaintext. Known as the "secure flag"
Secure as in the cookie cannot be read by Javascript running in the
browser — ie.
document.cookie will not work. Known as the "HttpOnly" flag.
This edit is to clarify that the original question is asking about the 2nd case.
Original Question
Is there any way to read a secure cookie with JavaScript?
I tried to do it using document.cookie and as far as I can see on this article about secure cookies and HttpOnly flag, I cannot access a secure cookie this way.
Can anyone suggest a workaround?
Different Browsers enable different security measures when the HTTPOnly flag is set. For instance Opera and Safari do not prevent javascript from writing to the cookie. However, reading is always forbidden on the latest version of all major browsers.
But more importantly why do you want to read an HTTPOnly cookie? If you are a developer, just disable the flag and make sure you test your code for xss. I recommend that you avoid disabling this flag if at all possible. The HTTPOnly flag and "secure flag" (which forces the cookie to be sent over https) should always be set.
If you are an attacker, then you want to hijack a session. But there is an easy way to hijack a session despite the HTTPOnly flag. You can still ride on the session without knowing the session id. The MySpace Samy worm did just that. It used an XHR to read a CSRF token and then perform an authorized task. Therefore, the attacker could do almost anything that the logged user could do.
People have too much faith in the HTTPOnly flag, XSS can still be exploitable. You should setup barriers around sensitive features. Such as the change password filed should require the current password. An admin's ability to create a new account should require a captcha, which is a CSRF prevention technique that cannot be easily bypassed with an XHR.
The whole point of HttpOnly cookies is that they can't be accessed by JavaScript.
The only way (except for exploiting browser bugs) for your script to read them is to have a cooperating script on the server that will read the cookie value and echo it back as part of the response content. But if you can and would do that, why use HttpOnly cookies in the first place?
You can not. Httponly cookies' purpose is being inaccessible by script.
Related
Goal:
When using JWT, I need to secure cookies and mitigate XSS attack vector in clients.
I understand that a cookie with the HttpOnly attribute is inaccessible to the JavaScript Document.cookie API in the client. The server can access the cookie to for session management (shipping cart, game scores, etc), personalization and, user behavior tracking but JavaScript code can no longer read and write to the cookie in the client.
Reference:https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies
Question:
If I am able to enable HttpOnly, is there any practical gain to encrypt the JWT (JWE)? I see that encryption for the JWT is described on https://www.rfc-editor.org/rfc/rfc7516.
I have not seen posts to indicate that JWE has been a practical choice though.
I would appreciate your insight before I explore the deployment of JWE in production.
One potential benefit would be that if the JWT is encrypted, the client won't be able to view and tweak it manually. Even if there aren't any malicious scripts running, there may well still be several inquisitive users who know how to open the developer console and change things - to see what they can break, or gain privileges they shouldn't, or just for the heck of it. If the JWT is encrypted so that only you on the server can decrypt it, that makes things easier for you because the client has no way to change the payload without breaking it entirely (unless they have another JWT saved or found somewhere).
If a cookie is set with samesite strict, is it possible to be sent with a javascript to another site, like using javascript to get the cookie and send it to another user?
Yes, samesite cookies can be read using javascript. So they are vulnerable to XSS attacks same as any other cookie.
You can test this out yourself, by opening chrome inspector on any website and typing the following:
// Set cookie
document.cookie = 'auth=lol;samesite=strict';
// Read cookie
console.log(document.cookie); // "auth=lol"
You may be thinking of httpOnly? Setting httpOnly will prevent reading in javascript, and will therefore prevent XSS. https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Security
Yes. You refer to a state where you run a script on a client's browser. A samesite cookie indicates the behavior of a browser's request when it handles a site's cookies, but it is still accessible locally by the scripts.
Like #jameslol said, you may refer to HttpOnly flagged cookies.
A server can set the HttpOnly flag for a Set-Cookie response header. If your target's browser supports the HttpOnly flag, then local scripts cannot access the cookie.
However, if the browser doesn't support this flag, it will set a regular cookie instead, yielding the cookie(s) accessible by the client scripts.
Additional reading :
HttpOnly flag
List of HttpOnly flag browser support table
samesite flag and CSRF attacks
I have an application where I send the auth token to the server with every request as a cookie in the header request. Also, I force the app to run over HTTPS, so cookie headers are encrypted. However, I know that's not enough keep the cookie inaccessible to (XSS) attacks. I thought of the HttpOnly option, but that won't help since it can't be accessible by Javascript.
Is there any other options that I can do to better secure the cookie that I send in the header request?
When using cookie-based authentication, the HttpOnly flag is the one you're looking for: when the user logs in, the server sends the HttpOnly cookie to the browser, which is not accessible by JavaScript and shouldn't be accessible by JavaScript, the only important part is that the browser will automatically send the cookie to the server for every request matching the domain of the cookie.
What you need to keep in mind is that cookie-based authentication needs an additional mechanism to protect against CSRF.
If, on the other hand, you're using OpenID Connect or OAuth2 authentication and want to store the access token in a cookie, then yes, you can't use HttpOnly flag. But it also doesn't make sense to encrypt that cookie with some magic, because if someone can steal the cookie, they'd steal the correctly encrypted cookie which remains valid. The key thing here is, you should protect every input on your website against XSS: if you have text-inputs, you'll have to filter the input against XSS attacks, for PHP you could take a look at the AntiXSS library. Also don't link to client-side libraries, images or other resources from CDN's you don't trust as scripts could be injected from there too.
For access tokens, no matter what method you're using to store or encrypt it, the access token is always prone to XSS, because your own JavaScript application needs access to it. That's the main reason why an access token is, and should always be, short living (max 1 hour f.e.).
I have read the OWASP information and also a range of articles including Jeff Atwood's Protecting Your Cookies article and I still feel I need to understand HttpOnly cookies better.
This came about because I needed to add some Google Adword tracking code to a site. This javascript needed to set and read a cookie on the website's domain and I assumed that this was an issue. The website is a .Net application with httpOnlyCookies="true" in the web.config, so I assumed that the best approach would be to replace the javascript and write the cookie from the backend to ensure that the generated cookie was HttpOnly. I could then easily read the cookie in the server-side too.
I understand that setting the HttpOnly of a cookie property largely prevents a cookie from being read and manipulated by the client. But what I don't understand is:
Given the example above, would there have been a problem with me using the javascript implementation?
Would it still have been ok to write the cookie using javascript (but still read it using the server-side)? I'm thinking not as the cookie is then not a HttpOnly cookie
If I have done the right thing (moving everything to a server-side implementation), why are Google Analytic cookies always implemented as non-HttpOnly cookies? Surely they pose a security issue too?
So as the title says, I guess what I'm asking is - when (if ever) is it appropriate to have non-HttpOnly cookies on your domain?
So this is much more straightforward than I assumed. According to the comments left by #mah above, flagging a cookie as HttpOnly is redundant when the cookie contains non-sensitive information.
The httpOnly option was response to JavaScript tricks to steal user's session cookie. It was because the session cookie is a temporary credential that allows you access to user's logged-in session on the server.
In case of any other, non-session cookies it really depends on your own risk assessment. If you're not really concerned about slightly increased exposure without httpOnly or you just have a business need to access their values from JavaScript, just ignore this option.
Some security scanners or incompetent pentesting teams will report missing httpOnly flags for each cookie just because it's trivial to spot and allows them to easily inflate their report. But explaining the actual purpose and origin of httpOnly should be sufficient to counter that.
I've installed the cookie extension for jquery, and am attempting to access the session id cookie.
I currently have two cookies for my session - see screenshot below:
however, $.cookie() only lists one:
> $.cookie()
Object {csrftoken: "fFrlipYaeUmWkkzLrQLwepyACzTfDXHE"}
> $.cookie('sessionid')
undefined
can i/how do i access the sessionid cookie from javascript?
The session id cookie should be marked as HTTP Only, preventing access from javascript. This is a security issue, preventing session hijacking via an xss vulnerability.
You can see in your screenshot that the cookie is indeed marked as HTTP.
If you want to learn more about the flag see here. Originally implemented by IE, most browsers support the flag nowadays, and session cookies not marked http-only are considered a security flaw. Also see here.