Add unique CVE ID field to Vulnerability - #125
Conversation
pombredanne
left a comment
There was a problem hiding this comment.
@haikoschol Thank you ++
See my comments inline ... all are mostly small nitpickings.
| vulnerability=vulnerability, | ||
| reference_id=data.get('vulnerability_id', ''), | ||
| vulnerability, _ = Vulnerability.objects.get_or_create( | ||
| cve_id=data['cve_id'], |
There was a problem hiding this comment.
What if there is no cve_id in the data? will this crash? And in this case we would likely still want to create a new Vulnerability?
There was a problem hiding this comment.
This is for the Debian import, where it doesn't look like there will be any entries without CVE ID. At least not in the feed we are currently consuming. The CVE ID is used as a dictionary key:
{
"librsync": {
"CVE-2014-8242": {
"scope": "remote",
"debianbug": 776246,
"description": "librsync before 1.0.0 uses a truncated MD4 checksum to match blocks",
[...]
| PackageReference.objects.create( | ||
| package=package_affected, | ||
| repository=f'https://security.archlinux.org/package/{package_name}', | ||
| version=avg['affected'], |
There was a problem hiding this comment.
Is affected always a single version?
There was a problem hiding this comment.
It was a string in all the records I looked at so I'm pretty sure, but haven't tried to verify it any further.
In general I think it's not really a problem if the import crashes due to unexpected schemas. In fact, I'd argue we want it to crash as soon as possible instead of writing lots of empty values into the database due to overly defensive code.
We just need to make sure to be notified about any crashes that happen in cron jobs and such.
| """ | ||
| Seperate list of Affected version and fixed version from all version | ||
| using the range specified | ||
| Seperate list of affected versions and fixed versions from all version |
There was a problem hiding this comment.
nitpicking: Separate list of affected versions and fixed versions from all versions
There was a problem hiding this comment.
Also unrelated, could it make sense to adopt "affect/fixed" rather "impacted/resolved" ? is this a better wording and more explicit?
There was a problem hiding this comment.
I think either is fine. We should make sure to be consistent in the data we store, API responses, documentation, etc. but I'm fine sticking with impacted/resolved. If you are in favor of affected/fixed we should change it now though, since this PR already resets migrations.
| using the ranges specified | ||
| """ | ||
|
|
||
| # FIXME This skips unfixed vulnerabilities |
There was a problem hiding this comment.
Good catch... this warrants a ticket
There was a problem hiding this comment.
Right. I meant to create one for it but apparently forgot. :-/ Done that now: #126
| vuln = result['vulnerabilities'][0] | ||
| self.assertEqual(1, len(vuln['references'])) | ||
| self.assertEqual('CVE-2012-3386', vuln['references'][0]['reference_id']) | ||
| self.assertEqual(0, len(vuln['references'])) |
There was a problem hiding this comment.
Note: if we decide to use pytest and its dnajo extension, we could start using plain asserts everywhere.
There was a problem hiding this comment.
Right, I had that thought as well. Wrote it down in a ticket now: #127
| self.assertTrue(VulnerabilityReference.objects.get(reference_id='CVE-2009-1382')) | ||
| self.assertTrue(VulnerabilityReference.objects.get(reference_id='CVE-2009-2459')) | ||
| self.assertTrue(VulnerabilityReference.objects.get(reference_id='CVE-2014-8242')) | ||
| self.assertEqual(0, VulnerabilityReference.objects.count()) |
There was a problem hiding this comment.
Is this right? or needed at all? I just realize that the previous code was making assumptions about data across tests.
There was a problem hiding this comment.
It is correct, although it's not ideal for the test, that for this data no vulnerability references are created any more. :)
I'm not sure what you mean with "assumptions about data across tests" though. The way the tests work now with setUpTestData() is that the data is loaded once and then used for assertions in all test methods. Since all of the tests are read-only, it should not make a difference in outcome while being a bit more efficient. Should be easy to switch to plain setUp()/tearDown() though if necessary.
This test is for the debian import and since this PR is for an issue about Arch, I wanted to keep the changes minimal. But I just checked and Debian has pages for CVEs just like Arch, so we could add those as vulnerability references.
There was a problem hiding this comment.
Should be easy to switch to plain setUp()/tearDown() though if necessary.
My point there was I personally find that the use of setUp()/tearDown() and similar to be confusing and making the tests less readable and less "unit" by bringing in some global state . But that's minor and nothing to fix just now.
| self.assertEqual(1, len(impacted_pkgs)) | ||
| self.assertEqual('librsync', impacted_pkg.package.name) | ||
| self.assertEqual('0.9.7-10', impacted_pkg.package.version) | ||
| self.assertEqual(1, impacted_pkgs.count()) |
There was a problem hiding this comment.
I am always puzzled by tests that make assertions about things done in the setup or elsewhere... this was not your making, but if we could find a way to have tests that are really unit and do not depend on each other and on global setup() that would be better IMHO... what's your take? @tdruez ping too
There was a problem hiding this comment.
I might actually have changed that in an earlier PR from having the import called in every test, which was tedious to change. If we use pytest we also have the option to write tests as simple functions instead of classes. If we do that I would still prefer to reuse setup code where it makes sense, either by calling a setup function in the test or using pytest decorators. Maybe that way it is more explicit?
| Check that no package references were found in the test data | ||
| """ | ||
| self.assertEqual(8, PackageReference.objects.count()) | ||
| self.assertEqual(0, PackageReference.objects.count()) |
There was a problem hiding this comment.
What is the purpose of this test?
There was a problem hiding this comment.
We had a discussion on the chat a while ago about the purpose of PackageReference after we added the PURL mixin. I don't think any decisions/tickets came out of it, but until we decide what to do with it, this just checks that the ArchLinux import does not currently create any package references. For example we might eventually ask ourselves "What are we using PackageReference for?" this will answer it for Arch.
|
|
||
| from django.test import TestCase | ||
| from vulnerabilities.scraper.npm import remove_spaces, get_all_version, extract_data | ||
| from vulnerabilities.scraper.npm import remove_spaces, get_all_versions, extract_data |
There was a problem hiding this comment.
I personally prefer having each import on its own line.
Also separate imports in four sorted group with an empty line between each: future import, standard lib, thirdparty, own modules. Would this work for you too?
794f733 to
9312d26
Compare
This change adds the field cve_id to the Vulnerability model and based on that, improves the data import for Arch Linux. The improvements made have been discussed in issue aboutcode-org#20: - For each CVE in a given AVG, exactly one Vulnerability is stored - For each CVE, one VulnerabilityReference to its page on security.archlinux.org is stored - Each ASA mentioned in an AVG is stored as a VulnerabilityReference Since there is no production deployment of vulnerablecode yet, I took the opportunity of changing the models to remove all migrations and create a new one that creates the whole schema. Since the cve_id field on Vulnerability has a unique constraint set, I needed to make some changes to the import code that belong to issue aboutcode-org#28. I kept them minimal however so aboutcode-org#28 is still open and needs to be addressed later. closes aboutcode-org#20 Signed-off-by: Haiko Schol <hs@haikoschol.com>
9312d26 to
5c9493d
Compare
pombredanne
left a comment
There was a problem hiding this comment.
Thanks for all the replies. Merging !
This change adds the field cve_id to the Vulnerability model and based
on that, improves the data import for Arch Linux.
The improvements made have been discussed in issue #20:
For each CVE in a given AVG, exactly one Vulnerability is stored
For each CVE, one VulnerabilityReference to its page on
security.archlinux.org is stored
Each ASA mentioned in an AVG is stored as a VulnerabilityReference
Since there is no production deployment of vulnerablecode yet, I took
the opportunity of changing the models to remove all migrations and
create a new one that creates the whole schema.
Since the cve_id field on Vulnerability has a unique constraint set, I
needed to make some changes to the import code that belong to issue #28.
I kept them minimal however so #28 is still open and needs to be
addressed later.
closes #20
Signed-off-by: Haiko Schol hs@haikoschol.com