Skip to content

Conversation

@erik-krogh
Copy link
Contributor

Fixes an FP that was found while looking into CVE-2020-7781.

@erik-krogh erik-krogh requested a review from a team as a code owner December 21, 2020 13:17
@github-actions github-actions bot added the JS label Dec 21, 2020
Copy link
Contributor

@esbena esbena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea seems fine, I have a few suggestions.

* A check of the form `type x === "X"`, where x is "number", or "boolean",
* which sanitized `x` in its "then" branch.
*/
class TypeOfSanitizer extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(It could be useful to have this as a public class in TaintTracking.qll, perhaps configurable. UnsafeJQueryPluginCustomizations could also use it in its treatment of typeof guards.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out we have a lot of places with a typeof guard.
I made a TaintTracking::isTypeofGuard predicate, and used that throughout our project.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great initiative. Lets wait proper performance evaluation of that change then.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 202 to 204
exists(StringLiteral str, TypeofExpr typeof | astNode.hasOperands(str, typeof) |
str.getValue() = ["number", "boolean"] and // "undefined" is already handled in TaintTracking.qll
typeof.getOperand() = x
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A slightly more general and robust formulation is found here:

exists(Expr op1, Expr op2 | test.hasOperands(op1, op2) |
read.asExpr() = op1.(TypeofExpr).getOperand() and
op2.mayHaveStringValue(any(InferredType t | t = TTUndefined()).getTypeofTag())
)

erik-krogh and others added 2 commits December 22, 2020 08:37
…ellCommandConstructionCustomizations.qll

Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
str.getValue() = ["number", "boolean"] and // "undefined" is already handled in TaintTracking.qll
exists(Expr str, TypeofExpr typeof | astNode.hasOperands(str, typeof) |
str.mayHaveStringValue(any(InferredType t |
t = TTUndefined() or t = TTNumber() or t = TTBoolean()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TTUndefined causes this to be out of sync with the qldoc above - I will let you decide on the solution.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it from the list.
TaintTracking::TypeOfUndefinedSanitizer takes care of that case.

@esbena esbena added the Awaiting evaluation Do not merge yet, this PR is waiting for an evaluation to finish label Dec 22, 2020
@esbena
Copy link
Contributor

esbena commented Dec 22, 2020

Minor: the many string constants that f7f8868 motivates seem a bit dangerous, the stringiness of TypeofTag does not allow the type system to detect mistakes such as "array" or "Object"..
(but the InferredType has other problems since it has types that are meaningless for typeof, so either is probably fine)

@erik-krogh
Copy link
Contributor Author

Minor: the many string constants that f7f8868 motivates seem a bit dangerous, the stringiness of TypeofTag does not allow the type system to detect mistakes such as "array" or "Object"..
(but the InferredType has other problems since it has types that are meaningless for typeof, so either is probably fine)

I want to keep the string constants.
My first attempt used InferredType, but that caused some unit-tests to fail, so I want to avoid anyone else making the same mistake.

@erik-krogh erik-krogh removed the Awaiting evaluation Do not merge yet, this PR is waiting for an evaluation to finish label Jan 6, 2021
@erik-krogh
Copy link
Contributor Author

Looks fine https://git.semmle.com/erik/dist-compare-reports/tree/eriks-profile-machine_1608843110557
(Also posted as a comment further up).

@codeql-ci codeql-ci merged commit 9d4cd0a into github:main Jan 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants