-
Notifications
You must be signed in to change notification settings - Fork 521
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
Alpine secdb should only be used to remove matches, never to add matches #970
Comments
Developer notes: On the surface, it looks like we could rewrite the func (m *Matcher) findApkPackage(store vulnerability.Provider, d *distro.Distro, p pkg.Package) ([]match.Match, error) {
return m.cpeMatchesWithoutSecDBFixes(store, d, p)
} |
@westonsteimel and I were discussing this a little further this morning, and I'm starting to think that both approaches are valid depending on the users risk tolerance. That is, the proposed change to not use the secdb to add matches to the results is textbook-wise correct, however, matching against NVD is notoriously error prone too... which may lead to higher FNs, which may be more sensitive over the raised FPs from this approach. I'm starting to think that the matcher should allow for either strategy:
This could be controlled with a new Additionally we could augment the output to show in the table view which matches came directly from secDB and annotate a hint on a lower confidence about those results. (maybe even add a I think this biggest question about this approach is what should be the default posture? I'm leaning towards the second matching strategy (what's originally being proposed), but I have a couple of questions:
One more note for anyone picking this up (CC @spiffcs ): we have a lot of labels already for alpine that will probably need to be redone. |
Hey! Here's how I would suggest thinking about this: First, I think "what's best today" might differ from "what's best down the road". Especially for the Wolfi part of your questioning, I can say authoritatively that our approach to providing security data is going to diverge from Alpine's, and in the not-too-distant future. In fact, just yesterday we cutover our secdb from being produced from "secfixes" to the newer "advisory data". As we've discussed, I believe that with the Wolfi security data evolution will come more reasons to trust the data as a (potentially sole) means of detecting vulnerabilities within Wolfi packages. The recommendation for how to use Wolfi data in the future (which would include using as a first-class means of discovering vulns) would be significantly different from the recommendation on how to use the Alpine-style secdb, which is purely subtractive according to the Alpine security team. For today, I'd advise following the Alpine team's guidance for Alpine, and for Wolfi/Chainguard matching as well. This means "strategy 2", which the distros involved here agree is the correct behavior. @spiffcs can correct me if I'm wrong about the following — but IIRC, when we discovered the unexpected matches from the additive approach, the findings were all FPs. That makes intuitive sense to me. I get the motivation of defending against FNs at all costs, but it might actually be a phantom problem here. If you're seeing evidence of FNs in Alpine resulting from "strategy 2", it'd be good to explore those here. But until then, it could be that the only difference between the correct matching approach and the modified matching approach is an addition of FPs. (But of course the data would show if FNs are a concern here.) |
Hey @willmurphyscode! I think my previous comment is still correct. And I just replied on #1318. Also happy to set up a time to chat, on this and other related enhancements. Would love to meet you! Feel free to DM me on the Anchore community Slack or something. 😃 |
I want to re-raise this:
Let me take an example from the PR: GHSA-vpvm-3wq2-2wvm (CVE-2023-27561 against runc). The NVD data has the following information (as of today):
(vunnel output of NVD results from today, Cct 28 2023){
"schema": "https://raw.githubusercontent.com/anchore/vunnel/main/schema/vulnerability/nvd/schema-1.0.0.json",
"identifier": "2023/cve-2023-27561",
"item": {
"cve": {
"id": "CVE-2023-27561",
"sourceIdentifier": "[email protected]",
"published": "2023-03-03T19:15:11.330",
"lastModified": "2023-08-16T03:15:26.440",
"vulnStatus": "Modified",
"descriptions": [
{
"lang": "en",
"value": "runc through 1.1.4 has Incorrect Access Control leading to Escalation of Privileges, related to libcontainer/rootfs_linux.go. To exploit this, an attacker must be able to spawn two containers with custom volume-mount configurations, and be able to run custom images. NOTE: this issue exists because of a CVE-2019-19921 regression."
}
],
"metrics": {
"cvssMetricV31": [
{
... snip ...
}
]
},
"weaknesses": [
{
"source": "[email protected]",
"type": "Primary",
"description": [
{
"lang": "en",
"value": "CWE-706"
}
]
}
],
"configurations": [
{
"nodes": [
{
"operator": "OR",
"negate": false,
"cpeMatch": [
{
"vulnerable": true,
"criteria": "cpe:2.3:a:linuxfoundation:runc:*:*:*:*:*:*:*:*",
"versionEndExcluding": "1.1.5",
"matchCriteriaId": "AE0C5D34-F78A-4993-AC70-25A6606FC82B"
}
]
}
]
},
{
"nodes": [
{
"operator": "OR",
"negate": false,
"cpeMatch": [
{
"vulnerable": true,
"criteria": "cpe:2.3:a:redhat:openshift_container_platform:4.0:*:*:*:*:*:*:*",
"matchCriteriaId": "932D137F-528B-4526-9A89-CD59FA1AB0FE"
},
{
"vulnerable": true,
"criteria": "cpe:2.3:o:redhat:enterprise_linux:8.0:*:*:*:*:*:*:*",
"matchCriteriaId": "F4CFF558-3C47-480D-A2F0-BABF26042943"
},
{
"vulnerable": true,
"criteria": "cpe:2.3:o:redhat:enterprise_linux:9.0:*:*:*:*:*:*:*",
"matchCriteriaId": "7F6FB57C-2BC7-487C-96DD-132683AEB35D"
}
]
}
]
},
{
"nodes": [
{
"operator": "OR",
"negate": false,
"cpeMatch": [
{
"vulnerable": true,
"criteria": "cpe:2.3:o:debian:debian_linux:10.0:*:*:*:*:*:*:*",
"matchCriteriaId": "07B237A9-69A3-4A9C-9DA0-4E06BD37AE73"
}
]
}
]
}
],
"references": [
... snip ...
]
}
}
} Let's focus just on
(grype db entries for CVE-2023-27561 relating to alpine)
(secfixes comments at v3.17.5)
Still focusing on
If we use the NVD data ( Let's extend this example into a hypothetical: assume that the patch for That would mean that the "correct" vulnerable range of releases are:
It's true, that we cannot infer the correct ranges from the secdb entries. What we'd do today is: This is just one dimension of the problem. There is an equally important problem to consider: can we accurately craft an CPE for all APKs in the alpine ecosystem for matching against NVD? Assuming the Take for example the CVE-2023-27561 we've been talking through above:
There is nothing in the APK record or binary to indicate that the linuxfoundation is a possible vendor.Take the
The best candidate is the The go module is
Nor even in the binary directly:
We have a growing set of manually-crafted mappings for |
Let's look at another example, (syft json snippet){
...
"cpes": [
"cpe:2.3:a:advancecomp:advancecomp:2.5-r1:*:*:*:*:*:*:*"
],
"purl": "pkg:apk/alpine/[email protected]?arch=aarch64&distro=alpine-3.18.4",
"metadataType": "ApkMetadata",
"metadata": {
"package": "advancecomp",
"originPackage": "advancecomp",
"maintainer": "TBK <[email protected]>",
"version": "2.5-r1",
"architecture": "aarch64",
"url": "https://www.advancemame.it/",
"description": "A collection of recompression utilities for your .ZIP archives, .PNG snapshots, .MNG video clips and .GZ files",
"size": 471494,
"installedSize": 1077248,
"pullDependencies": [
"so:libc.musl-aarch64.so.1",
"so:libgcc_s.so.1",
"so:libstdc++.so.6",
"so:libz.so.1"
],
...
} There is a chance of pulling it from the URL, but this is not a dependable method in many cases. (grype-db entries for advancecomp)
In this case we would not be able to reliably match against NVD (given we cannot find the right vendor), so it would be a FN. |
Taking a look at From a "which versions are patched vs not" point of view this is a great example; patched in:
(secfix comments from main branch)
(grype-db entries for alpine 3.12)
This one is interesting in the sense that we might be able to pick up that the version is date-ish, but we don't have that capability today. If we were able to pick up on that then we could put together a better range of Say we were able to match against the NVD record via CPE, the version story isn't promising: all versions are vulnerable. |
Looking at (secfixes comments on alpine)From the APKBUILD file for alpine 3.18.4:
(grype-db entries)
The CPE that Syft can surmise is (NVD node configuration from vunnel output)...
"configurations": [
{
"nodes": [
{
"operator": "OR",
"negate": false,
"cpeMatch": [
{
"vulnerable": true,
"criteria": "cpe:2.3:a:jenkins:jenkins:*:*:*:*:lts:*:*:*",
"versionEndIncluding": "2.319.1",
"matchCriteriaId": "ADE588E8-C485-4BA1-BBF6-50DC4B8C86BC"
},
{
"vulnerable": true,
"criteria": "cpe:2.3:a:jenkins:jenkins:*:*:*:*:-:*:*:*",
"versionEndIncluding": "2.329",
"matchCriteriaId": "08A2ED7E-D17B-4A19-BB96-CB2AD13039BF"
}
]
}
]
},
{
"nodes": [
{
"operator": "OR",
"negate": false,
"cpeMatch": [
{
"vulnerable": true,
"criteria": "cpe:2.3:a:oracle:communications_cloud_native_core_automated_test_suite:1.9.0:*:*:*:*:*:*:*",
"matchCriteriaId": "A4CA84D6-F312-4C29-A02B-050FCB7A902B"
}
]
}
]
}
],
... Given the multiple overlapping ranges from both data sources, I'll simplify it to this:
Today we are not considering the I could see an issue if there were alpine packagings for |
I think the next step for this issue is an update to existing alpine
This will help us get a more holistic picture of if this proposal is better or not. |
If the bar being set here is "all", my guess is you won't achieve this. It's also helpful to remember that not all packages have assigned CPEs in the first place.
These CPEs don't look specific to Alpine or to the APK ecosystem to me. Alpine, like other distros, is packaging some well known software, and that software itself has CPEs. But, I do think tracking down these CPEs is the right direction for Grype, if and only if it's going to continue to use NVD data for distro package matching. Some of this will be necessarily manual, since there's not always a reliable pattern for how CPEs get assigned to software applications. But even so, it's still valuable toward the objective of more accurate matching. My suspicion is relying on Alpine's (and Wolfi's) secdbs as a source of new CVE matches is a less accurate but cheaper alternative to getting the CPE identification in better shape. All this being said — I can't imagine this issue being the fastest path toward more accurate matches in Grype. I appreciate the investigation and hypotheticals. This stuff is really interesting to think about. I think if the Grype team wants to keep the current approach, that's certainly reasonable, and it's a defensible choice. It goes against the guidance of the distros involved, but possibly with a higher accuracy yield in some scenarios, especially without investing more in correct CPE identification. But my unsolicited prioritization input would be to focus on other higher return efforts! 😃 |
While looking into #964, @spiffcs discovered that when Grype started using Alpine's secdb data for edge, Grype began surfacing additional vulnerability matches that hadn't shown up before.
This indicates an incorrect behavior for Grype's existing Alpine matching: Alpine secfixes denote only fixes to packages — never vulnerabilities themselves. The secdb should only ever be used to remove existing matches (i.e. from NVD data) from the final result set.
Here are some examples of correct behavior for illustration:
Match in NVD only
Packages:
zlib
atv1.2.3-r1
NVD:
< v1.4.2
Expected result:
v1.2.3-r1
— CVE XMatch in NVD and Alpine secdb
Packages:
zlib
atv1.2.3-r2
NVD:
< v1.4.2
Secdb:
zlib
:v1.2.3-r2
fixes CVE XExpected result:
Match in Alpine secdb only
Packages:
zlib
atv1.2.3-r0
Secdb:
zlib
:v1.3.3-r0
fixes CVE XExpected result:
The text was updated successfully, but these errors were encountered: