Merge rc/1.19 into next.

This commit is contained in:
Aditya Sharad
2018-11-27 12:04:46 +00:00
32 changed files with 532 additions and 30 deletions

View File

@@ -6,8 +6,8 @@
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
| Cast between `HRESULT` and a Boolean type (`cpp/hresult-boolean-conversion`) | external/cwe/cwe-253 | Finds logic errors caused by mistakenly treating the Windows `HRESULT` type as a Boolean instead of testing it with the appropriate macros. Enabled by default. |
| Setting a DACL to `NULL` in a `SECURITY_DESCRIPTOR` (`cpp/unsafe-dacl-security-descriptor`) | external/cwe/cwe-732 | This query finds code that creates world-writable objects on Windows by setting their DACL to `NULL`. Enabled by default. |
| Cast between `HRESULT` and a Boolean type (`cpp/hresult-boolean-conversion`) | security, external/cwe/cwe-253 | Finds logic errors caused by mistakenly treating the Windows `HRESULT` type as a Boolean instead of testing it with the appropriate macros. Enabled by default. |
| Setting a DACL to `NULL` in a `SECURITY_DESCRIPTOR` (`cpp/unsafe-dacl-security-descriptor`) | security, external/cwe/cwe-732 | This query finds code that creates world-writable objects on Windows by setting their DACL to `NULL`. Enabled by default. |
| Cast from `char*` to `wchar_t*` | security, external/cwe/cwe-704 | Detects potentially dangerous casts from `char*` to `wchar_t*`. Enabled by default on LGTM. |
| Dead code due to `goto` or `break` statement (`cpp/dead-code-goto`) | maintainability, external/cwe/cwe-561 | Detects dead code following a `goto` or `break` statement. Enabled by default on LGTM. |
| Inconsistent direction of for loop | correctness, external/cwe/cwe-835 | This query detects `for` loops where the increment and guard condition don't appear to correspond. Enabled by default on LGTM. |

View File

@@ -11,7 +11,7 @@
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
| Using a package with a known vulnerability (cs/use-of-vulnerable-package) | security, external/cwe/cwe-937 | Finds project build files that import packages with known vulnerabilities. This is included by default. |
| Uncontrolled format string (cs/uncontrolled-format-string) | security, external/cwe/cwe-134 | Finds data flow from remote inputs to the format string in `String.Format`. This is included by default. |
## Changes to existing queries

View File

