Skip to content

Conversation

asger-semmle
Copy link
Contributor

@asger-semmle asger-semmle commented Jan 9, 2019

This adds the classes StringOps::StartsWith, StringOps::EndsWith, and StringOps::Includes for recognizing calls to the corresponding methods and ad-hoc implementations of these.

The former two are needed for some improvements to the tainted path query. I don't have an immediately use for the endsWith variant, but it's just there for the sake of completeness.

There are a few nags to this approach:

  • Some of these recognize calls to array methods as well, since indexOf and includes are also array methods.
  • Some expressions are one-sided tests, in that they imply containment in one direction, but not the other. For example, A.indexOf(B) > 1 implies that A.includes(B), but the false outcome does not imply !A.includes(B). The current implementation is conservative in this regard and only recognizes instances that are truly equivalent to startsWith/includes/endsWith.
  • For the above reason, EndsWith is hard to implement. For example, A.substr(-B.length) === B is almost a correct endsWith check, except it returns false if B is empty. Some security queries might still want to treat it as an alias for A.endsWith(B), though.

One day we might want to generalise this to reason about one-sided tests and "nearly correct" tests, but it might just turn into a time sink. For now, this is at least sufficient for the tainted path query improvements I'm working on.

I'm running an evaluation of all security queries due to change to sanitizers.

@asger-semmle asger-semmle requested a review from a team as a code owner January 9, 2019 10:41
@asger-semmle asger-semmle added the JS label Jan 9, 2019
@asger-semmle
Copy link
Contributor Author

Evaluation. I'll look into the performance of node and a few others.

Copy link

@xiemaisi xiemaisi left a comment

Choose a reason for hiding this comment

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

LGTM, modulo minor typos and evaluation.

@asger-semmle
Copy link
Contributor Author

After another evaluation, perf looks good.

@xiemaisi
Copy link

Conflicts.

@asger-semmle
Copy link
Contributor Author

This should be ready to go.

@asger-semmle
Copy link
Contributor Author

Looks like my rebasing eliminated the inline fixes from the review. Should be fixed now.

Copy link

@xiemaisi xiemaisi left a comment

Choose a reason for hiding this comment

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

Two more minor documentation niggles, otherwise lgtm.

/**
* Gets the polarity if the check.
*
* If the polarity is `false` the check returns `true` if the string does not start

Choose a reason for hiding this comment

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

s/start/end/


/**
* An expression that appears to be part of an `endsWith`-check, that is,
* roughly equivalent to `A.endsWith(B)` or `!A.endsWith(B)`.

Choose a reason for hiding this comment

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

What does "roughly" mean here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, good catch. I wrote this before I decided to exclude expressions that aren't strictly equivalent to endsWith, such as A.substr(-B.length) === B. I've updated the comment.

@semmle-qlci semmle-qlci merged commit d8947a7 into github:master Jan 25, 2019
cklin pushed a commit that referenced this pull request May 20, 2022
Add change note announcing generics support
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