Skip to content
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

tests(snyk): assert upper bounds #9308

Merged
merged 9 commits into from
Jul 20, 2019
Merged

tests(snyk): assert upper bounds #9308

merged 9 commits into from
Jul 20, 2019

Conversation

connorjclark
Copy link
Collaborator

see #8409 (comment)

Since we ship to places we can't necessarily quickly update (e.g. DevTools), I wonder if we should have a LH test that fails if the database has * or >=X, and require it be corrected to <= some hardcoded version (presumably the latest available release), even if that version is still vulnerable.

The theory would be: if a new, still vulnerable version of the library comes out after that LH release, then it's better to have a false negative (given that there's no fix available anyways and there are other sources (github, npm, greenkeeper, etc) that will warn folks) than it is to have up to 12 weeks of a false positive (if a new, non-vulnerable version comes out) which would annoy folks and encourage them to ignore Lighthouse's warnings in the future.

Should <=X be added to the end of every semver.vulnerable, where X = the latest release within that major version?

@patrickhulce
Copy link
Collaborator

Yeah I think we need to be stronger than no * to satisfy this, maybe nothing * and no unqualified >, i.e. all < or explicit ranges

@connorjclark
Copy link
Collaborator Author

We'll need a process for anything more than just no * please. need to augment the semvers that don't have an upper bound.

When snyk does its updating (the PR it auto-magically opens), is there a way for us to hook into it and make our changes on top?

@brendankenny
Copy link
Member

Yes, there's a script in our repo they run to trim it down, would be a good place for this.

@connorjclark
Copy link
Collaborator Author

{"id":"npm:moment:20170905","severity":"low","semver":{"vulnerable":["<2.19.3"]}}
{"id":"npm:knockout:20130701","severity":"medium","semver":{"vulnerable":["<3.0.0 >=2.1.0-pre"]}}
{"id":"npm:jquery:20150627","severity":"medium","semver":{"vulnerable":["<1.12.2",">=1.12.3 <2.2.2",">=2.2.3 <3.0.0"]}},

Every entry has an upper bound - good.


{"id":"npm:dojo:20100614","severity":"high","semver":{"vulnerable":[">=0.4 <0.4.4 || >=1.0 <1.0.3 || >=1.1 <1.1.2 || >=1.2 <1.2.4 || >=1.3 <1.3.3 || >=1.4 <1.4.2"]}},

is a hard one to grok (and luckily each clause is already given an upperbound)


I actually thought there would be some entries with no upperbound, but I didn't see any. So let's just add the assertion that there isn't one, and address it if it ever gets triggered.

@connorjclark connorjclark changed the title deps(snyk): do not allow * in semver deps(snyk): assert upper bounds Jun 28, 2019
@connorjclark connorjclark changed the title deps(snyk): assert upper bounds tests(snyk): assert upper bounds Jun 28, 2019
Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

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

LGTM


const clauses = semver.split('||');
for (const clause of clauses) {
if (!clause.trim().startsWith('=') && !clause.includes('<')) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

maybe give a few examples here for easier parsing? I had to go checkout the snapshot to see why it's includes('<') but .trim().startsWith('=')

Copy link
Member

Choose a reason for hiding this comment

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

I had to go checkout the snapshot to see why it's includes('<') but .trim().startsWith('=')

hmm, I still don't understand why that's the case :).

Isn't something like '=5.0 >=10' valid with no upper bound? But it wouldn't fail this check. Or '<5.0 >=10'? Maybe I just don't understand what we're checking here :)

Copy link
Collaborator

Choose a reason for hiding this comment

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

well those aren't real ranges :)

I suppose it's a meta question of if we should be checking to see that they're valid ranges at all

Copy link
Member

Choose a reason for hiding this comment

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

well those aren't real ranges :)

why aren't they? Isn't '=5.0 >=10' just saying 5.x or anything over 10 is vulnerable?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

well those aren't real ranges :)

this

valid ranges at all

doesn't make sense to validate snyk like that imo

Copy link
Collaborator

@patrickhulce patrickhulce Jul 9, 2019

Choose a reason for hiding this comment

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

a space is an AND

OR is either || or a separate entry in the vulnerable array

so while it might technically be valid, nothing will ever satisfy the range '=5 >=10'

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

semver package's validRange just verifies the string conforms to the grammar defined here: https://github.com/npm/node-semver/blob/ce6190e2b681700dcc5d7309fe8eda99941f712d/range.bnf not that the range is satisfiable.

Copy link
Member

Choose a reason for hiding this comment

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

so while it might technically be valid, nothing will ever satisfy the range '=5 >=10'

