-
Notifications
You must be signed in to change notification settings - Fork 1.9k
JS: add new prototype pollution query and reorganize #4778
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
ef52c46
JS: Add spread step in TaintedObject
asgerf 972c4d6
JS: Add PrototypePollutingAssignment
asgerf 877b4b0
JS: Move and rename other prototype pollution queries
asgerf 25161ed
JS: Move all prototype pollution queries to CWE-915
asgerf ca38a1c
JS: Update CWE tags
asgerf e42ca88
JS: Update security suite after move to CWE-915
asgerf 544b3d9
JS: Change note
asgerf 479dcf5
JS: Update to use more inclusive language
asgerf 0a7513f
JS: Move and rename test cases as well
asgerf daab3c1
JS: Add tests and fix some bugs
asgerf e10a22e
JS: Restrict size of some predicates
asgerf f132b4a
JS: Add type confusion sink for prototype pollution checks
asgerf fe86465
JS: Refactor store/load flow a bit
asgerf 1b0bec9
JS: Remove magic from barrier guard predicates
asgerf 355cfaa
JS: Autoformat
asgerf 0496642
JS: Add test for captured flow into callback
asgerf 254ac7f
JS: Fix TypeofCheck
asgerf f96c425
JS: Deny -> block
asgerf 04f51be
JS: Add missing qldoc
asgerf fd293d0
JS: Address doc review
asgerf ed729a1
Apply suggestions from code review
asgerf File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| lgtm,codescanning | ||
| * We've improved the detection of prototype pollution, and the queries involved have been reorganized: | ||
| * A new query "Prototype-polluting assignment" (`js/prototype-polluting-assignment`) has been added. This query | ||
| highlights direct modifications of an object obtained via a user-controlled property name, which may accidentally alter `Object.prototype`. | ||
| * The query previously named "Prototype pollution" (`js/prototype-pollution`) has been renamed to "Prototype-polluting merge call". | ||
| This highlights indirect modification of `Object.prototype` via an unsafe `merge` call taking a user-controlled object as argument. | ||
| * The query previously named "Prototype pollution in utility function" (`js/prototype-pollution-utility`) has been renamed to "Prototype-polluting function". | ||
| This query highlights the implementation of an unsafe `merge` function, to ensure a robust API is exposed downstream. | ||
| * The above queries have been moved to the Security/CWE-915 folder, and assigned the following tags: CWE-078, CWE-079, CWE-094, CWE-400, and CWE-915. | ||
| * The query "Type confusion through parameter tampering" (`js/type-confusion-through-parameter-tampering`) now highlights | ||
| ineffective prototype pollution checks that can be bypassed by type confusion. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
javascript/ql/src/Security/CWE-915/PrototypePollutingAssignment.qhelp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
26 changes: 26 additions & 0 deletions
26
javascript/ql/src/Security/CWE-915/PrototypePollutingAssignment.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| /** | ||
| * @name Prototype-polluting assignment | ||
| * @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 | ||
| * @precision high | ||
| * @id js/prototype-polluting-assignment | ||
| * @tags security | ||
| * external/cwe/cwe-078 | ||
mchammer01 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| * external/cwe/cwe-079 | ||
| * external/cwe/cwe-094 | ||
| * external/cwe/cwe-400 | ||
| * external/cwe/cwe-915 | ||
| */ | ||
|
|
||
| import javascript | ||
| import semmle.javascript.security.dataflow.PrototypePollutingAssignment::PrototypePollutingAssignment | ||
| import DataFlow::PathGraph | ||
|
|
||
| from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink | ||
| where cfg.hasFlowPath(source, sink) | ||
| select sink, source, sink, | ||
| "This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@.", | ||
| source.getNode(), "here" | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 7 additions & 3 deletions
10
...rc/Security/CWE-400/PrototypePollution.ql → ...ty/CWE-915/PrototypePollutingMergeCall.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
javascript/ql/src/Security/CWE-915/examples/PrototypePollutingAssignment.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| let express = require('express'); | ||
|
|
||
| express.put('/todos/:id', (req, res) => { | ||
| let id = req.params.id; | ||
| let items = req.session.todos[id]; | ||
| if (!items) { | ||
| items = req.session.todos[id] = {}; | ||
| } | ||
| items[req.query.name] = req.query.text; | ||
| res.end(200); | ||
| }); |
12 changes: 12 additions & 0 deletions
12
javascript/ql/src/Security/CWE-915/examples/PrototypePollutingAssignmentFixed.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| let express = require('express'); | ||
|
|
||
| express.put('/todos/:id', (req, res) => { | ||
| let id = req.params.id; | ||
| let items = req.session.todos.get(id); | ||
| if (!items) { | ||
| items = new Map(); | ||
| req.sessions.todos.set(id, items); | ||
| } | ||
| items.set(req.query.name, req.query.text); | ||
| res.end(200); | ||
| }); |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.