[javascript] CodeQL query to detect if cookies are sent without the flag secure being set#3978
Conversation
| <recommendation> | ||
|
|
||
| <p>Always set the <code>secure</code> flag to `true` on a cookie before adding it | ||
| <p>Always set the `secure` flag to `true` on a cookie before adding it |
There was a problem hiding this comment.
Why did you change this?
As far as I know, this will not work, but <code> will work.
There was a problem hiding this comment.
Sorry, I was thinking the opposite. Thanks for the feedback. I made the change.
esbena
left a comment
There was a problem hiding this comment.
Very nice. I only have some minor change requests.
Have you seen https://github.com/github/codeql/blob/71933a4d8a32d32f085f14b7b44f41d1cdcae2e4/javascript/ql/src/semmle/javascript/frameworks/CookieLibraries.qll ? It could inspire some changes to this PR, or perhaps some of the content in this PR belongs in that file (note that this file is not in "experimental", so I will set the bar a review bar a bit higher)?
One large, and optional, change to consider.
The qhelp file is a bit verbose in terms of examples. Could you remove some of them, and perhaps add them as tests instead? See #3835 (comment) for how another external contributor recently made tests.
It is a bit of a shame that result = this.getCookieOptionsArgument().getAPropertyWrite(flag).getRhs() has to be repeated so many times. This could be fixed with some additional inheritance, but that is a matter of taste.
Generally. Whenever you write exist(X x | x = getX() and ...) without ever using the x more than once, you can write exists(getX()) and ... instead.
| /** | ||
| * Abstract class to represent different cases of insecure cookie settings. | ||
| */ | ||
| abstract class InsecureCookies extends DataFlow::Node { |
There was a problem hiding this comment.
Could we rename the entire InsecureCookie module and class to just Cookie, and then just let the isInsecure determine if the cookie is secure or not.
There was a problem hiding this comment.
Yes, no problem. I made the change.
| * Predicate that determines if a cookie is insecure. | ||
| */ | ||
| abstract predicate isInsecure(); |
There was a problem hiding this comment.
| * Predicate that determines if a cookie is insecure. | |
| */ | |
| abstract predicate isInsecure(); | |
| * Holds if this cookie is secure. | |
| */ | |
| abstract predicate isSecure(); |
Optional: I think it is clearer to flip the polarity and avoid the negation in the predicate name.
Please note that this requires a change to all implementations of this predicate below.
There was a problem hiding this comment.
Yes, I agree with you. I changed the polarity (I did it in one commit) of all the implementations of this predicate.
| override predicate isInsecure() { | ||
| not exists(string s | | ||
| getCookieOptionsArgument().mayHaveStringValue(s) and | ||
| s.matches("%; secure%") |
There was a problem hiding this comment.
Hmm. What if the string is ...;secure...? That is: it lacks a space between ; and secure.
How about something likes.regexpMatch("(.*;)?\\s*secure.*") instead? That should allow any whitespace variation, and also permit the string to start with secure.
There was a problem hiding this comment.
Again, you are right. I missed that. I made the change
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
|
Hi @esbena, sorry for the late reply. About the I made all the changes that you suggested and then I also changed the polarity of the predicate Finally, I removed all the examples and I added them as tests, as you suggested (I hope I added in the correct folder). Let me know if now it’s ok and if there is something else I can do. |
|
Thanks. The new tests seem fine. |
|
Thanks for your reply. I formatted the code. |
esbena
left a comment
There was a problem hiding this comment.
Oops. Forgot to attach the inline feedback. PTAL
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
….qll Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
|
@esbena, no problem :) Let me know if there is something else I can do. |
|
esbena
left a comment
There was a problem hiding this comment.
One more thing. I stumbled upon it when I looked at the results of the query on LGTM.com.
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
|
@intrigus-lgtm thanks for the tip. @esbena I made the changes and updated the expected output. |
|
I took the liberty of pushing a formatting fix to your branch. The tests should go green shortly. |
|
Thank you for yet another contribution @dellalibera. |
|
@esbena It was really a pleasure. Thank you for all the feedback. |
Query to detect if the
secureflag is set to cookies is available in java query but it is not available in javascript query.This query detects if cookies are sent without the flag
securebeing set or with the flagsecurebeing set tofalse.Failing to set the
secureflag on a cookie can cause it to be sent in cleartext.This makes it easier for an attacker to intercept and read the cookie.
This query handles the cases when cookies are set with:
cookie-session(https://github.com/expressjs/cookie-session)express-session(https://github.com/expressjs/session)response.cookie(https://expressjs.com/en/api.html#res.cookie)Set-Cookieof an HTTP response (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie)js-cookie(https://github.com/js-cookie/js-cookie)I added several examples showing the different cases when the cookie is sent without the flag
securebeing set or with the flagsecurebeing set tofalse.Any feedback is welcome.
I hope this will help.