JS: add heuristic variants of queries that use RemoteFlowSource

This commit is contained in:
erik-krogh 2022-12-19 12:01:22 +01:00
Родитель 2f84b21c7f
Коммит 442749bb7f
Не найден ключ, соответствующий данной подписи
68 изменённых файлов: 1701 добавлений и 968 удалений

Просмотреть файл

@ -0,0 +1,57 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Using unsanitized untrusted data in an external API can cause a variety of security issues. This query reports
external APIs that use untrusted data. The results are not filtered so that you can audit all examples. The query provides data for security reviews of the application and you can also use it to identify external APIs that should be modeled as either taint steps, or sinks for specific problems.</p>
<p>An external API is defined as a method call to a method that is not defined in the source code, not overridden
in the source code, and is not modeled as a taint step in the default taint library. External APIs may be from the
third-party dependencies or from internal dependencies. The query reports uses of
untrusted data one of the arguments of external API call or in the return value from a callback passed to an external API.</p>
</overview>
<recommendation>
<p>For each result:</p>
<ul>
<li>If the result highlights a known sink, confirm that the result is reported by the relevant query, or
that the result is a false positive because this data is sanitized.</li>
<li>If the result highlights an unknown sink for a problem, then add modeling for the sink to the relevant query,
and confirm that the result is either found, or is safe due to appropriate sanitization.</li>
<li>If the result represents a call to an external API that transfers taint, add the appropriate modeling, and
re-run the query to determine what new results have appeared due to this additional modeling.</li>
</ul>
<p>Otherwise, the result is likely uninteresting. Custom versions of this query can extend the <code>SafeExternalAPIMethod</code>
class to exclude known safe external APIs from future analysis.</p>
</recommendation>
<example>
<p>In this first example, a query parameter is read from the <code>req</code> parameter and then ultimately used in a call to the
<code>res.send</code> external API:</p>
<sample src="ExternalAPISinkExample.js" />
<p>This is a reflected XSS sink. The XSS query should therefore be reviewed to confirm that this sink is appropriately modeled,
and if it is, to confirm that the query reports this particular result, or that the result is a false positive due to
some existing sanitization.</p>
<p>In this second example, again a query parameter is read from <code>req</code>.</p>
<sample src="ExternalAPITaintStepExample.js" />
<p>If the query reported the call to <code>path.join</code> on line 4, this would suggest that this external API is
not currently modeled as a taint step in the taint tracking library. The next step would be to model this as a taint step, then
re-run the query to determine what additional results might be found. In this example, it seems the result of the
<code>path.join</code> will be used as a file path, leading to a path traversal vulnerability.</p>
<p>Note that both examples are correctly handled by the standard taint tracking library and security queries.</p>
</example>
<references>
</references>
</qhelp>

Просмотреть файл

@ -1,57 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Using unsanitized untrusted data in an external API can cause a variety of security issues. This query reports
external APIs that use untrusted data. The results are not filtered so that you can audit all examples. The query provides data for security reviews of the application and you can also use it to identify external APIs that should be modeled as either taint steps, or sinks for specific problems.</p>
<p>An external API is defined as a method call to a method that is not defined in the source code, not overridden
in the source code, and is not modeled as a taint step in the default taint library. External APIs may be from the
third-party dependencies or from internal dependencies. The query reports uses of
untrusted data one of the arguments of external API call or in the return value from a callback passed to an external API.</p>
</overview>
<recommendation>
<p>For each result:</p>
<ul>
<li>If the result highlights a known sink, confirm that the result is reported by the relevant query, or
that the result is a false positive because this data is sanitized.</li>
<li>If the result highlights an unknown sink for a problem, then add modeling for the sink to the relevant query,
and confirm that the result is either found, or is safe due to appropriate sanitization.</li>
<li>If the result represents a call to an external API that transfers taint, add the appropriate modeling, and
re-run the query to determine what new results have appeared due to this additional modeling.</li>
</ul>
<p>Otherwise, the result is likely uninteresting. Custom versions of this query can extend the <code>SafeExternalAPIMethod</code>
class to exclude known safe external APIs from future analysis.</p>
</recommendation>
<example>
<p>In this first example, a query parameter is read from the <code>req</code> parameter and then ultimately used in a call to the
<code>res.send</code> external API:</p>
<sample src="ExternalAPISinkExample.js" />
<p>This is a reflected XSS sink. The XSS query should therefore be reviewed to confirm that this sink is appropriately modeled,
and if it is, to confirm that the query reports this particular result, or that the result is a false positive due to
some existing sanitization.</p>
<p>In this second example, again a query parameter is read from <code>req</code>.</p>
<sample src="ExternalAPITaintStepExample.js" />
<p>If the query reported the call to <code>path.join</code> on line 4, this would suggest that this external API is
not currently modeled as a taint step in the taint tracking library. The next step would be to model this as a taint step, then
re-run the query to determine what additional results might be found. In this example, it seems the result of the
<code>path.join</code> will be used as a file path, leading to a path traversal vulnerability.</p>
<p>Note that both examples are correctly handled by the standard taint tracking library and security queries.</p>
</example>
<references>
</references>
<include src="UntrustedDataToExternalAPI.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,44 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Code that passes user input directly to
<code>require('child_process').exec</code>, or some other library
routine that executes a command, allows the user to execute malicious
code.</p>
</overview>
<recommendation>
<p>If possible, use hard-coded string literals to specify the command to run
or library to load. Instead of passing the user input directly to the
process or library function, examine the user input and then choose
among hard-coded string literals.</p>
<p>If the applicable libraries or commands cannot be determined at
compile time, then add code to verify that the user input string is
safe before using it.</p>
</recommendation>
<example>
<p>The following example shows code that takes a shell script that can be changed
maliciously by a user, and passes it straight to <code>child_process.exec</code>
without examining it first.</p>
<sample src="examples/command-injection.js" />
</example>
<references>
<li>
OWASP:
<a href="https://www.owasp.org/index.php/Command_Injection">Command Injection</a>.
</li>
<!-- LocalWords: CWE untrusted unsanitized Runtime
-->
</references>
</qhelp>

Просмотреть файл

@ -1,44 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Code that passes user input directly to
<code>require('child_process').exec</code>, or some other library
routine that executes a command, allows the user to execute malicious
code.</p>
</overview>
<recommendation>
<p>If possible, use hard-coded string literals to specify the command to run
or library to load. Instead of passing the user input directly to the
process or library function, examine the user input and then choose
among hard-coded string literals.</p>
<p>If the applicable libraries or commands cannot be determined at
compile time, then add code to verify that the user input string is
safe before using it.</p>
</recommendation>
<example>
<p>The following example shows code that takes a shell script that can be changed
maliciously by a user, and passes it straight to <code>child_process.exec</code>
without examining it first.</p>
<sample src="examples/command-injection.js" />
</example>
<references>
<li>
OWASP:
<a href="https://www.owasp.org/index.php/Command_Injection">Command Injection</a>.
</li>
<!-- LocalWords: CWE untrusted unsanitized Runtime
-->
</references>
<include src="CommandInjection.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,57 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Directly writing user input (for example, a URL query parameter) to a webpage
without properly sanitizing the input first, allows for a cross-site scripting vulnerability.
</p>
<p>
This kind of vulnerability is also called <i>DOM-based</i> cross-site scripting, to distinguish
it from other types of cross-site scripting.
</p>
</overview>
<recommendation>
<p>
To guard against cross-site scripting, consider using contextual output encoding/escaping before
writing user input to the page, or one of the other solutions that are mentioned in the
references.
</p>
</recommendation>
<example>
<p>
The following example shows part of the page URL being written directly to the document,
leaving the website vulnerable to cross-site scripting.
</p>
<sample src="examples/Xss.js" />
</example>
<references>
<li>
OWASP:
<a href="https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html">DOM based
XSS Prevention Cheat Sheet</a>.
</li>
<li>
OWASP:
<a href="https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html">XSS
(Cross Site Scripting) Prevention Cheat Sheet</a>.
</li>
<li>
OWASP
<a href="https://www.owasp.org/index.php/DOM_Based_XSS">DOM Based XSS</a>.
</li>
<li>
OWASP
<a href="https://www.owasp.org/index.php/Types_of_Cross-Site_Scripting">Types of Cross-Site
Scripting</a>.
</li>
<li>
Wikipedia: <a href="http://en.wikipedia.org/wiki/Cross-site_scripting">Cross-site scripting</a>.
</li>
</references>
</qhelp>

Просмотреть файл

