documentation overhaul for clear-text-cookie

This commit is contained in:
Erik Krogh Kristensen
2021-10-06 11:53:38 +02:00
parent f36accf3e6
commit ab23ffff3d
11 changed files with 98 additions and 59 deletions

View File

@@ -0,0 +1,38 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Cookies that are transmitted in clear text can be intercepted by an attacker.
If sensitive cookies are intercepted, the attacker can read the cookie and
use it to perform actions on the user's behalf.
</p>
</overview>
<recommendation>
<p>
Always transmit sensitive cookies using SSL by setting the <code>secure</code>
attribute on the cookie.
</p>
</recommendation>
<example>
<p>
The following example stores an authentication token in a cookie that can
be transmitted in clear text.
</p>
<sample src="examples/CleartextStorageBad.js"/>
<p>
To force the cookie to be transmitted using SSL, set the <code>secure</code>
attribute on the cookie.
</p>
<sample src="examples/CleartextStorageGood.js"/>
</example>
<references>
<li>ExpressJS: <a href="https://expressjs.com/en/advanced/best-practice-security.html#use-cookies-securely">Use cookies securely</a>.</li>
<li>OWASP: <a href="https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html#set-cookie-flags-appropriately">Set cookie flags appropriately</a>.</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie">Set-Cookie</a>.</li>
</references>
</qhelp>

View File

@@ -0,0 +1,20 @@
/**
* @name Clear text transmission of sensitive cookie
* @description Sending sensitive information in a cookie without requring SSL encryption
* can expose the cookie to an attacker.
* @kind problem
* @problem.severity warning
* @security-severity 5.0
* @precision high
* @id js/clear-text-cookie
* @tags security
* external/cwe/cwe-614
* external/cwe/cwe-311
* external/cwe/cwe-312
*/
import javascript
from CookieWrites::CookieWrite cookie
where cookie.isSensitive() and not cookie.isSecure()
select cookie, "Sensitive cookie sent without enforcing SSL encryption"

View File

@@ -1,26 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Failing to set the 'secure' flag on a cookie can cause it to be sent in cleartext.
This makes it easier for an attacker to intercept.</p>
</overview>
<recommendation>
<p>Always set the <code>secure</code> flag to `true` on a cookie before adding it
to an HTTP response (if the default value is `false`).</p>
</recommendation>
<references>
<li>Production Best Practices: Security:<a href="https://expressjs.com/en/advanced/best-practice-security.html#use-cookies-securely">Use cookies securely</a>.</li>
<li>NodeJS security cheat sheet:<a href="https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html#set-cookie-flags-appropriately">Set cookie flags appropriately</a>.</li>
<li>express-session:<a href="https://github.com/expressjs/session#cookiesecure">cookie.secure</a>.</li>
<li>cookie-session:<a href="https://github.com/expressjs/cookie-session#cookie-options">Cookie Options</a>.</li>
<li><a href="https://expressjs.com/en/api.html#res.cookie">express response.cookie</a>.</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie">Set-Cookie</a>.</li>
<li><a href="https://github.com/js-cookie/js-cookie">js-cookie</a>.</li>
</references>
</qhelp>

View File

@@ -1,21 +0,0 @@
/**
* @name Failure to set secure cookies
* @description Insecure cookies may be sent in cleartext, which makes them vulnerable to
* interception.
* @kind problem
* @problem.severity error
* @precision high
* @id js/insecure-cookie
* @tags security
* external/cwe/cwe-614
*/
import javascript
// TODO: Rename to ClearTextCookie?
from DataFlow::Node node
where
exists(CookieWrites::CookieWrite cookie | cookie = node |
cookie.isSensitive() and not cookie.isSecure()
)
select node, "Cookie is added to response without the 'secure' flag being set to true"

View File

@@ -0,0 +1,7 @@
const http = require('http');
const server = http.createServer((req, res) => {
res.setHeader("Set-Cookie", `authKey=${makeAuthkey()}`);
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h2>Hello world</h2>');
});

View File

@@ -0,0 +1,7 @@
const http = require('http');
const server = http.createServer((req, res) => {
res.setHeader("Set-Cookie", `authKey=${makeAuthkey()}; secure; httpOnly`);
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h2>Hello world</h2>');
});

