mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
JavaScript: Add new query PostMessageStar.
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
| **Query** | **Tags** | **Purpose** |
|
| **Query** | **Tags** | **Purpose** |
|
||||||
|-----------------------------------------------|------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|-----------------------------------------------|------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| Cross-window communication with unrestricted target origin (`js/cross-window-information-leak`) | security, external/cwe/359 | Highlights code that sends potentially sensitive information to another window without restricting the receiver window's origin. Results are shown on LGTM by default. |
|
||||||
| Double escaping or unescaping (`js/double-escaping`) | correctness, security, external/cwe/cwe-116 | Highlights potential double escaping or unescaping of special characters, indicating a possible violation of [CWE-116](https://cwe.mitre.org/data/definitions/116.html). Results are shown on LGTM by default. |
|
| Double escaping or unescaping (`js/double-escaping`) | correctness, security, external/cwe/cwe-116 | Highlights potential double escaping or unescaping of special characters, indicating a possible violation of [CWE-116](https://cwe.mitre.org/data/definitions/116.html). Results are shown on LGTM by default. |
|
||||||
| Incomplete regular expression for hostnames (`js/incomplete-hostname-regexp`) | correctness, security, external/cwe/cwe-020 | Highlights hostname sanitizers that are likely to be incomplete, indicating a violation of [CWE-020](https://cwe.mitre.org/data/definitions/20.html). Results are shown on LGTM by default.|
|
| Incomplete regular expression for hostnames (`js/incomplete-hostname-regexp`) | correctness, security, external/cwe/cwe-020 | Highlights hostname sanitizers that are likely to be incomplete, indicating a violation of [CWE-020](https://cwe.mitre.org/data/definitions/20.html). Results are shown on LGTM by default.|
|
||||||
| Incomplete URL substring sanitization | correctness, security, external/cwe/cwe-020 | Highlights URL sanitizers that are likely to be incomplete, indicating a violation of [CWE-020](https://cwe.mitre.org/data/definitions/20.html). Results shown on LGTM by default. |
|
| Incomplete URL substring sanitization | correctness, security, external/cwe/cwe-020 | Highlights URL sanitizers that are likely to be incomplete, indicating a violation of [CWE-020](https://cwe.mitre.org/data/definitions/20.html). Results shown on LGTM by default. |
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
+ semmlecode-javascript-queries/Security/CWE-338/InsecureRandomness.ql: /Security/CWE/CWE-338
|
+ semmlecode-javascript-queries/Security/CWE-338/InsecureRandomness.ql: /Security/CWE/CWE-338
|
||||||
+ semmlecode-javascript-queries/Security/CWE-346/CorsMisconfigurationForCredentials.ql: /Security/CWE/CWE-346
|
+ semmlecode-javascript-queries/Security/CWE-346/CorsMisconfigurationForCredentials.ql: /Security/CWE/CWE-346
|
||||||
+ semmlecode-javascript-queries/Security/CWE-352/MissingCsrfMiddleware.ql: /Security/CWE/CWE-352
|
+ semmlecode-javascript-queries/Security/CWE-352/MissingCsrfMiddleware.ql: /Security/CWE/CWE-352
|
||||||
|
+ semmlecode-javascript-queries/Security/CWE-359/PostMessageStar.ql: /Security/CWE/CWE-359
|
||||||
+ semmlecode-javascript-queries/Security/CWE-400/RemotePropertyInjection.ql: /Security/CWE/CWE-400
|
+ semmlecode-javascript-queries/Security/CWE-400/RemotePropertyInjection.ql: /Security/CWE/CWE-400
|
||||||
+ semmlecode-javascript-queries/Security/CWE-502/UnsafeDeserialization.ql: /Security/CWE/CWE-502
|
+ semmlecode-javascript-queries/Security/CWE-502/UnsafeDeserialization.ql: /Security/CWE/CWE-502
|
||||||
+ semmlecode-javascript-queries/Security/CWE-506/HardcodedDataInterpretedAsCode.ql: /Security/CWE/CWE-506
|
+ semmlecode-javascript-queries/Security/CWE-506/HardcodedDataInterpretedAsCode.ql: /Security/CWE/CWE-506
|
||||||
|
|||||||
56
javascript/ql/src/Security/CWE-359/PostMessageStar.qhelp
Normal file
56
javascript/ql/src/Security/CWE-359/PostMessageStar.qhelp
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<!DOCTYPE qhelp PUBLIC
|
||||||
|
"-//Semmle//qhelp//EN"
|
||||||
|
"qhelp.dtd">
|
||||||
|
<qhelp>
|
||||||
|
|
||||||
|
<overview>
|
||||||
|
<p>
|
||||||
|
The <code>window.postMessage</code> method allows different windows or iframes
|
||||||
|
to communicate directly, even if they were loaded from different origins, circumventing
|
||||||
|
the usual same-origin policy.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The sender of the message can restrict the origin of the receiver by specifying
|
||||||
|
a target origin. If the receiver window does not come from this origin, the
|
||||||
|
message is not sent.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Alternatively, the sender can specify a target origin of <code>'*'</code>, which means
|
||||||
|
that any origin is acceptable and the message is always sent.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This feature should not be used if the message being sent contains sensitive data such
|
||||||
|
as user credentials: the target window may have been loaded from a malicious site,
|
||||||
|
to which the data would then become available.
|
||||||
|
</p>
|
||||||
|
</overview>
|
||||||
|
|
||||||
|
<recommendation>
|
||||||
|
<p>
|
||||||
|
If possible, specify a target origin when using <code>window.postMessage</code>.
|
||||||
|
Alternatively, encrypt the sensitive data before sending it to prevent an unauthorized
|
||||||
|
receiver from accessing it.
|
||||||
|
</p>
|
||||||
|
</recommendation>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
<p>
|
||||||
|
The following example code sends user credentials (in this case, their user
|
||||||
|
name) to <code>window.parent</code> without checking its origin. If a malicious site
|
||||||
|
loads the page containing this code into an iframe it would be able to gain access
|
||||||
|
to the user name.
|
||||||
|
</p>
|
||||||
|
<sample src="examples/PostMessageStar.js"/>
|
||||||
|
<p>
|
||||||
|
To prevent this from happening, the origin of the target window should be restricted,
|
||||||
|
as in this example:
|
||||||
|
</p>
|
||||||
|
<sample src="examples/PostMessageStarGood.js"/>
|
||||||
|
</example>
|
||||||
|
|
||||||
|
|
||||||
|
<references>
|
||||||
|
<li>Mozilla Developer Network: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage">Window.postMessage</a>.</li>
|
||||||
|
<li>Mozilla Developer Network: <a href="https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy">Same-origin policy</a>.</li>
|
||||||
|
</references>
|
||||||
|
</qhelp>
|
||||||
22
javascript/ql/src/Security/CWE-359/PostMessageStar.ql
Normal file
22
javascript/ql/src/Security/CWE-359/PostMessageStar.ql
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* @name Cross-window communication with unrestricted target origin
|
||||||
|
* @description When sending sensitive information to another window using `postMessage`,
|
||||||
|
* the origin of the target window should be restricted to avoid unintentional
|
||||||
|
* information leaks.
|
||||||
|
* @kind path-problem
|
||||||
|
* @problem.severity error
|
||||||
|
* @precision high
|
||||||
|
* @id js/cross-window-information-leak
|
||||||
|
* @tags security
|
||||||
|
* external/cwe/cwe-359
|
||||||
|
*/
|
||||||
|
|
||||||
|
import javascript
|
||||||
|
import semmle.javascript.security.dataflow.PostMessageStar::PostMessageStar
|
||||||
|
import DataFlow::PathGraph
|
||||||
|
|
||||||
|
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||||
|
where cfg.hasFlowPath(source, sink)
|
||||||
|
select sink.getNode(), source, sink,
|
||||||
|
"Sensitive data returned from $@ is sent to another window without origin restriction.",
|
||||||
|
source.getNode(), "here"
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
window.parent.postMessage(userName, '*');
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
window.parent.postMessage(userName, 'https://lgtm.com');
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* Provides a taint tracking configuration for reasoning about cross-window communication
|
||||||
|
* with unrestricted origin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import javascript
|
||||||
|
private import semmle.javascript.security.SensitiveActions
|
||||||
|
|
||||||
|
module PostMessageStar {
|
||||||
|
/**
|
||||||
|
* A data flow source for cross-window communication with unrestricted origin.
|
||||||
|
*/
|
||||||
|
abstract class Source extends DataFlow::Node { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A data flow sink for cross-window communication with unrestricted origin.
|
||||||
|
*/
|
||||||
|
abstract class Sink extends DataFlow::Node { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A sanitizer for cross-window communication with unrestricted origin.
|
||||||
|
*/
|
||||||
|
abstract class Sanitizer extends DataFlow::Node { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A taint tracking configuration for cross-window communication with unrestricted origin.
|
||||||
|
*
|
||||||
|
* This configuration identifies flows from `Source`s, which are sources of
|
||||||
|
* sensitive data, to `Sink`s, which is an abstract class representing all
|
||||||
|
* the places sensitive data may be transmitted across window boundaries without restricting
|
||||||
|
* the origin.
|
||||||
|
*
|
||||||
|
* Additional sources or sinks can be added either by extending the relevant class, or by subclassing
|
||||||
|
* this configuration itself, and amending the sources and sinks.
|
||||||
|
*/
|
||||||
|
class Configuration extends TaintTracking::Configuration {
|
||||||
|
Configuration() { this = "PostMessageStar" }
|
||||||
|
|
||||||
|
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||||
|
|
||||||
|
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||||
|
|
||||||
|
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A sensitive expression, viewed as a data flow source for cross-window communication
|
||||||
|
* with unrestricted origin.
|
||||||
|
*/
|
||||||
|
class SensitiveExprSource extends Source, DataFlow::ValueNode { override SensitiveExpr astNode; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A variable/property access or function call whose name suggests that it may contain credentials,
|
||||||
|
* viewed as a data flow source for cross-window communication with unrestricted origin.
|
||||||
|
*/
|
||||||
|
class CredentialsSource extends Source {
|
||||||
|
CredentialsSource() {
|
||||||
|
exists(string name |
|
||||||
|
name = this.(DataFlow::InvokeNode).getCalleeName() or
|
||||||
|
name = this.(DataFlow::PropRead).getPropertyName() or
|
||||||
|
name = this.asExpr().(VarUse).getVariable().getName()
|
||||||
|
|
|
||||||
|
name.regexpMatch(HeuristicNames::suspiciousCredentials()) and
|
||||||
|
not name.regexpMatch(HeuristicNames::nonSuspicious())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A call to any function whose name suggests that it encodes or encrypts its arguments. */
|
||||||
|
class ProtectSanitizer extends Sanitizer { ProtectSanitizer() { this instanceof ProtectCall } }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An expression sent using `postMessage` without restricting the target window origin.
|
||||||
|
*/
|
||||||
|
class PostMessageStarSink extends Sink {
|
||||||
|
PostMessageStarSink() {
|
||||||
|
exists(DataFlow::MethodCallNode postMessage |
|
||||||
|
postMessage.getMethodName() = "postMessage" and
|
||||||
|
postMessage.getArgument(1).mayHaveStringValue("*") and
|
||||||
|
this = postMessage.getArgument(0)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
nodes
|
||||||
|
| PostMessageStar2.js:1:27:1:34 | password |
|
||||||
|
| PostMessageStar.js:1:27:1:34 | userName |
|
||||||
|
edges
|
||||||
|
#select
|
||||||
|
| PostMessageStar2.js:1:27:1:34 | password | PostMessageStar2.js:1:27:1:34 | password | PostMessageStar2.js:1:27:1:34 | password | Sensitive data returned from $@ is sent to another window without origin restriction. | PostMessageStar2.js:1:27:1:34 | password | here |
|
||||||
|
| PostMessageStar.js:1:27:1:34 | userName | PostMessageStar.js:1:27:1:34 | userName | PostMessageStar.js:1:27:1:34 | userName | Sensitive data returned from $@ is sent to another window without origin restriction. | PostMessageStar.js:1:27:1:34 | userName | here |
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
window.parent.postMessage(userName, '*');
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Security/CWE-359/PostMessageStar.ql
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
window.parent.postMessage(password, '*');
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
window.parent.postMessage(userName, 'https://lgtm.com');
|
||||||
Reference in New Issue
Block a user