@ -1,57 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Directly writing user input (for example, a URL query parameter) to a webpage
without properly sanitizing the input first, allows for a cross-site scripting vulnerability.
</p>
<p>
This kind of vulnerability is also called <i>DOM-based</i> cross-site scripting, to distinguish
it from other types of cross-site scripting.
</p>
</overview>
<recommendation>
<p>
To guard against cross-site scripting, consider using contextual output encoding/escaping before
writing user input to the page, or one of the other solutions that are mentioned in the
references.
</p>
</recommendation>
<example>
<p>
The following example shows part of the page URL being written directly to the document,
leaving the website vulnerable to cross-site scripting.
</p>
<sample src="examples/Xss.js" />
</example>
<references>
<li>
OWASP:
<a href="https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html">DOM based
XSS Prevention Cheat Sheet</a>.
</li>
<li>
OWASP:
<a href="https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html">XSS
(Cross Site Scripting) Prevention Cheat Sheet</a>.
</li>
<li>
OWASP
<a href="https://www.owasp.org/index.php/DOM_Based_XSS">DOM Based XSS</a>.
</li>
<li>
OWASP
<a href="https://www.owasp.org/index.php/Types_of_Cross-Site_Scripting">Types of Cross-Site
Scripting</a>.
</li>
<li>
Wikipedia: <a href="http://en.wikipedia.org/wiki/Cross-site_scripting">Cross-site scripting</a>.
</li>
</references>
<include src="Xss.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,62 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
If a database query (such as a SQL or NoSQL query) is built from
user-provided data without sufficient sanitization, a malicious user
may be able to run malicious database queries.
</p>
</overview>
<recommendation>
<p>
Most database connector libraries offer a way of safely
embedding untrusted data into a query by means of query parameters
or prepared statements.
</p>
<p>
For NoSQL queries, make use of an operator like MongoDB's <code>$eq</code>
to ensure that untrusted data is interpreted as a literal value and not as
a query object.
</p>
</recommendation>
<example>
<p>
In the following example, assume the function <code>handler</code> is
an HTTP request handler in a web application, whose parameter
<code>req</code> contains the request object.
</p>
<p>
The handler constructs two copies of the same SQL query involving
user input taken from the request object, once unsafely using
string concatenation, and once safely using query parameters.
</p>
<p>
In the first case, the query string <code>query1</code> is built by
directly concatenating a user-supplied request parameter with some
string literals. The parameter may include quote characters, so this
code is vulnerable to a SQL injection attack.
</p>
<p>
In the second case, the parameter is embedded into the query string
<code>query2</code> using query parameters. In this example, we use
the API offered by the <code>pg</code> Postgres database connector
library, but other libraries offer similar features. This version is
immune to injection attacks.
</p>
<sample src="examples/SqlInjection.js" />
</example>
<references>
<li>Wikipedia: <a href="https://en.wikipedia.org/wiki/SQL_injection">SQL injection</a>.</li>
<li>MongoDB: <a href="https://docs.mongodb.com/manual/reference/operator/query/eq">$eq operator</a>.</li>
</references>
</qhelp>

Просмотреть файл

@ -1,62 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
If a database query (such as a SQL or NoSQL query) is built from
user-provided data without sufficient sanitization, a malicious user
may be able to run malicious database queries.
</p>
</overview>
<recommendation>
<p>
Most database connector libraries offer a way of safely
embedding untrusted data into a query by means of query parameters
or prepared statements.
</p>
<p>
For NoSQL queries, make use of an operator like MongoDB's <code>$eq</code>
to ensure that untrusted data is interpreted as a literal value and not as
a query object.
</p>
</recommendation>
<example>
<p>
In the following example, assume the function <code>handler</code> is
an HTTP request handler in a web application, whose parameter
<code>req</code> contains the request object.
</p>
<p>
The handler constructs two copies of the same SQL query involving
user input taken from the request object, once unsafely using
string concatenation, and once safely using query parameters.
</p>
<p>
In the first case, the query string <code>query1</code> is built by
directly concatenating a user-supplied request parameter with some
string literals. The parameter may include quote characters, so this
code is vulnerable to a SQL injection attack.
</p>
<p>
In the second case, the parameter is embedded into the query string
<code>query2</code> using query parameters. In this example, we use
the API offered by the <code>pg</code> Postgres database connector
library, but other libraries offer similar features. This version is
immune to injection attacks.
</p>
<sample src="examples/SqlInjection.js" />
</example>
<references>
<li>Wikipedia: <a href="https://en.wikipedia.org/wiki/SQL_injection">SQL injection</a>.</li>
<li>MongoDB: <a href="https://docs.mongodb.com/manual/reference/operator/query/eq">$eq operator</a>.</li>
</references>
<include src="SqlInjection.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,63 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Directly evaluating user input (for example, an HTTP request parameter) as code without properly
sanitizing the input first allows an attacker arbitrary code execution. This can occur when user
input is treated as JavaScript, or passed to a framework which interprets it as an expression to be
evaluated. Examples include AngularJS expressions or JQuery selectors.
</p>
</overview>
<recommendation>
<p>
Avoid including user input in any expression which may be dynamically evaluated. If user input must
be included, use context-specific escaping before
including it. It is important that the correct escaping is used for the type of evaluation that will
occur.
</p>
</recommendation>
<example>
<p>
The following example shows part of the page URL being evaluated as JavaScript code. This allows an
attacker to provide JavaScript within the URL. If an attacker can persuade a user to click on a link
to such a URL, the attacker can evaluate arbitrary JavaScript in the browser of the user to,
for example, steal cookies containing session information.
</p>
<sample src="examples/CodeInjection.js" />
<p>
The following example shows a Pug template being constructed from user input, allowing attackers to run
arbitrary code via a payload such as <code>#{global.process.exit(1)}</code>.
</p>
<sample src="examples/ServerSideTemplateInjection.js" />
<p>
Below is an example of how to use a template engine without any risk of template injection.
The user input is included via an interpolation expression <code>#{username}</code> whose value is provided
as an option to the template, instead of being part of the template string itself:
</p>
<sample src="examples/ServerSideTemplateInjectionSafe.js" />
</example>
<references>
<li>
OWASP:
<a href="https://www.owasp.org/index.php/Code_Injection">Code Injection</a>.
</li>
<li>
Wikipedia: <a href="https://en.wikipedia.org/wiki/Code_injection">Code Injection</a>.
</li>
<li>
PortSwigger Research Blog:
<a href="https://portswigger.net/research/server-side-template-injection">Server-Side Template Injection</a>.
</li>
</references>
</qhelp>

Просмотреть файл

@ -1,63 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Directly evaluating user input (for example, an HTTP request parameter) as code without properly
sanitizing the input first allows an attacker arbitrary code execution. This can occur when user
input is treated as JavaScript, or passed to a framework which interprets it as an expression to be
evaluated. Examples include AngularJS expressions or JQuery selectors.
</p>
</overview>
<recommendation>
<p>
Avoid including user input in any expression which may be dynamically evaluated. If user input must
be included, use context-specific escaping before
including it. It is important that the correct escaping is used for the type of evaluation that will
occur.
</p>
</recommendation>
<example>
<p>
The following example shows part of the page URL being evaluated as JavaScript code. This allows an
attacker to provide JavaScript within the URL. If an attacker can persuade a user to click on a link
to such a URL, the attacker can evaluate arbitrary JavaScript in the browser of the user to,
for example, steal cookies containing session information.
</p>
<sample src="examples/CodeInjection.js" />
<p>
The following example shows a Pug template being constructed from user input, allowing attackers to run
arbitrary code via a payload such as <code>#{global.process.exit(1)}</code>.
</p>
<sample src="examples/ServerSideTemplateInjection.js" />
<p>
Below is an example of how to use a template engine without any risk of template injection.
The user input is included via an interpolation expression <code>#{username}</code> whose value is provided
as an option to the template, instead of being part of the template string itself:
</p>
<sample src="examples/ServerSideTemplateInjectionSafe.js" />
</example>
<references>
<li>
OWASP:
<a href="https://www.owasp.org/index.php/Code_Injection">Code Injection</a>.
</li>
<li>
Wikipedia: <a href="https://en.wikipedia.org/wiki/Code_injection">Code Injection</a>.
</li>
<li>
PortSwigger Research Blog:
<a href="https://portswigger.net/research/server-side-template-injection">Server-Side Template Injection</a>.
</li>
</references>
<include src="CodeInjection.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,47 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>If unsanitized user input is written to a log entry, a malicious user may be able to forge new log entries.</p>
<p>Forgery can occur if a user provides some input with characters that are interpreted
when the log output is displayed. If the log is displayed as a plain text file, then new
line characters can be used by a malicious user. If the log is displayed as HTML, then
arbitrary HTML may be included to spoof log entries.</p>
</overview>
<recommendation>
<p>
User input should be suitably sanitized before it is logged.
</p>
<p>
If the log entries are in plain text then line breaks should be removed from user input, using
<code>String.prototype.replace</code> or similar. Care should also be taken that user input is clearly marked
in log entries.
</p>
<p>
For log entries that will be displayed in HTML, user input should be HTML-encoded before being logged, to prevent forgery and
other forms of HTML injection.
</p>
</recommendation>
<example>
<p>In the first example, a username, provided by the user, is logged using `console.info`. In
the first case, it is logged without any sanitization. In the second case, the username is used to build an error that is logged using `console.error`.
If a malicious user provides `username=Guest%0a[INFO]+User:+Admin%0a` as a username parameter,
the log entry will be splitted in two different lines, where the second line will be `[INFO]+User:+Admin`.
</p>
<sample src="examples/logInjectionBad.js" />
<p> In the second example, <code>String.prototype.replace</code> is used to ensure no line endings are present in the user input.</p>
<sample src="examples/logInjectionGood.js" />
</example>
<references>
<li>OWASP: <a href="https://www.owasp.org/index.php/Log_Injection">Log Injection</a>.</li>
</references>
</qhelp>

Просмотреть файл