Ah, I see your point, but it could also be '=11 >= 10'. I assume most of these are auto generated, so it doesn't seem out of the realm of possibility. See my other comment for one possibility rather than getting clever and hoping these ranges always make sense :)

Copy link
Member

Choose a reason for hiding this comment

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

Ah, I see your point, but it could also be '=11 >= 10'

oh, no, wait, that's wrong. So I'll have to fall back to hand waving about invalid ranges :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

doesn't make sense to validate snyk like that imo

didnt realize how easy it'd be to use semver to validate the ranges, sooo nvm. it's done indirectly with this test now.


const clauses = semver.split('||');
for (const clause of clauses) {
if (!clause.trim().startsWith('=') && !clause.includes('<')) {
Copy link
Member

Choose a reason for hiding this comment

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

I had to go checkout the snapshot to see why it's includes('<') but .trim().startsWith('=')

hmm, I still don't understand why that's the case :).

Isn't something like '=5.0 >=10' valid with no upper bound? But it wouldn't fail this check. Or '<5.0 >=10'? Maybe I just don't understand what we're checking here :)

…s-test.js

Co-Authored-By: Brendan Kenny <bckenny@gmail.com>
@googlebot
Copy link

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and have the pull request author add another comment and the bot will run again. If the bot doesn't comment, it means it doesn't think anything has changed.

ℹ️ Googlers: Go here for more info.

@googlebot
Copy link

A Googler has manually verified that the CLAs look good.

(Googler, please make sure the reason for overriding the CLA status is clearly documented in these comments.)

ℹ️ Googlers: Go here for more info.

@brendankenny
Copy link
Member

I guess one question would be do we strictly require an upper bound? If there's an earlier valid version, should that be sufficient?

If not, and we want to stick with requiring an upper bound, we could just use semver for this instead and do something like if (!semver.gtr('gazillions.0.0', snykRange')) assert.false(...).

@brendankenny
Copy link
Member

we could just use semver for this instead and do something like if (!semver.gtr('gazillions.0.0', snykRange)) assert.false(...).

@connorjclark points out they use Number.MAX_SAFE_INTEGER, so it could be semver.gtr(`${Number.MAX_SAFE_INTEGER}.0.0`, snykRange) :)

@brendankenny
Copy link
Member

brendankenny commented Jul 9, 2019

(I was hoping for Math.floor(Number.MAX_VALUE) :)

@connorjclark
Copy link
Collaborator Author

connorjclark commented Jul 9, 2019

npm/node-semver#166 (comment)

kind of like what I was doing, but normalizes the ranges w/ new semver.Range first. for example, this translates <4.1 || =5.0 into <4.1.0||>=5.0.0 <5.1.0. range.sets would have [<4.1.0] and [>=5.0.0, <5.1.0]

@googlebot
Copy link

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and have the pull request author add another comment and the bot will run again. If the bot doesn't comment, it means it doesn't think anything has changed.

ℹ️ Googlers: Go here for more info.

@googlebot googlebot added cla: no and removed cla: yes labels Jul 9, 2019
@vercel vercel bot temporarily deployed to staging July 9, 2019 01:04 Inactive
@googlebot
Copy link

A Googler has manually verified that the CLAs look good.

(Googler, please make sure the reason for overriding the CLA status is clearly documented in these comments.)

ℹ️ Googlers: Go here for more info.

// Upperbound exists if...

// < or <= is in one of the subset's clauses (= gets normalized to >= and <).
if (subset.some(comparator => comparator.operator.match(/^</))) {
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure this entirely works. A rangeString of '*' ends up throwing here, for instance.

We have an untested homegrown solution vs a tested (by semver) but ugly gtr solution...

Copy link
Collaborator

Choose a reason for hiding this comment

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

A rangeString of '*' ends up throwing here, for instance.

Isn't that kinda desired behavior? :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm not sure this entirely works. A rangeString of '*' ends up throwing here, for instance.

Fixed.

We have an untested homegrown solution vs a tested (by semver) but ugly gtr solution...

Added tests.

return true;
}

describe('every snyk vulnerability has an upper bound', () => {
Copy link
Member

Choose a reason for hiding this comment

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

needs an it() or changed to it and nested in a describe() above, otherwise on failures you end up with

Screen Shot 2019-07-10 at 11 52 18

@googlebot
Copy link

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and have the pull request author add another comment and the bot will run again. If the bot doesn't comment, it means it doesn't think anything has changed.

ℹ️ Googlers: Go here for more info.

@googlebot
Copy link

A Googler has manually verified that the CLAs look good.

(Googler, please make sure the reason for overriding the CLA status is clearly documented in these comments.)

ℹ️ Googlers: Go here for more info.

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

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

this is a net positive, even if about 27 lines longer than my really good gazillions idea :)

let's land

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.

4 participants