@@ -24,6 +24,7 @@
| Enabling Node.js integration for Electron web content renderers (`js/enabling-electron-renderer-node-integration`) | security, frameworks/electron, external/cwe/cwe-094 | Highlights Electron web content renderer preferences with Node.js integration enabled, indicating a violation of [CWE-94](https://cwe.mitre.org/data/definitions/94.html). Results are not shown on LGTM by default. |
| File data in outbound network request | security, external/cwe/cwe-200 | Highlights locations where file data is sent in a network request. Results are not shown on LGTM by default. |
| Host header poisoning in email generation | security, external/cwe/cwe-640 | Highlights code that generates emails with links that can be hijacked by HTTP host header poisoning, indicating a violation of [CWE-640](https://cwe.mitre.org/data/definitions/640.html). Results shown on LGTM by default. |
| Unsafe dynamic method access (`js/unsafe-dynamic-method-access` ) | security, external/cwe/cwe-094 | Highlights code that invokes a user-controlled method on an object with unsafe methods. Results are shown on LGTM by default. |
| Replacement of a substring with itself (`js/identity-replacement`) | correctness, security, external/cwe/cwe-116 | Highlights string replacements that replace a string with itself, which usually indicates a mistake. Results shown on LGTM by default. |
| Stored cross-site scripting (`js/stored-xss`) | security, external/cwe/cwe-079, external/cwe/cwe-116 | Highlights uncontrolled stored values flowing into HTML content, indicating a violation of [CWE-079](https://cwe.mitre.org/data/definitions/79.html). Results shown on LGTM by default. |
| Unclear precedence of nested operators (`js/unclear-operator-precedence`) | maintainability, correctness, external/cwe/cwe-783 | Highlights nested binary operators whose relative precedence is easy to misunderstand. Results shown on LGTM by default. |

View File

@@ -33,14 +33,7 @@ abstract class SystemData extends Element {
result = getAnExpr() or
// flow via global or member variable (conservative approximation)
exists(Variable var |
(
var.getAnAssignedValue() = getAnExprIndirect() or
var.getAnAccess() = getAnExprIndirect()
) and
result = var.getAnAccess() and
not var instanceof LocalScopeVariable
) or
result = getAnAffectedVar().getAnAccess() or
// flow via stack variable
definitionUsePair(_, getAnExprIndirect(), result) or
@@ -50,6 +43,17 @@ abstract class SystemData extends Element {
// flow from assigned value to assignment expression
result.(AssignExpr).getRValue() = getAnExprIndirect()
}
/** Gets a global or member variable that may be affected by this system
* data (conservative approximation).
*/
private Variable getAnAffectedVar() {
(
result.getAnAssignedValue() = this.getAnExprIndirect() or
result.getAnAccess() = this.getAnExprIndirect()
) and
not result instanceof LocalScopeVariable
}
}
/**

View File

@@ -0,0 +1,44 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Passing untrusted format strings to <code>String.Format</code> can throw exceptions
and cause a denial of service. For example, if the format string references a missing argument,
or an argument of the wrong type, then <code>System.FormatException</code> is thrown.
</p>
</overview>
<recommendation>
<p>Use a string literal for the format string to prevent the possibility of data flow from
an untrusted source. This also helps to prevent errors where the arguments to
<code>String.Format</code> do not match the format string.</p>
<p>If the format string cannot be constant, ensure that it comes from a secure
data source or is compiled into the source code.</p>
</recommendation>
<example>
<p>In this example, the format string is read from an HTTP request, which could cause
the application to crash.</p>
<sample src="UncontrolledFormatStringBad.cs" />
</example>
<references>
<li>
OWASP:
<a href="https://www.owasp.org/index.php/Format_string_attack">Format string attack</a>.
</li>
<li>
Microsoft docs:
<a href="https://docs.microsoft.com/en-us/dotnet/api/system.string.format">String.Format Method</a>
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,34 @@
/**
* @name Uncontrolled format string
* @description Passing untrusted format strings from remote data sources can throw exceptions
* and cause a denial of service.
* @kind path-problem
* @problem.severity error
* @precision high
* @id cs/uncontrolled-format-string
* @tags security
* external/cwe/cwe-134
*/
import csharp
import semmle.code.csharp.dataflow.flowsources.Remote
import semmle.code.csharp.dataflow.TaintTracking
import semmle.code.csharp.frameworks.Format
import DataFlow::PathGraph
class FormatStringConfiguration extends TaintTracking::Configuration {
FormatStringConfiguration() { this = "FormatStringConfiguration" }
override predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource
}
override predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(FormatCall call).getFormatExpr()
}
}
from FormatStringConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink,
"$@ flows to here and is used as a format string.", source.getNode(), source.getNode().toString()

View File

@@ -0,0 +1,14 @@
using System.Web;
public class HttpHandler : IHttpHandler
{
string Surname, Forenames, FormattedName;
public void ProcessRequest(HttpContext ctx)
{
string format = ctx.Request.QueryString["nameformat"];
// BAD: Uncontrolled format string.
FormattedName = string.Format(format, Surname, Forenames);
}
}

View File

@@ -0,0 +1,25 @@
// semmle-extractor-options: /r:System.Runtime.Extensions.dll /r:System.Collections.Specialized.dll ${testdir}/../../../resources/stubs/System.Web.cs
using System;
using System.IO;
using System.Web;
public class TaintedPathHandler : IHttpHandler
{
public void ProcessRequest(HttpContext ctx)
{
String path = ctx.Request.QueryString["page"];
// BAD: Uncontrolled format string.
String.Format(path, "Do not do this");
// BAD: Using an IFormatProvider.
String.Format((IFormatProvider)null, path, "Do not do this");
// GOOD: Not the format string.
String.Format("Do not do this", path);
// GOOD: Not the format string.
String.Format((IFormatProvider)null, "Do not do this", path);
}
}

View File

@@ -0,0 +1,16 @@
edges
| UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString | UncontrolledFormatString.cs:14:23:14:26 | access to local variable path |
| UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString | UncontrolledFormatString.cs:17:46:17:49 | access to local variable path |
| UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString | UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format |
nodes
| UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString |
| UncontrolledFormatString.cs:14:23:14:26 | access to local variable path |
| UncontrolledFormatString.cs:17:46:17:49 | access to local variable path |
| UncontrolledFormatString.cs:20:23:20:38 | "Do not do this" |
| UncontrolledFormatString.cs:23:46:23:61 | "Do not do this" |
| UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString |
| UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format |
#select
| UncontrolledFormatString.cs:14:23:14:26 | access to local variable path | UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString | UncontrolledFormatString.cs:14:23:14:26 | access to local variable path | $@ flows to here and is used as a format string. | UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString | access to property QueryString |
| UncontrolledFormatString.cs:17:46:17:49 | access to local variable path | UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString | UncontrolledFormatString.cs:17:46:17:49 | access to local variable path | $@ flows to here and is used as a format string. | UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString | access to property QueryString |
| UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format | UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString | UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format | $@ flows to here and is used as a format string. | UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString | access to property QueryString |

View File

@@ -0,0 +1 @@
Security Features/CWE-134/UncontrolledFormatString.ql

View File

@@ -0,0 +1,14 @@
using System.Web;
public class HttpHandler : IHttpHandler
{
string Surname, Forenames, FormattedName;
public void ProcessRequest(HttpContext ctx)
{
string format = ctx.Request.QueryString["nameformat"];
// BAD: Uncontrolled format string.
FormattedName = string.Format(format, Surname, Forenames);
}
}

View File

@@ -7,6 +7,7 @@
+ semmlecode-javascript-queries/Security/CWE-079/Xss.ql: /Security/CWE/CWE-079
+ semmlecode-javascript-queries/Security/CWE-089/SqlInjection.ql: /Security/CWE/CWE-089
+ semmlecode-javascript-queries/Security/CWE-094/CodeInjection.ql: /Security/CWE/CWE-094
+ semmlecode-javascript-queries/Security/CWE-094/UnsafeDynamicMethodAccess.ql: /Security/CWE/CWE-094
+ semmlecode-javascript-queries/Security/CWE-116/IncompleteSanitization.ql: /Security/CWE/CWE-116
+ semmlecode-javascript-queries/Security/CWE-134/TaintedFormatString.ql: /Security/CWE/CWE-134
+ semmlecode-javascript-queries/Security/CWE-209/StackTraceExposure.ql: /Security/CWE/CWE-209

View File

@@ -0,0 +1,53 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Calling a user-controlled method on certain objects can lead to invocation of unsafe functions,
such as <code>eval</code> or the <code>Function</code> constructor. In particular, the global object
contains the <code>eval</code> function, and any function object contains the <code>Function</code> constructor
in its <code>constructor</code> property.
</p>
</overview>
<recommendation>
<p>
Avoid invoking user-controlled methods on the global object or on any function object.
Whitelist the permitted method names or change the type of object the methods are stored on.
</p>
</recommendation>
<example>
<p>
In the following example, a message from the document's parent frame can invoke the <code>play</code>
or <code>pause</code> method. However, it can also invoke <code>eval</code>.
A malicious website could embed the page in an iframe and execute arbitrary code by sending a message
with the name <code>eval</code>.
</p>
<sample src="examples/UnsafeDynamicMethodAccess.js" />
<p>
Instead of storing the API methods in the global scope, put them in an API object or Map. It is also good
practice to prevent invocation of inherited methods like <code>toString</code> and <code>valueOf</code>.
</p>
<sample src="examples/UnsafeDynamicMethodAccessGood.js" />
</example>
<references>
<li>
OWASP:
<a href="https://www.owasp.org/index.php/Code_Injection">Code Injection</a>.
</li>
<li>
MDN: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects#Function_properties">Global functions</a>.
</li>
<li>
MDN: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function">Function constructor</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,17 @@
/**
* @name Unsafe dynamic method access
* @description Invoking user-controlled methods on certain objects can lead to remote code execution.
* @kind path-problem
* @problem.severity error
* @precision high
* @id js/unsafe-dynamic-method-access
* @tags security
* external/cwe/cwe-094
*/
import javascript
import semmle.javascript.security.dataflow.UnsafeDynamicMethodAccess::UnsafeDynamicMethodAccess
import DataFlow::PathGraph
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink, source, sink, "Invocation of method derived from $@ may lead to remote code execution.", source.getNode(), "user-controlled value"

View File

@@ -0,0 +1,14 @@
// API methods
function play(data) {
// ...
}
function pause(data) {
// ...
}
window.addEventListener("message", (ev) => {
let message = JSON.parse(ev.data);
// Let the parent frame call the 'play' or 'pause' function
window[message.name](message.payload);
});

View File

@@ -0,0 +1,19 @@
// API methods
let api = {
play: function(data) {
// ...
},
pause: function(data) {
// ...
}
};
window.addEventListener("message", (ev) => {
let message = JSON.parse(ev.data);
// Let the parent frame call the 'play' or 'pause' function
if (!api.hasOwnProperty(message.name)) {
return;
}
api[message.name](message.payload);
});

View File

@@ -0,0 +1,39 @@
/**
* Provides predicates for reasoning about flow of user-controlled values that are used
* as property names.
*/
import javascript
module PropertyInjection {
/**
* A data-flow node that sanitizes user-controlled property names that flow through it.
*/
abstract class Sanitizer extends DataFlow::Node {
}
/**
* Concatenation with a constant, acting as a sanitizer.
*/
private class ConcatSanitizer extends Sanitizer {
ConcatSanitizer() {
StringConcatenation::getAnOperand(this).asExpr() instanceof ConstantString
}
}
/**
* Holds if the methods of the given value are unsafe, such as `eval`.
*/
predicate hasUnsafeMethods(DataFlow::SourceNode node) {
// eval and friends can be accessed from the global object.
node = DataFlow::globalObjectRef()
or
// document.write can be accessed
isDocument(node.asExpr())
or
// 'constructor' property leads to the Function constructor.
node.analyze().getAValue() instanceof AbstractCallable
or
// Assume that a value that is invoked can refer to a function.
exists (node.getAnInvocation())
}
}

View File

@@ -6,6 +6,7 @@
import javascript
import semmle.javascript.frameworks.Express
import PropertyInjectionShared
module RemotePropertyInjection {
/**
@@ -45,7 +46,8 @@ module RemotePropertyInjection {
override predicate isSanitizer(DataFlow::Node node) {
super.isSanitizer(node) or
node instanceof Sanitizer
node instanceof Sanitizer or
node instanceof PropertyInjection::Sanitizer
}
}
@@ -76,9 +78,12 @@ module RemotePropertyInjection {
*/
class MethodCallSink extends Sink, DataFlow::ValueNode {
MethodCallSink() {
exists (DataFlow::PropRead pr | astNode = pr.getPropertyNameExpr() |
exists (pr.getAnInvocation())
)
exists (DataFlow::PropRead pr | astNode = pr.getPropertyNameExpr() |
exists (pr.getAnInvocation()) and
// Omit sinks covered by the UnsafeDynamicMethodAccess query
not PropertyInjection::hasUnsafeMethods(pr.getBase().getALocalSource())
)
}
override string getMessage() {
@@ -105,18 +110,4 @@ module RemotePropertyInjection {
result = " a header name."
}
}
/**
* A binary expression that sanitzes a value for remote property injection. That
* is, if a string is prepended or appended to the remote input, an attacker
* cannot access arbitrary properties.
*/
class ConcatSanitizer extends Sanitizer, DataFlow::ValueNode {
override BinaryExpr astNode;
ConcatSanitizer() {
astNode.getAnOperand() instanceof ConstantString
}
}
}

View File

@@ -0,0 +1,129 @@
/**
* Provides a taint-tracking configuration for reasoning about method invocations
* with a user-controlled method name on objects with unsafe methods.
*/
import javascript
import semmle.javascript.frameworks.Express
import PropertyInjectionShared
module UnsafeDynamicMethodAccess {
private import DataFlow::FlowLabel
/**
* A data flow source for unsafe dynamic method access.
*/
abstract class Source extends DataFlow::Node {
/**
* Gets the flow label relevant for this source.
*/
DataFlow::FlowLabel getFlowLabel() {
result = data()
}
}
/**
* A data flow sink for unsafe dynamic method access.
*/
abstract class Sink extends DataFlow::Node {
/**
* Gets the flow label relevant for this sink
*/
abstract DataFlow::FlowLabel getFlowLabel();
}
/**
* A sanitizer for unsafe dynamic method access.
*/
abstract class Sanitizer extends DataFlow::Node { }
/**
* Gets the flow label describing values that may refer to an unsafe
* function as a result of an attacker-controlled property name.
*/
UnsafeFunction unsafeFunction() { any() }
private class UnsafeFunction extends DataFlow::FlowLabel {
UnsafeFunction() { this = "UnsafeFunction" }
}
/**
* A taint-tracking configuration for reasoning about unsafe dynamic method access.
*/
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "UnsafeDynamicMethodAccess" }
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
source.(Source).getFlowLabel() = label
}
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
sink.(Sink).getFlowLabel() = label
}
override predicate isSanitizer(DataFlow::Node node) {
super.isSanitizer(node) or
node instanceof Sanitizer or
node instanceof PropertyInjection::Sanitizer
}
/**
* Holds if a property of the given object is an unsafe function.
*/
predicate hasUnsafeMethods(DataFlow::SourceNode node) {
PropertyInjection::hasUnsafeMethods(node) // Redefined here so custom queries can override it
}
/**
* Holds if the `node` is of form `Object.create(null)` and so it has no prototype.
*/
predicate isPrototypeLessObject(DataFlow::MethodCallNode node) {
node = DataFlow::globalVarRef("Object").getAMethodCall("create") and
node.getArgument(0).asExpr() instanceof NullLiteral
}
override predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node dst, DataFlow::FlowLabel srclabel, DataFlow::FlowLabel dstlabel) {
// Reading a property of the global object or of a function
exists (DataFlow::PropRead read |
hasUnsafeMethods(read.getBase().getALocalSource()) and
src = read.getPropertyNameExpr().flow() and
dst = read and
(srclabel = data() or srclabel = taint()) and
dstlabel = unsafeFunction())
or
// Reading a chain of properties from any object with a prototype can lead to Function
exists (PropertyProjection proj |
not isPrototypeLessObject(proj.getObject().getALocalSource()) and
src = proj.getASelector() and
dst = proj and
(srclabel = data() or srclabel = taint()) and
dstlabel = unsafeFunction())
}
}
/**
* A source of remote user input, considered as a source for unsafe dynamic method access.
*/
class RemoteFlowSourceAsSource extends Source {
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
}
/**
* The page URL considered as a flow source for unsafe dynamic method access.
*/
class DocumentUrlAsSource extends Source {
DocumentUrlAsSource() { isDocumentURL(asExpr()) }
}
/**
* A function invocation of an unsafe function, as a sink for remote unsafe dynamic method access.
*/
class CalleeAsSink extends Sink {
CalleeAsSink() {
this = any(DataFlow::InvokeNode node).getCalleeNode()
}
override DataFlow::FlowLabel getFlowLabel() {
result = unsafeFunction()
}
}
}

View File

@@ -0,0 +1,54 @@
nodes
| example.js:9:37:9:38 | ev |
| example.js:10:9:10:37 | message |
| example.js:10:19:10:37 | JSON.parse(ev.data) |
| example.js:10:30:10:31 | ev |
| example.js:10:30:10:36 | ev.data |
| example.js:13:5:13:24 | window[message.name] |
| example.js:13:12:13:18 | message |
| example.js:13:12:13:23 | message.name |
| tst.js:3:37:3:38 | ev |
| tst.js:4:9:4:37 | message |
| tst.js:4:19:4:37 | JSON.parse(ev.data) |
| tst.js:4:30:4:31 | ev |
| tst.js:4:30:4:36 | ev.data |
| tst.js:5:5:5:24 | window[message.name] |
| tst.js:5:12:5:18 | message |
| tst.js:5:12:5:23 | message.name |
| tst.js:6:9:6:28 | window[message.name] |
| tst.js:6:16:6:22 | message |
| tst.js:6:16:6:27 | message.name |
| tst.js:11:5:11:19 | f[message.name] |
| tst.js:11:7:11:13 | message |
| tst.js:11:7:11:18 | message.name |
| tst.js:15:5:15:14 | window[ev] |
| tst.js:15:12:15:13 | ev |
edges
| example.js:9:37:9:38 | ev | example.js:10:30:10:31 | ev |
| example.js:10:9:10:37 | message | example.js:13:12:13:18 | message |
| example.js:10:19:10:37 | JSON.parse(ev.data) | example.js:10:9:10:37 | message |
| example.js:10:30:10:31 | ev | example.js:10:30:10:36 | ev.data |
| example.js:10:30:10:36 | ev.data | example.js:10:19:10:37 | JSON.parse(ev.data) |
| example.js:13:12:13:18 | message | example.js:13:12:13:23 | message.name |
| example.js:13:12:13:23 | message.name | example.js:13:5:13:24 | window[message.name] |
| tst.js:3:37:3:38 | ev | tst.js:4:30:4:31 | ev |
| tst.js:3:37:3:38 | ev | tst.js:15:12:15:13 | ev |
| tst.js:4:9:4:37 | message | tst.js:5:12:5:18 | message |
| tst.js:4:9:4:37 | message | tst.js:6:16:6:22 | message |
| tst.js:4:9:4:37 | message | tst.js:11:7:11:13 | message |
| tst.js:4:19:4:37 | JSON.parse(ev.data) | tst.js:4:9:4:37 | message |
| tst.js:4:30:4:31 | ev | tst.js:4:30:4:36 | ev.data |
| tst.js:4:30:4:36 | ev.data | tst.js:4:19:4:37 | JSON.parse(ev.data) |
| tst.js:5:12:5:18 | message | tst.js:5:12:5:23 | message.name |
| tst.js:5:12:5:23 | message.name | tst.js:5:5:5:24 | window[message.name] |
| tst.js:6:16:6:22 | message | tst.js:6:16:6:27 | message.name |
| tst.js:6:16:6:27 | message.name | tst.js:6:9:6:28 | window[message.name] |
| tst.js:11:7:11:13 | message | tst.js:11:7:11:18 | message.name |
| tst.js:11:7:11:18 | message.name | tst.js:11:5:11:19 | f[message.name] |
| tst.js:15:12:15:13 | ev | tst.js:15:5:15:14 | window[ev] |
#select
| example.js:13:5:13:24 | window[message.name] | example.js:9:37:9:38 | ev | example.js:13:5:13:24 | window[message.name] | Invocation of method derived from $@ may lead to remote code execution. | example.js:9:37:9:38 | ev | user-controlled value |
| tst.js:5:5:5:24 | window[message.name] | tst.js:3:37:3:38 | ev | tst.js:5:5:5:24 | window[message.name] | Invocation of method derived from $@ may lead to remote code execution. | tst.js:3:37:3:38 | ev | user-controlled value |
| tst.js:6:9:6:28 | window[message.name] | tst.js:3:37:3:38 | ev | tst.js:6:9:6:28 | window[message.name] | Invocation of method derived from $@ may lead to remote code execution. | tst.js:3:37:3:38 | ev | user-controlled value |
| tst.js:11:5:11:19 | f[message.name] | tst.js:3:37:3:38 | ev | tst.js:11:5:11:19 | f[message.name] | Invocation of method derived from $@ may lead to remote code execution. | tst.js:3:37:3:38 | ev | user-controlled value |
| tst.js:15:5:15:14 | window[ev] | tst.js:3:37:3:38 | ev | tst.js:15:5:15:14 | window[ev] | Invocation of method derived from $@ may lead to remote code execution. | tst.js:3:37:3:38 | ev | user-controlled value |

View File

@@ -0,0 +1 @@
Security/CWE-094/UnsafeDynamicMethodAccess.ql

View File

@@ -0,0 +1,14 @@
// API methods
function play(data) {
// ...
}
function pause(data) {
// ...
}
window.addEventListener("message", (ev) => {
let message = JSON.parse(ev.data);
// Let the parent frame call the 'play' or 'pause' function
window[message.name](message.payload); // NOT OK
});

View File

@@ -0,0 +1,16 @@
let obj = {};
window.addEventListener('message', (ev) => {
let message = JSON.parse(ev.data);
window[message.name](message.payload); // NOT OK - may invoke eval
new window[message.name](message.payload); // NOT OK - may invoke jQuery $ function or similar
window["HTMLElement" + message.name](message.payload); // OK - concatenation restricts choice of methods
window[`HTMLElement${message.name}`](message.payload); // OK - concatenation restricts choice of methods
function f() {}
f[message.name](message.payload)(); // NOT OK - may acccess Function constructor
obj[message.name](message.payload); // OK - may crash, but no code execution involved
window[ev](ev); // NOT OK
});

View File

@@ -14,7 +14,8 @@ app.get('/user/:id', function(req, res) {
Object.defineProperty(myObj, prop, {value: 24}); // NOT OK
var headers = {};
headers[prop] = 42; // NOT OK
res.set(headers);
res.set(headers);
myCoolLocalFct[req.query.x](); // OK - flagged by method name injection
});
function myCoolLocalFct(x) {