@ -1,47 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>If unsanitized user input is written to a log entry, a malicious user may be able to forge new log entries.</p>
<p>Forgery can occur if a user provides some input with characters that are interpreted
when the log output is displayed. If the log is displayed as a plain text file, then new
line characters can be used by a malicious user. If the log is displayed as HTML, then
arbitrary HTML may be included to spoof log entries.</p>
</overview>
<recommendation>
<p>
User input should be suitably sanitized before it is logged.
</p>
<p>
If the log entries are in plain text then line breaks should be removed from user input, using
<code>String.prototype.replace</code> or similar. Care should also be taken that user input is clearly marked
in log entries.
</p>
<p>
For log entries that will be displayed in HTML, user input should be HTML-encoded before being logged, to prevent forgery and
other forms of HTML injection.
</p>
</recommendation>
<example>
<p>In the first example, a username, provided by the user, is logged using `console.info`. In
the first case, it is logged without any sanitization. In the second case, the username is used to build an error that is logged using `console.error`.
If a malicious user provides `username=Guest%0a[INFO]+User:+Admin%0a` as a username parameter,
the log entry will be splitted in two different lines, where the second line will be `[INFO]+User:+Admin`.
</p>
<sample src="examples/logInjectionBad.js" />
<p> In the second example, <code>String.prototype.replace</code> is used to ensure no line endings are present in the user input.</p>
<sample src="examples/logInjectionGood.js" />
</example>
<references>
<li>OWASP: <a href="https://www.owasp.org/index.php/Log_Injection">Log Injection</a>.</li>
</references>
<include src="LogInjection.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,46 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Functions like the Node.js standard library function <code>util.format</code> accept a
format string that is used to format the remaining arguments by providing inline format
specifiers. If the format string contains unsanitized input from an untrusted source,
then that string may contain unexpected format specifiers that cause garbled output.
</p>
</overview>
<recommendation>
<p>
Either sanitize the input before including it in the format string, or use a
<code>%s</code> specifier in the format string, and pass the untrusted data as corresponding
argument.
</p>
</recommendation>
<example>
<p>
The following program snippet logs information about an unauthorized access attempt. The
log message includes the user name, and the user's IP address is passed as an additional
argument to <code>console.log</code> to be appended to the message:
</p>
<sample src="examples/TaintedFormatStringBad.js"/>
<p>
However, if a malicious user provides <code>%d</code> as their user name, <code>console.log</code>
will instead attempt to format the <code>ip</code> argument as a number. Since IP addresses are
not valid numbers, the result of this conversion is <code>NaN</code>. The resulting log message
will read "Unauthorized access attempt by NaN", missing all the information that it was trying to
log in the first place.
</p>
<p>
Instead, the user name should be included using the <code>%s</code> specifier:
</p>
<sample src="examples/TaintedFormatStringGood.js"/>
</example>
<references>
<li>Node.js Documentation: <a href="https://nodejs.org/api/util.html#util_util_format_format_args">util.format</a>.</li>
</references>
</qhelp>

Просмотреть файл

@ -1,46 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Functions like the Node.js standard library function <code>util.format</code> accept a
format string that is used to format the remaining arguments by providing inline format
specifiers. If the format string contains unsanitized input from an untrusted source,
then that string may contain unexpected format specifiers that cause garbled output.
</p>
</overview>
<recommendation>
<p>
Either sanitize the input before including it in the format string, or use a
<code>%s</code> specifier in the format string, and pass the untrusted data as corresponding
argument.
</p>
</recommendation>
<example>
<p>
The following program snippet logs information about an unauthorized access attempt. The
log message includes the user name, and the user's IP address is passed as an additional
argument to <code>console.log</code> to be appended to the message:
</p>
<sample src="examples/TaintedFormatStringBad.js"/>
<p>
However, if a malicious user provides <code>%d</code> as their user name, <code>console.log</code>
will instead attempt to format the <code>ip</code> argument as a number. Since IP addresses are
not valid numbers, the result of this conversion is <code>NaN</code>. The resulting log message
will read "Unauthorized access attempt by NaN", missing all the information that it was trying to
log in the first place.
</p>
<p>
Instead, the user name should be included using the <code>%s</code> specifier:
</p>
<sample src="examples/TaintedFormatStringGood.js"/>
</example>
<references>
<li>Node.js Documentation: <a href="https://nodejs.org/api/util.html#util_util_format_format_args">util.format</a>.</li>
</references>
<include src="TaintedFormatString.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,85 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
A server can send the
<code>"Access-Control-Allow-Credentials"</code> CORS header to control
when a browser may send user credentials in Cross-Origin HTTP
requests.
</p>
<p>
When the <code>Access-Control-Allow-Credentials</code> header
is <code>"true"</code>, the <code>Access-Control-Allow-Origin</code>
header must have a value different from <code>"*"</code> in order to
make browsers accept the header. Therefore, to allow multiple origins
for Cross-Origin requests with credentials, the server must
dynamically compute the value of the
<code>"Access-Control-Allow-Origin"</code> header. Computing this
header value from information in the request to the server can
therefore potentially allow an attacker to control the origins that
the browser sends credentials to.
</p>
</overview>
<recommendation>
<p>
When the <code>Access-Control-Allow-Credentials</code> header
value is <code>"true"</code>, a dynamic computation of the
<code>Access-Control-Allow-Origin</code> header must involve
sanitization if it relies on user-controlled input.
</p>
<p>
Since the <code>"null"</code> origin is easy to obtain for an
attacker, it is never safe to use <code>"null"</code> as the value of
the <code>Access-Control-Allow-Origin</code> header when the
<code>Access-Control-Allow-Credentials</code> header value is
<code>"true"</code>.
</p>
</recommendation>
<example>
<p>
In the example below, the server allows the browser to send
user credentials in a Cross-Origin request. The request header
<code>origins</code> controls the allowed origins for such a
Cross-Origin request.
</p>
<sample src="examples/CorsMisconfigurationForCredentials.js"/>
<p>
This is not secure, since an attacker can choose the value of
the <code>origin</code> request header to make the browser send
credentials to their own server. The use of a whitelist containing
allowed origins for the Cross-Origin request fixes the issue:
</p>
<sample src="examples/CorsMisconfigurationForCredentials_fixed.js"/>
</example>
<references>
<li>Mozilla Developer Network: <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin">CORS, Access-Control-Allow-Origin</a>.</li>
<li>Mozilla Developer Network: <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials">CORS, Access-Control-Allow-Credentials</a>.</li>
<li>PortSwigger: <a href="http://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html">Exploiting CORS Misconfigurations for Bitcoins and Bounties</a></li>
<li>W3C: <a href="https://w3c.github.io/webappsec-cors-for-developers/#resources">CORS for developers, Advice for Resource Owners</a></li>
</references>
</qhelp>

Просмотреть файл

@ -2,84 +2,5 @@
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
A server can send the
<code>"Access-Control-Allow-Credentials"</code> CORS header to control
when a browser may send user credentials in Cross-Origin HTTP
requests.
</p>
<p>
When the <code>Access-Control-Allow-Credentials</code> header
is <code>"true"</code>, the <code>Access-Control-Allow-Origin</code>
header must have a value different from <code>"*"</code> in order to
make browsers accept the header. Therefore, to allow multiple origins
for Cross-Origin requests with credentials, the server must
dynamically compute the value of the
<code>"Access-Control-Allow-Origin"</code> header. Computing this
header value from information in the request to the server can
therefore potentially allow an attacker to control the origins that
the browser sends credentials to.
</p>
</overview>
<recommendation>
<p>
When the <code>Access-Control-Allow-Credentials</code> header
value is <code>"true"</code>, a dynamic computation of the
<code>Access-Control-Allow-Origin</code> header must involve
sanitization if it relies on user-controlled input.
</p>
<p>
Since the <code>"null"</code> origin is easy to obtain for an
attacker, it is never safe to use <code>"null"</code> as the value of
the <code>Access-Control-Allow-Origin</code> header when the
<code>Access-Control-Allow-Credentials</code> header value is
<code>"true"</code>.
</p>
</recommendation>
<example>
<p>
In the example below, the server allows the browser to send
user credentials in a Cross-Origin request. The request header
<code>origins</code> controls the allowed origins for such a
Cross-Origin request.
</p>
<sample src="examples/CorsMisconfigurationForCredentials.js"/>
<p>
This is not secure, since an attacker can choose the value of
the <code>origin</code> request header to make the browser send
credentials to their own server. The use of a whitelist containing
allowed origins for the Cross-Origin request fixes the issue:
</p>
<sample src="examples/CorsMisconfigurationForCredentials_fixed.js"/>
</example>
<references>
<li>Mozilla Developer Network: <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin">CORS, Access-Control-Allow-Origin</a>.</li>
<li>Mozilla Developer Network: <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials">CORS, Access-Control-Allow-Credentials</a>.</li>
<li>PortSwigger: <a href="http://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html">Exploiting CORS Misconfigurations for Bitcoins and Bounties</a></li>
<li>W3C: <a href="https://w3c.github.io/webappsec-cors-for-developers/#resources">CORS for developers, Advice for Resource Owners</a></li>
</references>
<include src="CorsMisconfigurationForCredentials.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,87 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Dynamically computing object property names from untrusted input
may have multiple undesired consequences. For example,
if the property access is used as part of a write, an
attacker may overwrite vital properties of objects, such as
<code>__proto__</code>. This attack is known as <i>prototype
pollution attack</i> and may serve as a vehicle for denial-of-service
attacks. A similar attack vector, is to replace the
<code>toString</code> property of an object with a primitive.
Whenever <code>toString</code> is then called on that object, either
explicitly or implicitly as part of a type coercion, an exception
will be raised.
</p>
<p>
Moreover, if the name of an HTTP header is user-controlled,
an attacker may exploit this to overwrite security-critical headers
such as <code>Access-Control-Allow-Origin</code> or
<code>Content-Security-Policy</code>.
</p>
</overview>
<recommendation>
<p>
The most common case in which prototype pollution vulnerabilities arise
is when JavaScript objects are used for implementing map data
structures. This case should be avoided whenever possible by using the
ECMAScript 2015 <code>Map</code> instead. When this is not possible, an
alternative fix is to prepend untrusted input with a marker character
such as <code>$</code>, before using it in properties accesses. In this way,
the attacker does not have access to built-in properties which do not
start with the chosen character.
</p>
<p>
When using user input as part of a header name, a sanitization
step should be performed on the input to ensure that the name does not
clash with existing header names such as
<code>Content-Security-Policy</code>.
</p>
</recommendation>
<example>
<p>
In the example below, the dynamically computed property
<code>prop</code> is accessed on <code>myObj</code> using a
user-controlled value.
</p>
<sample src="examples/RemotePropertyInjection.js"/>
<p>
This is not secure since an attacker may exploit this code to
overwrite the property <code>__proto__</code> with an empty function.
If this happens, the concatenation in the <code>console.log</code>
argument will fail with a confusing message such as
"Function.prototype.toString is not generic". If the application does
not properly handle this error, this scenario may result in a serious
denial-of-service attack. The fix is to prepend the user-controlled
string with a marker character such as <code>$</code> which will
prevent arbitrary property names from being overwritten.
</p>
<sample src="examples/RemotePropertyInjection_fixed.js"/>
</example>
<references>
<li>Prototype pollution attacks:
<a href="https://github.com/electron/electron/pull/9287">electron</a>,
<a href="https://hackerone.com/reports/310443">lodash</a>,
<a href="https://npmjs.com/advisories/566">hoek</a>.
</li>
<li> Penetration testing report:
<a href="http://seclists.org/pen-test/2009/Mar/67">
header name injection attack</a>
</li>
<li> npm blog post:
<a href="https://github.com/nodesecurity/eslint-plugin-security/blob/3c7522ca1be800353513282867a1034c795d9eb4/docs/the-dangers-of-square-bracket-notation.md">
dangers of square bracket notation</a>
</li>
</references>
</qhelp>

