mirror of
https://github.com/github/codeql.git
synced 2026-05-04 05:05:12 +02:00
Merge branch 'main' into ts4
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
* @id js/duplicate-html-id
|
||||
* @tags maintainability
|
||||
* correctness
|
||||
* @precision high
|
||||
* @precision low
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<overview>
|
||||
<p>
|
||||
|
||||
Sanitizing untrusted input for HTML meta-characters is an important
|
||||
Sanitizing untrusted input for HTML meta-characters is a common
|
||||
technique for preventing cross-site scripting attacks. Usually, this
|
||||
is done by escaping <code><</code>, <code>></code>,
|
||||
<code>&</code> and <code>"</code>. However, the context in which
|
||||
@@ -38,6 +38,14 @@
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
An even safer alternative is to design the application
|
||||
so that sanitization is not needed, for instance by using HTML
|
||||
templates that are explicit about the values they treat as HTML.
|
||||
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
Sanitizing untrusted input is an important technique for preventing injection attacks such as
|
||||
Sanitizing untrusted input is a common technique for preventing injection attacks such as
|
||||
SQL injection or cross-site scripting. Usually, this is done by escaping meta-characters such
|
||||
as quotes in a domain-specific way so that they are treated as normal characters.
|
||||
</p>
|
||||
@@ -31,6 +31,14 @@ still have undesirable effects, such as badly rendered or confusing output.
|
||||
Use a (well-tested) sanitization library if at all possible. These libraries are much more
|
||||
likely to handle corner cases correctly than a custom implementation.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
An even safer alternative is to design the application so that sanitization is not
|
||||
needed, for instance by using prepared statements for SQL queries.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Otherwise, make sure to use a regular expression with the <code>g</code> flag to ensure that
|
||||
all occurrences are replaced, and remember to escape backslashes if applicable.
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<overview>
|
||||
<p>
|
||||
|
||||
Sanitizing untrusted input for HTML meta-characters is an
|
||||
important technique for preventing cross-site scripting attacks. But
|
||||
Sanitizing untrusted input for HTML meta-characters is a
|
||||
common technique for preventing cross-site scripting attacks. But
|
||||
even a sanitized input can be dangerous to use if it is modified
|
||||
further before a browser treats it as HTML.
|
||||
|
||||
@@ -28,6 +28,15 @@
|
||||
them as HTML.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
An even safer alternative is to design the application
|
||||
so that sanitization is not needed, for instance by using HTML
|
||||
templates that are explicit about the values they treat as HTML.
|
||||
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<overview>
|
||||
<p>
|
||||
|
||||
Sanitizing untrusted HTTP request parameters is an important
|
||||
Sanitizing untrusted HTTP request parameters is a common
|
||||
technique for preventing injection attacks such as SQL injection or
|
||||
path traversal. This is sometimes done by checking if the request
|
||||
parameters contain blacklisted substrings.
|
||||
@@ -35,6 +35,15 @@
|
||||
is user-controlled.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
An even safer alternative is to design the application so that sanitization is not
|
||||
needed, for instance by using prepared statements for SQL queries.
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<!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>
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @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
|
||||
import InsecureCookie::Cookie
|
||||
|
||||
from Cookie cookie
|
||||
where not cookie.isSecure()
|
||||
select cookie, "Cookie is added to response without the 'secure' flag being set to true"
|
||||
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
* Provides classes for reasoning about cookies added to response without the 'secure' flag being set.
|
||||
* A cookie without the 'secure' flag being set can be intercepted and read by a malicious user.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
module Cookie {
|
||||
/**
|
||||
* `secure` property of the cookie options.
|
||||
*/
|
||||
string flag() { result = "secure" }
|
||||
|
||||
/**
|
||||
* Abstract class to represent different cases of insecure cookie settings.
|
||||
*/
|
||||
abstract class Cookie extends DataFlow::Node {
|
||||
/**
|
||||
* Gets the name of the middleware/library used to set the cookie.
|
||||
*/
|
||||
abstract string getKind();
|
||||
|
||||
/**
|
||||
* Gets the options used to set this cookie, if any.
|
||||
*/
|
||||
abstract DataFlow::Node getCookieOptionsArgument();
|
||||
|
||||
/**
|
||||
* Holds if this cookie is secure.
|
||||
*/
|
||||
abstract predicate isSecure();
|
||||
}
|
||||
|
||||
/**
|
||||
* A cookie set using the `express` module `cookie-session` (https://github.com/expressjs/cookie-session).
|
||||
*/
|
||||
class InsecureCookieSession extends ExpressLibraries::CookieSession::MiddlewareInstance, Cookie {
|
||||
override string getKind() { result = "cookie-session" }
|
||||
|
||||
override DataFlow::SourceNode getCookieOptionsArgument() { result = this.getOption("cookie") }
|
||||
|
||||
private DataFlow::Node getCookieFlagValue(string flag) {
|
||||
result = this.getCookieOptionsArgument().getAPropertyWrite(flag).getRhs()
|
||||
}
|
||||
|
||||
override predicate isSecure() {
|
||||
// The flag `secure` is set to `false` by default for HTTP, `true` by default for HTTPS (https://github.com/expressjs/cookie-session#cookie-options).
|
||||
// A cookie is secure if the `secure` flag is not explicitly set to `false`.
|
||||
not getCookieFlagValue(flag()).mayHaveBooleanValue(false)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A cookie set using the `express` module `express-session` (https://github.com/expressjs/session).
|
||||
*/
|
||||
class InsecureExpressSessionCookie extends ExpressLibraries::ExpressSession::MiddlewareInstance,
|
||||
Cookie {
|
||||
override string getKind() { result = "express-session" }
|
||||
|
||||
override DataFlow::SourceNode getCookieOptionsArgument() { result = this.getOption("cookie") }
|
||||
|
||||
private DataFlow::Node getCookieFlagValue(string flag) {
|
||||
result = this.getCookieOptionsArgument().getAPropertyWrite(flag).getRhs()
|
||||
}
|
||||
|
||||
override predicate isSecure() {
|
||||
// The flag `secure` is not set by default (https://github.com/expressjs/session#Cookieecure).
|
||||
// The default value for cookie options is { path: '/', httpOnly: true, secure: false, maxAge: null }.
|
||||
// A cookie is secure if there are the cookie options with the `secure` flag set to `true` or to `auto`.
|
||||
getCookieFlagValue(flag()).mayHaveBooleanValue(true) or
|
||||
getCookieFlagValue(flag()).mayHaveStringValue("auto")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A cookie set using `response.cookie` from `express` module (https://expressjs.com/en/api.html#res.cookie).
|
||||
*/
|
||||
class InsecureExpressCookieResponse extends Cookie, DataFlow::MethodCallNode {
|
||||
InsecureExpressCookieResponse() { this.calls(any(Express::ResponseExpr r).flow(), "cookie") }
|
||||
|
||||
override string getKind() { result = "response.cookie" }
|
||||
|
||||
override DataFlow::SourceNode getCookieOptionsArgument() {
|
||||
result = this.getLastArgument().getALocalSource()
|
||||
}
|
||||
|
||||
private DataFlow::Node getCookieFlagValue(string flag) {
|
||||
result = this.getCookieOptionsArgument().getAPropertyWrite(flag).getRhs()
|
||||
}
|
||||
|
||||
override predicate isSecure() {
|
||||
// A cookie is secure if there are cookie options with the `secure` flag set to `true`.
|
||||
getCookieFlagValue(flag()).mayHaveBooleanValue(true)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A cookie set using `Set-Cookie` header of an `HTTP` response (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie).
|
||||
*/
|
||||
class InsecureSetCookieHeader extends Cookie {
|
||||
InsecureSetCookieHeader() {
|
||||
this.asExpr() = any(HTTP::SetCookieHeader setCookie).getHeaderArgument()
|
||||
}
|
||||
|
||||
override string getKind() { result = "set-cookie header" }
|
||||
|
||||
override DataFlow::Node getCookieOptionsArgument() {
|
||||
result.asExpr() = this.asExpr().(ArrayExpr).getAnElement()
|
||||
}
|
||||
|
||||
override predicate isSecure() {
|
||||
// A cookie is secure if the 'secure' flag is specified in the cookie definition.
|
||||
exists(string s |
|
||||
getCookieOptionsArgument().mayHaveStringValue(s) and
|
||||
s.regexpMatch("(.*;)?\\s*secure.*")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A cookie set using `js-cookie` library (https://github.com/js-cookie/js-cookie).
|
||||
*/
|
||||
class InsecureJsCookie extends Cookie {
|
||||
InsecureJsCookie() {
|
||||
this =
|
||||
[DataFlow::globalVarRef("Cookie"),
|
||||
DataFlow::globalVarRef("Cookie").getAMemberCall("noConflict"),
|
||||
DataFlow::moduleImport("js-cookie")].getAMemberCall("set")
|
||||
}
|
||||
|
||||
override string getKind() { result = "js-cookie" }
|
||||
|
||||
override DataFlow::SourceNode getCookieOptionsArgument() {
|
||||
result = this.(DataFlow::CallNode).getAnArgument().getALocalSource()
|
||||
}
|
||||
|
||||
DataFlow::Node getCookieFlagValue(string flag) {
|
||||
result = this.getCookieOptionsArgument().getAPropertyWrite(flag).getRhs()
|
||||
}
|
||||
|
||||
override predicate isSecure() {
|
||||
// A cookie is secure if there are cookie options with the `secure` flag set to `true`.
|
||||
getCookieFlagValue(flag()).mayHaveBooleanValue(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,6 +181,7 @@ class JSXQualifiedName extends Expr, @jsxqualifiedname {
|
||||
class JSXName extends Expr {
|
||||
JSXName() {
|
||||
this instanceof Identifier or
|
||||
this instanceof ThisExpr or
|
||||
this.(DotExpr).getBase() instanceof JSXName or
|
||||
this instanceof JSXQualifiedName
|
||||
}
|
||||
@@ -198,6 +199,9 @@ class JSXName extends Expr {
|
||||
exists(JSXQualifiedName qual | qual = this |
|
||||
result = qual.getNamespace().getName() + ":" + qual.getName().getName()
|
||||
)
|
||||
or
|
||||
this instanceof ThisExpr and
|
||||
result = "this"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -162,6 +162,17 @@ private predicate isRequire(DataFlow::Node nd) {
|
||||
not nd.getFile().getExtension() = "mjs"
|
||||
or
|
||||
isRequire(nd.getAPredecessor())
|
||||
or
|
||||
// `import { createRequire } from 'module';` support.
|
||||
// specialized to ES2015 modules to avoid recursion in the `DataFlow::moduleImport()` predicate.
|
||||
exists(ImportDeclaration imp | imp.getImportedPath().getValue() = "module" |
|
||||
nd =
|
||||
imp
|
||||
.getImportedModuleNode()
|
||||
.(DataFlow::SourceNode)
|
||||
.getAPropertyRead("createRequire")
|
||||
.getACall()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
console.log(".mjs inside a `type:\"commonjs\" is still a ES2015 module`");
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
console.log("I'm empty! The containing package.json determines the type.");
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
console.log(".cjs inside a `type:\"module\" is still a CommonJS module`");
|
||||
@@ -0,0 +1 @@
|
||||
console.log();
|
||||
@@ -0,0 +1 @@
|
||||
console.log("I'm empty! The containing package.json determines the type.");
|
||||
@@ -1,5 +1,10 @@
|
||||
| commonjs.cjs:1:1:3:16 | <toplevel> | node |
|
||||
| commonjsPackage/innermjs.mjs:1:1:1:74 | <toplevel> | es2015 |
|
||||
| commonjsPackage/tst.js:1:1:1:75 | <toplevel> | node |
|
||||
| import.js:1:1:5:2 | <toplevel> | es2015 |
|
||||
| mjs.mjs:1:1:1:32 | <toplevel> | es2015 |
|
||||
| modulePackage/subdir/innercjs.cjs:1:1:1:74 | <toplevel> | node |
|
||||
| modulePackage/subdir/subfile.js:1:1:1:14 | <toplevel> | es2015 |
|
||||
| modulePackage/tst.js:1:1:1:75 | <toplevel> | es2015 |
|
||||
| require.js:1:1:7:1 | <toplevel> | node |
|
||||
| script.js:1:1:1:35 | <toplevel> | non-module |
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
| g.js:1:43:1:61 | require("electron") |
|
||||
| index.js:1:12:1:26 | require('path') |
|
||||
| index.js:2:1:2:41 | require ... b.js")) |
|
||||
| mjs-files/createRequire.mjs:4:26:4:49 | require ... erver') |
|
||||
| mjs-files/require-from-js.js:1:12:1:36 | require ... on-me') |
|
||||
| mjs-files/require-from-js.js:2:12:2:39 | require ... me.js') |
|
||||
| mjs-files/require-from-js.js:3:12:3:40 | require ... e.mjs') |
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
import { createRequire } from 'module';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
const { ApolloServer } = require('apollo-server');
|
||||
@@ -0,0 +1,17 @@
|
||||
import semmle.javascript.frameworks.React
|
||||
|
||||
query predicate test_JSXname(JSXElement element, JSXName jsxname, string name, string type) {
|
||||
name = jsxname.getValue() and
|
||||
(
|
||||
jsxname instanceof Identifier and type = "Identifier"
|
||||
or
|
||||
jsxname instanceof ThisExpr and type = "thisExpr"
|
||||
or
|
||||
jsxname.(DotExpr).getBase() instanceof JSXName and type = "dot"
|
||||
or
|
||||
jsxname instanceof JSXQualifiedName and type = "qualifiedName"
|
||||
) and
|
||||
element.getNameExpr() = jsxname
|
||||
}
|
||||
|
||||
query ThisExpr test_JSXName_this(JSXElement element) { result.getParentExpr+() = element }
|
||||
@@ -35,6 +35,7 @@ test_ReactComponent_getInstanceMethod
|
||||
| thisAccesses.js:18:19:29:1 | {\\n r ... }\\n} | someInstanceMethod | thisAccesses.js:26:25:28:5 | functio ... ;\\n } |
|
||||
| thisAccesses.js:31:2:36:1 | functio ... iv/>;\\n} | render | thisAccesses.js:31:2:36:1 | functio ... iv/>;\\n} |
|
||||
| thisAccesses.js:38:19:45:1 | {\\n r ... },\\n} | render | thisAccesses.js:39:13:44:5 | functio ... ;\\n } |
|
||||
| thisAccesses.js:54:1:63:1 | class C ... }\\n} | render | thisAccesses.js:59:11:62:5 | () {\\n ... ;\\n } |
|
||||
| thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | render | thisAccesses_importedMappers.js:5:13:14:5 | functio ... ;\\n } |
|
||||
test_react
|
||||
| es5.js:1:13:1:17 | React |
|
||||
@@ -70,6 +71,7 @@ test_react
|
||||
| thisAccesses.js:38:1:38:5 | React |
|
||||
| thisAccesses.js:40:9:40:13 | React |
|
||||
| thisAccesses.js:47:18:47:22 | React |
|
||||
| thisAccesses.js:54:18:54:22 | React |
|
||||
| thisAccesses_importedMappers.js:1:8:1:12 | React |
|
||||
| thisAccesses_importedMappers.js:4:1:4:5 | React |
|
||||
| thisAccesses_importedMappers.js:6:9:6:13 | React |
|
||||
@@ -165,6 +167,10 @@ test_ReactComponent_ref
|
||||
| thisAccesses.js:47:1:52:1 | class C ... }\\n} | thisAccesses.js:48:17:48:16 | this |
|
||||
| thisAccesses.js:47:1:52:1 | class C ... }\\n} | thisAccesses.js:49:9:49:12 | this |
|
||||
| thisAccesses.js:47:1:52:1 | class C ... }\\n} | thisAccesses.js:50:9:50:12 | this |
|
||||
| thisAccesses.js:54:1:63:1 | class C ... }\\n} | thisAccesses.js:55:16:55:15 | this |
|
||||
| thisAccesses.js:54:1:63:1 | class C ... }\\n} | thisAccesses.js:59:11:59:10 | this |
|
||||
| thisAccesses.js:54:1:63:1 | class C ... }\\n} | thisAccesses.js:60:20:60:23 | this |
|
||||
| thisAccesses.js:54:1:63:1 | class C ... }\\n} | thisAccesses.js:61:20:61:23 | this |
|
||||
| thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} |
|
||||
| thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | thisAccesses_importedMappers.js:5:13:5:12 | this |
|
||||
| thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | thisAccesses_importedMappers.js:6:38:6:37 | this |
|
||||
@@ -248,6 +254,7 @@ test_ReactComponent
|
||||
| thisAccesses.js:31:2:36:1 | functio ... iv/>;\\n} |
|
||||
| thisAccesses.js:38:19:45:1 | {\\n r ... },\\n} |
|
||||
| thisAccesses.js:47:1:52:1 | class C ... }\\n} |
|
||||
| thisAccesses.js:54:1:63:1 | class C ... }\\n} |
|
||||
| thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} |
|
||||
test_ReactComponent_getAPropRead
|
||||
| es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} | name | es5.js:4:24:4:38 | this.props.name |
|
||||
@@ -258,3 +265,30 @@ test_ReactComponent_getAPropRead
|
||||
| preact.js:1:1:7:1 | class H ... }\\n} | name | preact.js:3:9:3:18 | props.name |
|
||||
| probably-a-component.js:1:1:6:1 | class H ... }\\n} | name | probably-a-component.js:3:9:3:23 | this.props.name |
|
||||
| statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | name | statePropertyWrites.js:38:24:38:38 | this.props.name |
|
||||
test_JSXname
|
||||
| es5.js:4:12:4:45 | <div>He ... }</div> | es5.js:4:13:4:15 | div | div | Identifier |
|
||||
| es5.js:20:12:20:44 | <h1>Hel ... e}</h1> | es5.js:20:13:20:14 | h1 | h1 | Identifier |
|
||||
| es6.js:3:12:3:45 | <div>He ... }</div> | es6.js:3:13:3:15 | div | div | Identifier |
|
||||
| exportedComponent.jsx:2:12:2:46 | <div st ... lor}}/> | exportedComponent.jsx:2:13:2:15 | div | div | Identifier |
|
||||
| importedComponent.jsx:4:12:4:39 | <MyComp ... olor}/> | importedComponent.jsx:4:13:4:23 | MyComponent | MyComponent | Identifier |
|
||||
| plainfn.js:2:10:2:38 | <div>He ... }</div> | plainfn.js:2:11:2:13 | div | div | Identifier |
|
||||
| preact.js:5:16:5:21 | <div/> | preact.js:5:17:5:19 | div | div | Identifier |
|
||||
| probably-a-component.js:4:16:4:21 | <div/> | probably-a-component.js:4:17:4:19 | div | div | Identifier |
|
||||
| props.js:7:6:7:37 | <C prop ... JSX"}/> | props.js:7:7:7:7 | C | C | Identifier |
|
||||
| props.js:19:6:19:37 | <C prop ... JSX"}/> | props.js:19:7:19:7 | C | C | Identifier |
|
||||
| props.js:27:16:27:21 | <div/> | props.js:27:17:27:19 | div | div | Identifier |
|
||||
| props.js:32:6:32:37 | <C prop ... JSX"}/> | props.js:32:7:32:7 | C | C | Identifier |
|
||||
| statePropertyWrites.js:38:12:38:45 | <div>He ... }</div> | statePropertyWrites.js:38:13:38:15 | div | div | Identifier |
|
||||
| thisAccesses.js:23:16:23:21 | <div/> | thisAccesses.js:23:17:23:19 | div | div | Identifier |
|
||||
| thisAccesses.js:35:12:35:17 | <div/> | thisAccesses.js:35:13:35:15 | div | div | Identifier |
|
||||
| thisAccesses.js:43:16:43:21 | <div/> | thisAccesses.js:43:17:43:19 | div | div | Identifier |
|
||||
| thisAccesses.js:60:19:60:41 | <this.n ... s.name> | thisAccesses.js:60:20:60:28 | this.name | this.name | dot |
|
||||
| thisAccesses.js:61:19:61:41 | <this.t ... s.this> | thisAccesses.js:61:20:61:28 | this.this | this.this | dot |
|
||||
| thisAccesses_importedMappers.js:13:16:13:21 | <div/> | thisAccesses_importedMappers.js:13:17:13:19 | div | div | Identifier |
|
||||
test_JSXName_this
|
||||
| es5.js:4:12:4:45 | <div>He ... }</div> | es5.js:4:24:4:27 | this |
|
||||
| es5.js:20:12:20:44 | <h1>Hel ... e}</h1> | es5.js:20:24:20:27 | this |
|
||||
| es6.js:3:12:3:45 | <div>He ... }</div> | es6.js:3:24:3:27 | this |
|
||||
| statePropertyWrites.js:38:12:38:45 | <div>He ... }</div> | statePropertyWrites.js:38:24:38:27 | this |
|
||||
| thisAccesses.js:60:19:60:41 | <this.n ... s.name> | thisAccesses.js:60:20:60:23 | this |
|
||||
| thisAccesses.js:61:19:61:41 | <this.t ... s.this> | thisAccesses.js:61:20:61:23 | this |
|
||||
|
||||
@@ -8,3 +8,4 @@ import ReactComponent_getADirectPropsSource
|
||||
import ReactComponent_getACandidatePropsValue
|
||||
import ReactComponent
|
||||
import ReactComponent_getAPropRead
|
||||
import ReactName
|
||||
|
||||
@@ -50,3 +50,14 @@ class C2 extends React.Component {
|
||||
this.state = y;
|
||||
}
|
||||
}
|
||||
|
||||
class C3 extends React.Component {
|
||||
constructor() {
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
var foo = <this.name></this.name>;
|
||||
var bar = <this.this></this.this>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
| test_cookie-session.js:18:9:28:2 | session ... }\\n}) | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_express-session.js:5:9:8:2 | session ... T OK\\n}) | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_express-session.js:10:9:13:2 | session ... T OK\\n}) | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_express-session.js:15:9:18:2 | session ... T OK\\n}) | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_express-session.js:25:9:25:21 | session(sess) | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_httpserver.js:7:37:7:73 | ["type= ... cript"] | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_jscookie.js:2:1:2:48 | js_cook ... alse }) | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_responseCookie.js:5:5:10:10 | res.coo ... }) | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_responseCookie.js:20:5:20:40 | res.coo ... ptions) | Cookie is added to response without the 'secure' flag being set to true |
|
||||
@@ -0,0 +1 @@
|
||||
experimental/Security/CWE-614/InsecureCookie.ql
|
||||
@@ -0,0 +1,28 @@
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
const session = require('cookie-session')
|
||||
const expiryDate = new Date(Date.now() + 60 * 60 * 1000)
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
cookie: {
|
||||
secure: true, // OK
|
||||
httpOnly: true,
|
||||
domain: 'example.com',
|
||||
path: 'foo/bar',
|
||||
expires: expiryDate
|
||||
}
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
cookie: {
|
||||
secure: false, // NOT OK
|
||||
httpOnly: true,
|
||||
domain: 'example.com',
|
||||
path: 'foo/bar',
|
||||
expires: expiryDate
|
||||
}
|
||||
}))
|
||||
@@ -0,0 +1,33 @@
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
const session = require('express-session')
|
||||
|
||||
app.use(session({
|
||||
secret: 'secret',
|
||||
cookie: { secure: false } // NOT OK
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
secret: 'secret'
|
||||
// NOT OK
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
secret: 'secret',
|
||||
cookie: {} // NOT OK
|
||||
}))
|
||||
|
||||
const sess = {
|
||||
secret: 'secret',
|
||||
cookie: { secure: false } // NOT OK
|
||||
}
|
||||
|
||||
app.use(session(sess))
|
||||
|
||||
|
||||
app.set('trust proxy', 1)
|
||||
app.use(session({
|
||||
secret: 'secret',
|
||||
cookie: { secure: true } // OK
|
||||
}))
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
const http = require('http');
|
||||
|
||||
function test1() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// NOT OK
|
||||
res.setHeader("Set-Cookie", ["type=ninja", "language=javascript"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function test2() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// OK
|
||||
res.setHeader("Set-Cookie", ["type=ninja; Secure", "language=javascript; secure"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
const js_cookie = require('js-cookie')
|
||||
js_cookie.set('key', 'value', { secure: false }); // NOT OK
|
||||
js_cookie.set('key', 'value', { secure: true }); // OK
|
||||
@@ -0,0 +1,33 @@
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
res.cookie('name', 'value',
|
||||
{
|
||||
maxAge: 9000000000,
|
||||
httpOnly: true,
|
||||
secure: false // NOT OK
|
||||
});
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/b', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: true,
|
||||
secure: false // NOT OK
|
||||
}
|
||||
res.cookie('name', 'value', options);
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/c', function (req, res, next) {
|
||||
res.cookie('name', 'value',
|
||||
{
|
||||
maxAge: 9000000000,
|
||||
httpOnly: true,
|
||||
secure: true // OK
|
||||
});
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user