View File

@@ -0,0 +1,12 @@
| tst-cleartextCookie.js:5:5:10:10 | res.coo ... }) | Sensitive cookie sent without enforcing SSL encryption |
| tst-cleartextCookie.js:20:5:20:43 | res.coo ... ptions) | Sensitive cookie sent without enforcing SSL encryption |
| tst-cleartextCookie.js:35:1:35:52 | js_cook ... alse }) | Sensitive cookie sent without enforcing SSL encryption |
| tst-cleartextCookie.js:44:37:44:51 | "authKey=ninja" | Sensitive cookie sent without enforcing SSL encryption |
| tst-cleartextCookie.js:64:38:64:52 | "authKey=ninja" | Sensitive cookie sent without enforcing SSL encryption |
| tst-cleartextCookie.js:94:60:94:72 | "authKey=foo" | Sensitive cookie sent without enforcing SSL encryption |
| tst-cleartextCookie.js:104:9:107:2 | session ... T OK\\n}) | Sensitive cookie sent without enforcing SSL encryption |
| tst-cleartextCookie.js:109:9:112:2 | session ... T OK\\n}) | Sensitive cookie sent without enforcing SSL encryption |
| tst-cleartextCookie.js:114:9:117:2 | session ... T OK\\n}) | Sensitive cookie sent without enforcing SSL encryption |
| tst-cleartextCookie.js:124:9:124:21 | session(sess) | Sensitive cookie sent without enforcing SSL encryption |
| tst-cleartextCookie.js:148:9:156:2 | session ... Date\\n}) | Sensitive cookie sent without enforcing SSL encryption |
| tst-cleartextCookie.js:160:33:160:58 | `authKe ... key()}` | Sensitive cookie sent without enforcing SSL encryption |

View File

@@ -0,0 +1 @@
Security/CWE-614/ClearTextCookie.ql

View File

@@ -1,11 +0,0 @@
| tst-cleartextCookie.js:5:5:10:10 | res.coo ... }) | Cookie is added to response without the 'secure' flag being set to true |
| tst-cleartextCookie.js:20:5:20:43 | res.coo ... ptions) | Cookie is added to response without the 'secure' flag being set to true |
| tst-cleartextCookie.js:35:1:35:52 | js_cook ... alse }) | Cookie is added to response without the 'secure' flag being set to true |
| tst-cleartextCookie.js:44:37:44:51 | "authKey=ninja" | Cookie is added to response without the 'secure' flag being set to true |
| tst-cleartextCookie.js:64:38:64:52 | "authKey=ninja" | Cookie is added to response without the 'secure' flag being set to true |
| tst-cleartextCookie.js:94:60:94:72 | "authKey=foo" | Cookie is added to response without the 'secure' flag being set to true |
| tst-cleartextCookie.js:104:9:107:2 | session ... T OK\\n}) | Cookie is added to response without the 'secure' flag being set to true |
| tst-cleartextCookie.js:109:9:112:2 | session ... T OK\\n}) | Cookie is added to response without the 'secure' flag being set to true |
| tst-cleartextCookie.js:114:9:117:2 | session ... T OK\\n}) | Cookie is added to response without the 'secure' flag being set to true |
| tst-cleartextCookie.js:124:9:124:21 | session(sess) | Cookie is added to response without the 'secure' flag being set to true |
| tst-cleartextCookie.js:148:9:156:2 | session ... Date\\n}) | Cookie is added to response without the 'secure' flag being set to true |

View File

@@ -1 +0,0 @@
Security/CWE-614/InsecureCookie.ql

View File

@@ -154,3 +154,16 @@ app.use(session({
path: 'foo/bar',
expires: expiryDate
}))
http.createServer((req, res) => {
res.setHeader('Content-Type', 'text/html');
res.setHeader("Set-Cookie", `authKey=${makeAuthkey()}`); // NOT OK
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('ok');
});
http.createServer((req, res) => {
res.setHeader("Set-Cookie", `authKey=${makeAuthkey()}; secure; httpOnly`); // OK
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h2>Hello world</h2>');
});