Просмотреть файл

@ -2,86 +2,5 @@
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Dynamically computing object property names from untrusted input
may have multiple undesired consequences. For example,
if the property access is used as part of a write, an
attacker may overwrite vital properties of objects, such as
<code>__proto__</code>. This attack is known as <i>prototype
pollution attack</i> and may serve as a vehicle for denial-of-service
attacks. A similar attack vector, is to replace the
<code>toString</code> property of an object with a primitive.
Whenever <code>toString</code> is then called on that object, either
explicitly or implicitly as part of a type coercion, an exception
will be raised.
</p>
<p>
Moreover, if the name of an HTTP header is user-controlled,
an attacker may exploit this to overwrite security-critical headers
such as <code>Access-Control-Allow-Origin</code> or
<code>Content-Security-Policy</code>.
</p>
</overview>
<recommendation>
<p>
The most common case in which prototype pollution vulnerabilities arise
is when JavaScript objects are used for implementing map data
structures. This case should be avoided whenever possible by using the
ECMAScript 2015 <code>Map</code> instead. When this is not possible, an
alternative fix is to prepend untrusted input with a marker character
such as <code>$</code>, before using it in properties accesses. In this way,
the attacker does not have access to built-in properties which do not
start with the chosen character.
</p>
<p>
When using user input as part of a header name, a sanitization
step should be performed on the input to ensure that the name does not
clash with existing header names such as
<code>Content-Security-Policy</code>.
</p>
</recommendation>
<example>
<p>
In the example below, the dynamically computed property
<code>prop</code> is accessed on <code>myObj</code> using a
user-controlled value.
</p>
<sample src="examples/RemotePropertyInjection.js"/>
<p>
This is not secure since an attacker may exploit this code to
overwrite the property <code>__proto__</code> with an empty function.
If this happens, the concatenation in the <code>console.log</code>
argument will fail with a confusing message such as
"Function.prototype.toString is not generic". If the application does
not properly handle this error, this scenario may result in a serious
denial-of-service attack. The fix is to prepend the user-controlled
string with a marker character such as <code>$</code> which will
prevent arbitrary property names from being overwritten.
</p>
<sample src="examples/RemotePropertyInjection_fixed.js"/>
</example>
<references>
<li>Prototype pollution attacks:
<a href="https://github.com/electron/electron/pull/9287">electron</a>,
<a href="https://hackerone.com/reports/310443">lodash</a>,
<a href="https://npmjs.com/advisories/566">hoek</a>.
</li>
<li> Penetration testing report:
<a href="http://seclists.org/pen-test/2009/Mar/67">
header name injection attack</a>
</li>
<li> npm blog post:
<a href="https://github.com/nodesecurity/eslint-plugin-security/blob/3c7522ca1be800353513282867a1034c795d9eb4/docs/the-dangers-of-square-bracket-notation.md">
dangers of square bracket notation</a>
</li>
</references>
<include src="RemotePropertyInjection.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,52 @@
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
<qhelp>
<overview>
<p>
Deserializing untrusted data using any deserialization framework that
allows the construction of arbitrary functions is easily exploitable
and, in many cases, allows an attacker to execute arbitrary code.
</p>
</overview>
<recommendation>
<p>
Avoid deserialization of untrusted data if at all possible. If the
architecture permits it, then use formats like JSON or XML that cannot
represent functions. When using YAML or other formats that support the
serialization and deserialization of functions, ensure that the parser
is configured to disable deserialization of arbitrary functions.
</p>
</recommendation>
<example>
<p>
The following example calls the <code>load</code> function of the popular
<code>js-yaml</code> package on data that comes from an HTTP request and
hence is inherently unsafe.
</p>
<sample src="examples/UnsafeDeserializationBad.js"/>
<p>
Using the <code>safeLoad</code> function instead (which does not deserialize
YAML-encoded functions) removes the vulnerability.
</p>
<sample src="examples/UnsafeDeserializationGood.js" />
</example>
<references>
<li>
OWASP vulnerability description:
<a href="https://www.owasp.org/index.php/Deserialization_of_untrusted_data">Deserialization of untrusted data</a>.
</li>
<li>
OWASP guidance on deserializing objects:
<a href="https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html">Deserialization Cheat Sheet</a>.
</li>
<li>
Neal Poole:
<a href="https://nealpoole.com/blog/2013/06/code-execution-via-yaml-in-js-yaml-nodejs-module/">Code Execution via YAML in JS-YAML Node.js Module</a>.
</li>
</references>
</qhelp>

Просмотреть файл

@ -1,52 +1,6 @@
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Deserializing untrusted data using any deserialization framework that
allows the construction of arbitrary functions is easily exploitable
and, in many cases, allows an attacker to execute arbitrary code.
</p>
</overview>
<recommendation>
<p>
Avoid deserialization of untrusted data if at all possible. If the
architecture permits it, then use formats like JSON or XML that cannot
represent functions. When using YAML or other formats that support the
serialization and deserialization of functions, ensure that the parser
is configured to disable deserialization of arbitrary functions.
</p>
</recommendation>
<example>
<p>
The following example calls the <code>load</code> function of the popular
<code>js-yaml</code> package on data that comes from an HTTP request and
hence is inherently unsafe.
</p>
<sample src="examples/UnsafeDeserializationBad.js"/>
<p>
Using the <code>safeLoad</code> function instead (which does not deserialize
YAML-encoded functions) removes the vulnerability.
</p>
<sample src="examples/UnsafeDeserializationGood.js" />
</example>
<references>
<li>
OWASP vulnerability description:
<a href="https://www.owasp.org/index.php/Deserialization_of_untrusted_data">Deserialization of untrusted data</a>.
</li>
<li>
OWASP guidance on deserializing objects:
<a href="https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html">Deserialization Cheat Sheet</a>.
</li>
<li>
Neal Poole:
<a href="https://nealpoole.com/blog/2013/06/code-execution-via-yaml-in-js-yaml-nodejs-module/">Code Execution via YAML in JS-YAML Node.js Module</a>.
</li>
</references>
<include src="UnsafeDeserialization.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,57 @@
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
<qhelp>
<overview>
<p>
Parsing untrusted XML files with a weakly configured XML parser may lead to an
XML External Entity (XXE) attack. This type of attack uses external entity references
to access arbitrary files on a system, carry out denial-of-service (DoS) attacks, or server-side
request forgery. Even when the result of parsing is not returned to the user, DoS attacks are still possible
and out-of-band data retrieval techniques may allow attackers to steal sensitive data.
</p>
</overview>
<recommendation>
<p>
The easiest way to prevent XXE attacks is to disable external entity handling when
parsing untrusted data. How this is done depends on the library being used. Note that some
libraries, such as recent versions of <code>libxml</code>, disable entity expansion by default,
so unless you have explicitly enabled entity expansion, no further action needs to be taken.
</p>
</recommendation>
<example>
<p>
The following example uses the <code>libxml</code> XML parser to parse a string <code>xmlSrc</code>.
If that string is from an untrusted source, this code may be vulnerable to an XXE attack, since
the parser is invoked with the <code>noent</code> option set to <code>true</code>:
</p>
<sample src="examples/Xxe.js"/>
<p>
To guard against XXE attacks, the <code>noent</code> option should be omitted or set to
<code>false</code>. This means that no entity expansion is undertaken at all, not even for standard
internal entities such as <code>&amp;amp;</code> or <code>&amp;gt;</code>. If desired, these
entities can be expanded in a separate step using utility functions provided by libraries such
as <a href="http://underscorejs.org/#unescape">underscore</a>,
<a href="https://lodash.com/docs/4.17.15#unescape">lodash</a> or
<a href="https://github.com/mathiasbynens/he">he</a>.
</p>
<sample src="examples/XxeGood.js"/>
</example>
<references>
<li>
OWASP:
<a href="https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing">XML External Entity (XXE) Processing</a>.
</li>
<li>
Timothy Morgen:
<a href="https://research.nccgroup.com/2014/05/19/xml-schema-dtd-and-entity-attacks-a-compendium-of-known-techniques/">XML Schema, DTD, and Entity Attacks</a>.
</li>
<li>
Timur Yunusov, Alexey Osipov:
<a href="https://www.slideshare.net/qqlan/bh-ready-v4">XML Out-Of-Band Data Retrieval</a>.
</li>
</references>
</qhelp>

