Closed JamieMagee closed 4 months ago
Thanks for filing this @JamieMagee! Apologies for the delay on responding to this.
Sketching through what this might look like if were to encode this in the OSV schema, perhaps one simple way to do this is (using a fictional example based on log4j):
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "log4j:log4j"
},
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "1.2.0"
},
{
"fixed": "2.1.0",
"in_package": "org.apache.logging.log4j:log4j-core"
}
]
}
]
},
in_package
(or some better worded variant) would be only applicable to fixed
events, and override the package name.
It doesn't seem to make sense to also encode ecosystem
here, because it's unlikely a fix that happens in a different package in a different ecosystem is actionable.
The other question here would be whether if this made sense to be part of the OSV schema. For the log4j case, it seems to make sense because the fix for a vulnerability is to upgrade to a new major version (where the package name happens to be different).
On the other hand, it's unclear if this information (associating different package names that form part of the same logical package) belongs in security advisories. Perhaps a better ecosystem-supported solution is needed for this?
For example, what if there was a v3 of log4j where the package name was once again different (say org.apache.logging.log4j:log4j-core-v3
), and there were more vulns in v2? An automated tool to perform upgrades on someone using v1 would only know about the path from v1 -> v2 -> v3 if there are advisories that encode this information for the entire path. It seems like a bit of an indirect way to achieve this.
I think an event is the right level to encode this sort of information, and ecosystem information isn't important. But there may be the possibility that there are multiple upgrade paths, if there are multiple forks.
As for whether or not it belongs in OSV, I think you could make the case that this sort of information would be useful for non-security purposes. I opened https://github.com/npm/rfcs/issues/766 to see how receptive npm would be to adding this sort of structured data.
To your final point, about multi-step migrations, I wouldn't be too concerned. I imagine a human doing a manual migration might make the same v1 -> v2 -> v3 upgrade. I agree it's indirect, but it's no worse than a manual process.
(@JamieMagee and I met in person briefly to discuss this!)
One other potential problem with this is that this changes the attack surface of OSV as a database -- with this, database consumers (and feeds) would have to be mindful of potential malicious packages being introduced as the "fixed package".
A malicious actor could find some way to inject a fake advisory somewhere in the OSV ecosystem to get users to upgrade to a malicious package.
It was great to meet up again @oliverchang 😄
I'll close this for now and followup with upstream (npm and NuGet to start with)
Problem Statement
Currently, the OSV schema allows automated tooling, like Dependabot and Renovate, to upgrade vulnerable package versions to non-vulnerable versions. However, it doesn't currently support package migrations.
For example, CVE-2021-4104 affects all versions of
log4j:log4j
AKA log4j v1. The suggested migration path is to migrate toorg.apache.logging.log4j:log4j-core
AKA log4j v2. This is even noted in the details field:But this data is unstructured and doesn't allow automated dependency upgrade tools to act on the vulnerability. As far as they are concerned there is no upgrade path.
Prior Art
Renovate has solved this problem with a community maintained list of replacement packages. Renovate's approach is to upgrade to a specific version of a specific package, usually the first version of the new package, and assumes that users will receive regular upgrades with subsequent Renovate PRs.
In terms of what is accepted into the list, something like an npm deprecation notice, NuGet deprecation notice, or some sort of note in the underlying repository which points to the replacement package is easy. Where it is trickier is when a package is abandoned without any sort of notice. Renovate relies on trusted maintainers, community members, and experts in the specific ecosystem to review these sorts of replacements.
Next steps
I'm looking to get feedback on if support for this sort of structured data is something that might be accepted as part of the OSV schema, and what that structured data might look like.