Просмотреть файл

@ -1,57 +1,6 @@
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Parsing untrusted XML files with a weakly configured XML parser may lead to an
XML External Entity (XXE) attack. This type of attack uses external entity references
to access arbitrary files on a system, carry out denial-of-service (DoS) attacks, or server-side
request forgery. Even when the result of parsing is not returned to the user, DoS attacks are still possible
and out-of-band data retrieval techniques may allow attackers to steal sensitive data.
</p>
</overview>
<recommendation>
<p>
The easiest way to prevent XXE attacks is to disable external entity handling when
parsing untrusted data. How this is done depends on the library being used. Note that some
libraries, such as recent versions of <code>libxml</code>, disable entity expansion by default,
so unless you have explicitly enabled entity expansion, no further action needs to be taken.
</p>
</recommendation>
<example>
<p>
The following example uses the <code>libxml</code> XML parser to parse a string <code>xmlSrc</code>.
If that string is from an untrusted source, this code may be vulnerable to an XXE attack, since
the parser is invoked with the <code>noent</code> option set to <code>true</code>:
</p>
<sample src="examples/Xxe.js"/>
<p>
To guard against XXE attacks, the <code>noent</code> option should be omitted or set to
<code>false</code>. This means that no entity expansion is undertaken at all, not even for standard
internal entities such as <code>&amp;amp;</code> or <code>&amp;gt;</code>. If desired, these
entities can be expanded in a separate step using utility functions provided by libraries such
as <a href="http://underscorejs.org/#unescape">underscore</a>,
<a href="https://lodash.com/docs/4.17.15#unescape">lodash</a> or
<a href="https://github.com/mathiasbynens/he">he</a>.
</p>
<sample src="examples/XxeGood.js"/>
</example>
<references>
<li>
OWASP:
<a href="https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing">XML External Entity (XXE) Processing</a>.
</li>
<li>
Timothy Morgen:
<a href="https://research.nccgroup.com/2014/05/19/xml-schema-dtd-and-entity-attacks-a-compendium-of-known-techniques/">XML Schema, DTD, and Entity Attacks</a>.
</li>
<li>
Timur Yunusov, Alexey Osipov:
<a href="https://www.slideshare.net/qqlan/bh-ready-v4">XML Out-Of-Band Data Retrieval</a>.
</li>
</references>
<include src="Xxe.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,40 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
If an XPath expression is built using string concatenation, and the components of the concatenation
include user input, it makes it very easy for a user to create a malicious XPath expression.
</p>
</overview>
<recommendation>
<p>
If user input must be included in an XPath expression, either sanitize the data or use variable
references to safely embed it without altering the structure of the expression.
</p>
</recommendation>
<example>
<p>
In this example, the code accepts a user name specified by the user, and uses this
unvalidated and unsanitized value in an XPath expression constructed using the <code>xpath</code>
package. This is vulnerable to the user providing special characters or string sequences
that change the meaning of the XPath expression to search for different values.
</p>
<sample src="examples/XpathInjectionBad.js" />
<p>
Instead, embed the user input using the variable replacement mechanism offered
by <code>xpath</code>:
</p>
<sample src="examples/XpathInjectionGood.js" />
</example>
<references>
<li>OWASP: <a href="https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/09-Testing_for_XPath_Injection">Testing for XPath Injection</a>.</li>
<li>OWASP: <a href="https://www.owasp.org/index.php/XPATH_Injection">XPath Injection</a>.</li>
<li>npm: <a href="https://www.npmjs.com/package/xpath">xpath</a>.</li>
</references>
</qhelp>

Просмотреть файл

@ -1,40 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
If an XPath expression is built using string concatenation, and the components of the concatenation
include user input, it makes it very easy for a user to create a malicious XPath expression.
</p>
</overview>
<recommendation>
<p>
If user input must be included in an XPath expression, either sanitize the data or use variable
references to safely embed it without altering the structure of the expression.
</p>
</recommendation>
<example>
<p>
In this example, the code accepts a user name specified by the user, and uses this
unvalidated and unsanitized value in an XPath expression constructed using the <code>xpath</code>
package. This is vulnerable to the user providing special characters or string sequences
that change the meaning of the XPath expression to search for different values.
</p>
<sample src="examples/XpathInjectionBad.js" />
<p>
Instead, embed the user input using the variable replacement mechanism offered
by <code>xpath</code>:
</p>
<sample src="examples/XpathInjectionGood.js" />
</example>
<references>
<li>OWASP: <a href="https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/09-Testing_for_XPath_Injection">Testing for XPath Injection</a>.</li>
<li>OWASP: <a href="https://www.owasp.org/index.php/XPATH_Injection">XPath Injection</a>.</li>
<li>npm: <a href="https://www.npmjs.com/package/xpath">xpath</a>.</li>
</references>
<include src="XpathInjection.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,48 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Constructing a regular expression with unsanitized user input is dangerous as a malicious user may
be able to modify the meaning of the expression. In particular, such a user may be able to provide
a regular expression fragment that takes exponential time in the worst case, and use that to
perform a Denial of Service attack.
</p>
</overview>
<recommendation>
<p>
Before embedding user input into a regular expression, use a sanitization function such as
lodash's <code>_.escapeRegExp</code> to escape meta-characters that have special meaning.
</p>
</recommendation>
<example>
<p>
The following example shows a HTTP request parameter that is used to construct a regular expression
without sanitizing it first:
</p>
<sample src="examples/RegExpInjection.js" />
<p>
Instead, the request parameter should be sanitized first, for example using the function
<code>_.escapeRegExp</code> from the lodash package. This ensures that the user cannot insert
characters which have a special meaning in regular expressions.
</p>
<sample src="examples/RegExpInjectionGood.js" />
</example>
<references>
<li>
OWASP:
<a href="https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS">Regular expression Denial of Service - ReDoS</a>.
</li>
<li>
Wikipedia: <a href="https://en.wikipedia.org/wiki/ReDoS">ReDoS</a>.
</li>
<li>
npm: <a href="https://www.npmjs.com/package/lodash">lodash</a>.
</li>
</references>
</qhelp>

Просмотреть файл

@ -1,48 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Constructing a regular expression with unsanitized user input is dangerous as a malicious user may
be able to modify the meaning of the expression. In particular, such a user may be able to provide
a regular expression fragment that takes exponential time in the worst case, and use that to
perform a Denial of Service attack.
</p>
</overview>
<recommendation>
<p>
Before embedding user input into a regular expression, use a sanitization function such as
lodash's <code>_.escapeRegExp</code> to escape meta-characters that have special meaning.
</p>
</recommendation>
<example>
<p>
The following example shows a HTTP request parameter that is used to construct a regular expression
without sanitizing it first:
</p>
<sample src="examples/RegExpInjection.js" />
<p>
Instead, the request parameter should be sanitized first, for example using the function
<code>_.escapeRegExp</code> from the lodash package. This ensures that the user cannot insert
characters which have a special meaning in regular expressions.
</p>
<sample src="examples/RegExpInjectionGood.js" />
</example>
<references>
<li>
OWASP:
<a href="https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS">Regular expression Denial of Service - ReDoS</a>.
</li>
<li>
Wikipedia: <a href="https://en.wikipedia.org/wiki/ReDoS">ReDoS</a>.
</li>
<li>
npm: <a href="https://www.npmjs.com/package/lodash">lodash</a>.
</li>
</references>
<include src="RegExpInjection.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,115 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Applications are constrained by how many resources they can make use
of. Failing to respect these constraints may cause the application to
be unresponsive or crash. It is therefore problematic if attackers
can control the sizes or lifetimes of allocated objects.
</p>
</overview>
<recommendation>
<p>
Ensure that attackers can not control object sizes and their
lifetimes. If object sizes and lifetimes must be controlled by
external parties, ensure you restrict the object sizes and lifetimes so that
they are within acceptable ranges.
</p>
</recommendation>
<example>
<p>
The following example allocates a buffer with a user-controlled
size.
</p>
<sample src="examples/ResourceExhaustion_buffer.js" />
<p>
This is problematic since an attacker can choose a size
that makes the application run out of memory. Even worse, in older
versions of Node.js, this could leak confidential memory.
To prevent such attacks, limit the buffer size:
</p>
<sample src="examples/ResourceExhaustion_buffer_fixed.js" />
</example>
<example>
<p>
As another example, consider an application that allocates an
array with a user-controlled size, and then fills it with values:
</p>
<sample src="examples/ResourceExhaustion_array.js" />
<p>
The allocation of the array itself is not problematic since arrays are
allocated sparsely, but the subsequent filling of the array will take
a long time, causing the application to be unresponsive, or even run
out of memory.
Again, a limit on the size will prevent the attack:
</p>
<sample src="examples/ResourceExhaustion_array_fixed.js" />
</example>
<example>
<p>
Finally, the following example lets a user choose a delay after
which a function is executed:
</p>
<sample src="examples/ResourceExhaustion_timeout.js" />
<p>
This is problematic because a large delay essentially makes the
application wait indefinitely before executing the function. Repeated
registrations of such delays will therefore use up all of the memory
in the application.
A limit on the delay will prevent the attack:
</p>
<sample src="examples/ResourceExhaustion_timeout_fixed.js" />
</example>
<references>
<li>
Wikipedia: <a href="https://en.wikipedia.org/wiki/Denial-of-service_attack">Denial-of-service attack</a>.
</li>
</references>
</qhelp>

Просмотреть файл

@ -2,114 +2,5 @@
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Applications are constrained by how many resources they can make use
of. Failing to respect these constraints may cause the application to
be unresponsive or crash. It is therefore problematic if attackers
can control the sizes or lifetimes of allocated objects.
</p>
</overview>
<recommendation>
<p>
Ensure that attackers can not control object sizes and their
lifetimes. If object sizes and lifetimes must be controlled by
external parties, ensure you restrict the object sizes and lifetimes so that
they are within acceptable ranges.
</p>
</recommendation>
<example>
<p>
The following example allocates a buffer with a user-controlled
size.
</p>
<sample src="examples/ResourceExhaustion_buffer.js" />
<p>
This is problematic since an attacker can choose a size
that makes the application run out of memory. Even worse, in older
versions of Node.js, this could leak confidential memory.
To prevent such attacks, limit the buffer size:
</p>
<sample src="examples/ResourceExhaustion_buffer_fixed.js" />
</example>
<example>
<p>
As another example, consider an application that allocates an
array with a user-controlled size, and then fills it with values:
</p>
<sample src="examples/ResourceExhaustion_array.js" />
<p>
The allocation of the array itself is not problematic since arrays are
allocated sparsely, but the subsequent filling of the array will take
a long time, causing the application to be unresponsive, or even run
out of memory.
Again, a limit on the size will prevent the attack:
</p>
<sample src="examples/ResourceExhaustion_array_fixed.js" />
</example>
<example>
<p>
Finally, the following example lets a user choose a delay after
which a function is executed:
</p>
<sample src="examples/ResourceExhaustion_timeout.js" />
<p>
This is problematic because a large delay essentially makes the
application wait indefinitely before executing the function. Repeated
registrations of such delays will therefore use up all of the memory
in the application.
A limit on the delay will prevent the attack:
</p>
<sample src="examples/ResourceExhaustion_timeout_fixed.js" />
</example>
<references>
<li>
Wikipedia: <a href="https://en.wikipedia.org/wiki/Denial-of-service_attack">Denial-of-service attack</a>.
</li>
</references>
<include src="ResourceExhaustion.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,60 @@
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
<qhelp>
<overview>
<p>
Parsing untrusted XML files with a weakly configured XML parser may be vulnerable to
denial-of-service (DoS) attacks exploiting uncontrolled internal entity expansion.
</p>
<p>
In XML, so-called <i>internal entities</i> are a mechanism for introducing an abbreviation
for a piece of text or part of a document. When a parser that has been configured
to expand entities encounters a reference to an internal entity, it replaces the entity
by the data it represents. The replacement text may itself contain other entity references,
which are expanded recursively. This means that entity expansion can increase document size
dramatically.
</p>
<p>
If untrusted XML is parsed with entity expansion enabled, a malicious attacker could
submit a document that contains very deeply nested entity definitions, causing the parser
to take a very long time or use large amounts of memory. This is sometimes called an
<i>XML bomb</i> attack.
</p>
</overview>
<recommendation>
<p>
The safest way to prevent XML bomb attacks is to disable entity expansion when parsing untrusted
data. How this is done depends on the library being used. Note that some libraries, such as
recent versions of <code>libxmljs</code> (though not its SAX parser API), disable entity expansion
by default, so unless you have explicitly enabled entity expansion, no further action is needed.
</p>
</recommendation>
<example>
<p>
The following example uses the XML parser provided by the <code>node-expat</code> package to
parse a string <code>xmlSrc</code>. If that string is from an untrusted source, this code may be
vulnerable to a DoS attack, since <code>node-expat</code> expands internal entities by default:
</p>
<sample src="examples/XmlBomb.js"/>
<p>
At the time of writing, <code>node-expat</code> does not provide a way of controlling entity
expansion, but the example could be rewritten to use the <code>sax</code> package instead,
which only expands standard entities such as <code>&amp;amp;</code>:
</p>
<sample src="examples/XmlBombGood.js"/>
</example>
<references>
<li>
Wikipedia:
<a href="https://en.wikipedia.org/wiki/Billion_laughs">Billion Laughs</a>.
</li>
<li>
Bryan Sullivan:
<a href="https://msdn.microsoft.com/en-us/magazine/ee335713.aspx">Security Briefs - XML Denial of Service Attacks and Defenses</a>.
</li>
</references>
</qhelp>

Просмотреть файл

@ -1,60 +1,6 @@
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Parsing untrusted XML files with a weakly configured XML parser may be vulnerable to
denial-of-service (DoS) attacks exploiting uncontrolled internal entity expansion.
</p>
<p>
In XML, so-called <i>internal entities</i> are a mechanism for introducing an abbreviation
for a piece of text or part of a document. When a parser that has been configured
to expand entities encounters a reference to an internal entity, it replaces the entity
by the data it represents. The replacement text may itself contain other entity references,
which are expanded recursively. This means that entity expansion can increase document size
dramatically.
</p>
<p>
If untrusted XML is parsed with entity expansion enabled, a malicious attacker could
submit a document that contains very deeply nested entity definitions, causing the parser
to take a very long time or use large amounts of memory. This is sometimes called an
<i>XML bomb</i> attack.
</p>
</overview>
<recommendation>
<p>
The safest way to prevent XML bomb attacks is to disable entity expansion when parsing untrusted
data. How this is done depends on the library being used. Note that some libraries, such as
recent versions of <code>libxmljs</code> (though not its SAX parser API), disable entity expansion
by default, so unless you have explicitly enabled entity expansion, no further action is needed.
</p>
</recommendation>
<example>
<p>
The following example uses the XML parser provided by the <code>node-expat</code> package to
parse a string <code>xmlSrc</code>. If that string is from an untrusted source, this code may be
vulnerable to a DoS attack, since <code>node-expat</code> expands internal entities by default:
</p>
<sample src="examples/XmlBomb.js"/>
<p>
At the time of writing, <code>node-expat</code> does not provide a way of controlling entity
expansion, but the example could be rewritten to use the <code>sax</code> package instead,
which only expands standard entities such as <code>&amp;amp;</code>:
</p>
<sample src="examples/XmlBombGood.js"/>
</example>
<references>
<li>
Wikipedia:
<a href="https://en.wikipedia.org/wiki/Billion_laughs">Billion Laughs</a>.
</li>
<li>
Bryan Sullivan:
<a href="https://msdn.microsoft.com/en-us/magazine/ee335713.aspx">Security Briefs - XML Denial of Service Attacks and Defenses</a>.
</li>
</references>
<include src="XmlBomb.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,27 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Using user-controlled data in a permissions check may
allow a user to gain unauthorized access to protected functionality or
data.
</p>
</overview>
<recommendation>
<include src="recommendation.inc.qhelp" />
</recommendation>
<example>
<include src="example.inc.qhelp" />
</example>
<references>
</references>
</qhelp>

Просмотреть файл

@ -2,26 +2,5 @@
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Using user-controlled data in a permissions check may
allow a user to gain unauthorized access to protected functionality or
data.
</p>
</overview>
<recommendation>
<include src="recommendation.inc.qhelp" />
</recommendation>
<example>
<include src="example.inc.qhelp" />
</example>
<references>
</references>
<include src="ConditionalBypass.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,62 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Most JavaScript objects inherit the properties of the built-in <code>Object.prototype</code> object.
Prototype pollution is a type of vulnerability in which an attacker is able to modify <code>Object.prototype</code>.
Since most objects inherit from the compromised <code>Object.prototype</code> object, the attacker can use this
to tamper with the application logic, and often escalate to remote code execution or cross-site scripting.
</p>
<p>
One way to cause prototype pollution is by modifying an object obtained via a user-controlled property name.
Most objects have a special <code>__proto__</code> property that refers to <code>Object.prototype</code>.
An attacker can abuse this special property to trick the application into performing unintended modifications
of <code>Object.prototype</code>.
</p>
</overview>
<recommendation>
<p>
Use an associative data structure that is resilient to untrusted key values, such as a <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map">Map</a>.
In some cases, a prototype-less object created with <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create(null)</a>
may be preferable.
</p>
<p>
Alternatively, restrict the computed property name so it can't clash with a built-in property, either by
prefixing it with a constant string, or by rejecting inputs that don't conform to the expected format.
</p>
</recommendation>
<example>
<p>
In the example below, the untrusted value <code>req.params.id</code> is used as the property name
<code>req.session.todos[id]</code>. If a malicious user passes in the ID value <code>__proto__</code>,
the variable <code>todo</code> will then refer to <code>Object.prototype</code>.
Finally, the modification of <code>todo</code> then allows the attacker to inject arbitrary properties
onto <code>Object.prototype</code>.
</p>
<sample src="examples/PrototypePollutingAssignment.js"/>
<p>
One way to fix this is to use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map">Map</a> objects to associate key/value pairs
instead of regular objects, as shown below:
</p>
<sample src="examples/PrototypePollutingAssignmentFixed.js"/>
</example>
<references>
<li>MDN:
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto">Object.prototype.__proto__</a>
</li>
<li>MDN:
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map">Map</a>
</li>
</references>
</qhelp>

Просмотреть файл

@ -2,61 +2,5 @@
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Most JavaScript objects inherit the properties of the built-in <code>Object.prototype</code> object.
Prototype pollution is a type of vulnerability in which an attacker is able to modify <code>Object.prototype</code>.
Since most objects inherit from the compromised <code>Object.prototype</code> object, the attacker can use this
to tamper with the application logic, and often escalate to remote code execution or cross-site scripting.
</p>
<p>
One way to cause prototype pollution is by modifying an object obtained via a user-controlled property name.
Most objects have a special <code>__proto__</code> property that refers to <code>Object.prototype</code>.
An attacker can abuse this special property to trick the application into performing unintended modifications
of <code>Object.prototype</code>.
</p>
</overview>
<recommendation>
<p>
Use an associative data structure that is resilient to untrusted key values, such as a <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map">Map</a>.
In some cases, a prototype-less object created with <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create(null)</a>
may be preferable.
</p>
<p>
Alternatively, restrict the computed property name so it can't clash with a built-in property, either by
prefixing it with a constant string, or by rejecting inputs that don't conform to the expected format.
</p>
</recommendation>
<example>
<p>
In the example below, the untrusted value <code>req.params.id</code> is used as the property name
<code>req.session.todos[id]</code>. If a malicious user passes in the ID value <code>__proto__</code>,
the variable <code>todo</code> will then refer to <code>Object.prototype</code>.
Finally, the modification of <code>todo</code> then allows the attacker to inject arbitrary properties
onto <code>Object.prototype</code>.
</p>
<sample src="examples/PrototypePollutingAssignment.js"/>
<p>
One way to fix this is to use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map">Map</a> objects to associate key/value pairs
instead of regular objects, as shown below:
</p>
<sample src="examples/PrototypePollutingAssignmentFixed.js"/>
</example>
<references>
<li>MDN:
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto">Object.prototype.__proto__</a>
</li>
<li>MDN:
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map">Map</a>
</li>
</references>
<include src="PrototypePollutingAssignment.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="../../../../../../Security/CWE-020/UntrustedDataToExternalAPI.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,22 @@
/**
* @name Untrusted data passed to external API with additional heuristic sources
* @description Data provided remotely is used in this external API without sanitization, which could be a security risk.
* @id js/untrusted-data-to-external-api-more-sources
* @kind path-problem
* @precision low
* @problem.severity error
* @security-severity 7.8
* @tags experimental
* security external/cwe/cwe-20
*/
import javascript
import semmle.javascript.security.dataflow.ExternalAPIUsedWithUntrustedDataQuery
import DataFlow::PathGraph
import semmle.javascript.heuristics.AdditionalSources
from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource
select sink, source, sink,
"Call to " + sink.getNode().(Sink).getApiName() + " with untrusted data from $@.", source,
source.toString()

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="../../../../../../Security/CWE-078/CommandInjection.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,35 @@
/**
* @name Uncontrolled command line with additional heuristic sources
* @description Using externally controlled strings in a command line may allow a malicious
* user to change the meaning of the command.
* @kind path-problem
* @problem.severity error
* @security-severity 9.8
* @precision high
* @id js/command-line-injection-more-sources
* @tags experimental
* correctness
* security
* external/cwe/cwe-078
* external/cwe/cwe-088
*/
import javascript
import semmle.javascript.security.dataflow.CommandInjectionQuery
import DataFlow::PathGraph
import semmle.javascript.heuristics.AdditionalSources
from
Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Node highlight,
Source sourceNode
where
cfg.hasFlowPath(source, sink) and
(
if cfg.isSinkWithHighlight(sink.getNode(), _)
then cfg.isSinkWithHighlight(sink.getNode(), highlight)
else highlight = sink.getNode()
) and
sourceNode = source.getNode() and
source.getNode() instanceof HeuristicSource
select highlight, source, sink, "This command line depends on a $@.", source.getNode(),
"user-provided value"

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="../../../../../../Security/CWE-079/Xss.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,25 @@
/**
* @name Client-side cross-site scripting with additional heuristic sources
* @description Writing user input directly to the DOM allows for
* a cross-site scripting vulnerability.
* @kind path-problem
* @problem.severity error
* @security-severity 6.1
* @precision high
* @id js/xss-more-sources
* @tags experimental
* security
* external/cwe/cwe-079
* external/cwe/cwe-116
*/
import javascript
import semmle.javascript.security.dataflow.DomBasedXssQuery
import DataFlow::PathGraph
import semmle.javascript.heuristics.AdditionalSources
from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource
select sink.getNode(), source, sink,
sink.getNode().(Sink).getVulnerabilityKind() + " vulnerability due to $@.", source.getNode(),
"user-provided value"

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="../../../../../../Security/CWE-089/SqlInjection.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,32 @@
/**
* @name Database query built from user-controlled sources with additional heuristic sources
* @description Building a database query from user-controlled sources is vulnerable to insertion of
* malicious code by the user.
* @kind path-problem
* @problem.severity error
* @security-severity 8.8
* @precision high
* @id js/sql-injection-more-sources
* @tags experimental
* security
* external/cwe/cwe-089
* external/cwe/cwe-090
* external/cwe/cwe-943
*/
import javascript
import semmle.javascript.security.dataflow.SqlInjectionQuery as SqlInjection
import semmle.javascript.security.dataflow.NosqlInjectionQuery as NosqlInjection
import DataFlow::PathGraph
import semmle.javascript.heuristics.AdditionalSources
from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where
(
cfg instanceof SqlInjection::Configuration or
cfg instanceof NosqlInjection::Configuration
) and
cfg.hasFlowPath(source, sink) and
source.getNode() instanceof HeuristicSource
select sink.getNode(), source, sink, "This query depends on a $@.", source.getNode(),
"user-provided value"

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="../../../../../../Security/CWE-094/CodeInjection.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,26 @@
/**
* @name Code injection with additional heuristic sources
* @description Interpreting unsanitized user input as code allows a malicious user arbitrary
* code execution.
* @kind path-problem
* @problem.severity error
* @security-severity 9.3
* @precision high
* @id js/code-injection-more-sources
* @tags experimental
* security
* external/cwe/cwe-094
* external/cwe/cwe-095
* external/cwe/cwe-079
* external/cwe/cwe-116
*/
import javascript
import semmle.javascript.security.dataflow.CodeInjectionQuery
import DataFlow::PathGraph
import semmle.javascript.heuristics.AdditionalSources
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource
select sink.getNode(), source, sink, sink.getNode().(Sink).getMessagePrefix() + " depends on a $@.",
source.getNode(), "user-provided value"

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="../../../../../../Security/CWE-117/LogInjection.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,23 @@
/**
* @name Log injection with additional heuristic sources
* @description Building log entries from user-controlled sources is vulnerable to
* insertion of forged log entries by a malicious user.
* @kind path-problem
* @problem.severity error
* @security-severity 7.8
* @precision medium
* @id js/log-injection-more-sources
* @tags experimental
* security
* external/cwe/cwe-117
*/
import javascript
import DataFlow::PathGraph
import semmle.javascript.security.dataflow.LogInjectionQuery
import semmle.javascript.heuristics.AdditionalSources
from LogInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource
select sink.getNode(), source, sink, "Log entry depends on a $@.", source.getNode(),
"user-provided value"

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="../../../../../../Security/CWE-134/TaintedFormatString.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,22 @@
/**
* @name Use of externally-controlled format string with additional heuristic sources
* @description Using external input in format strings can lead to garbled output.
* @kind path-problem
* @problem.severity warning
* @security-severity 7.3
* @precision high
* @id js/tainted-format-string-more-sources
* @tags experimental
* security
* external/cwe/cwe-134
*/
import javascript
import semmle.javascript.security.dataflow.TaintedFormatStringQuery
import DataFlow::PathGraph
import semmle.javascript.heuristics.AdditionalSources
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource
select sink.getNode(), source, sink, "Format string depends on a $@.", source.getNode(),
"user-provided value"

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="../../../../../../Security/CWE-346/CorsMisconfigurationForCredentials.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,25 @@
/**
* @name CORS misconfiguration for credentials transfer with additional heuristic sources
* @description Misconfiguration of CORS HTTP headers allows for leaks of secret credentials.
* @kind path-problem
* @problem.severity error
* @security-severity 7.5
* @precision high
* @id js/cors-misconfiguration-for-credentials-more-sources
* @tags experimental
* security
* external/cwe/cwe-346
* external/cwe/cwe-639
* external/cwe/cwe-942
*/
import javascript
import semmle.javascript.security.dataflow.CorsMisconfigurationForCredentialsQuery
import DataFlow::PathGraph
import semmle.javascript.heuristics.AdditionalSources
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource
select sink.getNode(), source, sink, "$@ leak vulnerability due to a $@.",
sink.getNode().(Sink).getCredentialsHeader(), "Credential", source.getNode(),
"misconfigured CORS header value"

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="../../../../../../Security/CWE-400/RemotePropertyInjection.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,24 @@
/**
* @name Remote property injection with additional heuristic sources
* @description Allowing writes to arbitrary properties of an object may lead to
* denial-of-service attacks.
* @kind path-problem
* @problem.severity warning
* @security-severity 7.5
* @precision medium
* @id js/remote-property-injection-more-sources
* @tags experimental
* security
* external/cwe/cwe-250
* external/cwe/cwe-400
*/
import javascript
import semmle.javascript.security.dataflow.RemotePropertyInjectionQuery
import DataFlow::PathGraph
import semmle.javascript.heuristics.AdditionalSources
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource
select sink.getNode(), source, sink, sink.getNode().(Sink).getMessage() + " depends on a $@.",
source.getNode(), "user-provided value"

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="../../../../../../Security/CWE-502/UnsafeDeserialization.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,23 @@
/**
* @name Deserialization of user-controlled data with additional heuristic sources
* @description Deserializing user-controlled data may allow attackers to
* execute arbitrary code.
* @kind path-problem
* @problem.severity warning
* @security-severity 9.8
* @precision high
* @id js/unsafe-deserialization-more-sources
* @tags experimental
* security
* external/cwe/cwe-502
*/
import javascript
import semmle.javascript.security.dataflow.UnsafeDeserializationQuery
import DataFlow::PathGraph
import semmle.javascript.heuristics.AdditionalSources
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource
select sink.getNode(), source, sink, "Unsafe deserialization depends on a $@.", source.getNode(),
"user-provided value"

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="../../../../../../Security/CWE-611/Xxe.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,25 @@
/**
* @name XML external entity expansion with additional heuristic sources
* @description Parsing user input as an XML document with external
* entity expansion is vulnerable to XXE attacks.
* @kind path-problem
* @problem.severity error
* @security-severity 9.1
* @precision high
* @id js/xxe-more-sources
* @tags experimental
* security
* external/cwe/cwe-611
* external/cwe/cwe-827
*/
import javascript
import semmle.javascript.security.dataflow.XxeQuery
import DataFlow::PathGraph
import semmle.javascript.heuristics.AdditionalSources
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource
select sink.getNode(), source, sink,
"XML parsing depends on a $@ without guarding against external entity expansion.",
source.getNode(), "user-provided value"

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="../../../../../../Security/CWE-643/XpathInjection.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,23 @@
/**
* @name XPath injection with additional heuristic sources
* @description Building an XPath expression from user-controlled sources is vulnerable to insertion of
* malicious code by the user.
* @kind path-problem
* @problem.severity error
* @security-severity 9.8
* @precision high
* @id js/xpath-injection-more-sources
* @tags experimental
* security
* external/cwe/cwe-643
*/
import javascript
import semmle.javascript.security.dataflow.XpathInjectionQuery
import DataFlow::PathGraph
import semmle.javascript.heuristics.AdditionalSources
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource
select sink.getNode(), source, sink, "XPath expression depends on a $@.", source.getNode(),
"user-provided value"

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="../../../../../../Security/CWE-730/RegExpInjection.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,25 @@
/**
* @name Regular expression injection with additional heuristic sources
* @description User input should not be used in regular expressions without first being escaped,
* otherwise a malicious user may be able to inject an expression that could require
* exponential time on certain inputs.
* @kind path-problem
* @problem.severity error
* @security-severity 7.5
* @precision high
* @id js/regex-injection-more-sources
* @tags experimental
* security
* external/cwe/cwe-730
* external/cwe/cwe-400
*/
import javascript
import semmle.javascript.security.dataflow.RegExpInjectionQuery
import DataFlow::PathGraph
import semmle.javascript.heuristics.AdditionalSources
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource
select sink.getNode(), source, sink, "This regular expression is constructed from a $@.",
source.getNode(), "user-provided value"

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="../../../../../../Security/CWE-770/ResourceExhaustion.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,24 @@
/**
* @name Resource exhaustion with additional heuristic sources
* @description Allocating objects or timers with user-controlled
* sizes or durations can cause resource exhaustion.
* @kind path-problem
* @problem.severity warning
* @security-severity 7.5
* @id js/resource-exhaustion-more-sources
* @precision high
* @tags experimental
* security
* external/cwe/cwe-400
* external/cwe/cwe-770
*/
import javascript
import DataFlow::PathGraph
import semmle.javascript.security.dataflow.ResourceExhaustionQuery
import semmle.javascript.heuristics.AdditionalSources
from Configuration dataflow, DataFlow::PathNode source, DataFlow::PathNode sink
where dataflow.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource
select sink, source, sink, sink.getNode().(Sink).getProblemDescription() + " from a $@.", source,
"user-provided value"

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="../../../../../../Security/CWE-776/XmlBomb.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,25 @@
/**
* @name XML internal entity expansion with additional heuristic sources
* @description Parsing user input as an XML document with arbitrary internal
* entity expansion is vulnerable to denial-of-service attacks.
* @kind path-problem
* @problem.severity warning
* @security-severity 7.5
* @precision high
* @id js/xml-bomb-more-sources
* @tags experimental
* security
* external/cwe/cwe-776
* external/cwe/cwe-400
*/
import javascript
import semmle.javascript.security.dataflow.XmlBombQuery
import DataFlow::PathGraph
import semmle.javascript.heuristics.AdditionalSources
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource
select sink.getNode(), source, sink,
"XML parsing depends on a $@ without guarding against uncontrolled entity expansion.",
source.getNode(), "user-provided value"

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="../../../../../../Security/CWE-807/ConditionalBypass.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,120 @@
/**
* @name User-controlled bypass of security check with additional heuristic sources
* @description Conditions that the user controls are not suited for making security-related decisions.
* @kind path-problem
* @problem.severity error
* @security-severity 7.8
* @precision medium
* @id js/user-controlled-bypass-more-sources
* @tags experimental
* security
* external/cwe/cwe-807
* external/cwe/cwe-290
*/
import javascript
import semmle.javascript.security.dataflow.ConditionalBypassQuery
import DataFlow::PathGraph
/**
* Holds if the value of `nd` flows into `guard`.
*/
predicate flowsToGuardExpr(DataFlow::Node nd, SensitiveActionGuardConditional guard) {
nd = guard or
flowsToGuardExpr(nd.getASuccessor(), guard)
}
/**
* A comparison that guards a sensitive action, e.g. the comparison in:
* `var ok = x == y; if (ok) login()`.
*/
class SensitiveActionGuardComparison extends Comparison {
SensitiveActionGuardConditional guard;
SensitiveActionGuardComparison() { flowsToGuardExpr(DataFlow::valueNode(this), guard) }
/**
* Gets the guard that uses this comparison.
*/
SensitiveActionGuardConditional getGuard() { result = guard }
}
/**
* An intermediary sink to enable reuse of the taint configuration.
* This sink should not be presented to the client of this query.
*/
class SensitiveActionGuardComparisonOperand extends Sink {
SensitiveActionGuardComparison comparison;
SensitiveActionGuardComparisonOperand() { asExpr() = comparison.getAnOperand() }
override SensitiveAction getAction() { result = comparison.getGuard().getAction() }
}
/**
* Holds if `sink` guards `action`, and `source` taints `sink`.
*
* If flow from `source` taints `sink`, then an attacker can
* control if `action` should be executed or not.
*/
predicate isTaintedGuardForSensitiveAction(
DataFlow::PathNode sink, DataFlow::PathNode source, SensitiveAction action
) {
action = sink.getNode().(Sink).getAction() and
// exclude the intermediary sink
not sink.getNode() instanceof SensitiveActionGuardComparisonOperand and
exists(Configuration cfg |
// ordinary taint tracking to a guard
cfg.hasFlowPath(source, sink)
or
// taint tracking to both operands of a guard comparison
exists(
SensitiveActionGuardComparison cmp, DataFlow::PathNode lSource, DataFlow::PathNode rSource,
DataFlow::PathNode lSink, DataFlow::PathNode rSink
|
sink.getNode() = cmp.getGuard() and
cfg.hasFlowPath(lSource, lSink) and
lSink.getNode() = DataFlow::valueNode(cmp.getLeftOperand()) and
cfg.hasFlowPath(rSource, rSink) and
rSink.getNode() = DataFlow::valueNode(cmp.getRightOperand())
|
source = lSource or
source = rSource
)
)
}
/**
* Holds if `e` effectively guards access to `action` by returning or throwing early.
*
* Example: `if (e) return; action(x)`.
*/
predicate isEarlyAbortGuard(DataFlow::PathNode e, SensitiveAction action) {
exists(IfStmt guard |
// `e` is in the condition of an if-statement ...
e.getNode().(Sink).asExpr().getParentExpr*() = guard.getCondition() and
// ... where the then-branch always throws or returns
exists(Stmt abort |
abort instanceof ThrowStmt or
abort instanceof ReturnStmt
|
abort.nestedIn(guard) and
abort.getBasicBlock().(ReachableBasicBlock).postDominates(guard.getThen().getBasicBlock())
) and
// ... and the else-branch does not exist
not exists(guard.getElse())
|
// ... and `action` is outside the if-statement
not action.asExpr().getEnclosingStmt().nestedIn(guard)
)
}
import semmle.javascript.heuristics.AdditionalSources
from DataFlow::PathNode source, DataFlow::PathNode sink, SensitiveAction action
where
isTaintedGuardForSensitiveAction(sink, source, action) and
not isEarlyAbortGuard(sink, action) and
source.getNode() instanceof HeuristicSource
select sink.getNode(), source, sink, "This condition guards a sensitive $@, but a $@ controls it.",
action, "action", source.getNode(), "user-provided value"

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="../../../../../../Security/CWE-915/PrototypePollutingAssignment.inc.qhelp" />
</qhelp>

Просмотреть файл

@ -0,0 +1,30 @@
/**
* @name Prototype-polluting assignment with additional heuristic sources
* @description Modifying an object obtained via a user-controlled property name may
* lead to accidental mutation of the built-in Object prototype,
* and possibly escalate to remote code execution or cross-site scripting.
* @kind path-problem
* @problem.severity warning
* @security-severity 6.1
* @precision high
* @id js/prototype-polluting-assignment-more-sources
* @tags experimental
* security
* external/cwe/cwe-078
* external/cwe/cwe-079
* external/cwe/cwe-094
* external/cwe/cwe-400
* external/cwe/cwe-471
* external/cwe/cwe-915
*/
import javascript
import semmle.javascript.security.dataflow.PrototypePollutingAssignmentQuery
import DataFlow::PathGraph
import semmle.javascript.heuristics.AdditionalSources
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink) and source.getNode() instanceof HeuristicSource
select sink, source, sink,
"This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@.",
source.getNode(), source.getNode().(Source).describe()