-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
340 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# OSV | ||
|
||
OSV stand for <kbd>Open Source Vulnerability</kbd> database. This project is an open, precise, and distributed approach to producing and consuming vulnerability information for open source. | ||
|
||
All advisories in this database use the [OpenSSF OSV format](https://ossf.github.io/osv-schema/), which was developed in collaboration with open source communities. | ||
|
||
Lean more at [osv.dev](https://osv.dev/) | ||
|
||
## Format | ||
|
||
The OSV interface is exported as root like `StandardVulnerability`. | ||
|
||
```ts | ||
export interface OSV { | ||
schema_version: string; | ||
id: string; | ||
modified: string; | ||
published: string; | ||
withdraw: string; | ||
aliases: string[]; | ||
related: string[]; | ||
summary: string; | ||
details: string; | ||
severity: OSVSeverity[]; | ||
affected: OSVAffected[]; | ||
references: { | ||
type: OSVReferenceType; | ||
url: string; | ||
}[]; | ||
credits: { | ||
name: string; | ||
contact: string[]; | ||
type: OSVCreditType; | ||
}[]; | ||
database_specific: Record<string, any>; | ||
} | ||
``` | ||
|
||
## API | ||
|
||
### findOne(parameters: OSVApiParameter): Promise< OSV[] > | ||
Find the vulnerabilities of a given package using available OSV API parameters. | ||
|
||
```ts | ||
export type OSVApiParameter = { | ||
version?: string; | ||
package: { | ||
name: string; | ||
/** | ||
* @default npm | ||
*/ | ||
ecosystem?: string; | ||
}; | ||
} | ||
``` | ||
### findOneBySpec(spec: string): Promise< OSV[] > | ||
Find the vulnerabilities of a given package using the NPM spec format like `packageName@version`. | ||
```ts | ||
import * as vulnera from "@nodesecure/vulnera"; | ||
|
||
const vulns = await vulnera.Database.osv.findOneBySpec( | ||
"01template1" | ||
); | ||
console.log(vulns); | ||
``` | ||
|
||
### findMany< T extends string >(specs: T[]): Promise< Record< T, OSV[] > > | ||
Find the vulnerabilities of many packages using the spec format. | ||
|
||
Return a Record where keys are equals to the provided specs. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * as osv from "./osv.js"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Import Third-Party Dependencies | ||
import * as httpie from "@myunisoft/httpie"; | ||
|
||
// Import Internal Dependencies | ||
import { OSV } from "../formats/osv"; | ||
import * as utils from "../utils.js"; | ||
|
||
// CONSTANTS | ||
export const ROOT_API = "https://api.osv.dev"; | ||
|
||
export type OSVApiParameter = { | ||
version?: string; | ||
package: { | ||
name: string; | ||
/** | ||
* @default npm | ||
*/ | ||
ecosystem?: string; | ||
}; | ||
} | ||
|
||
export async function findOne( | ||
parameters: OSVApiParameter | ||
): Promise<OSV[]> { | ||
if (!parameters.package.ecosystem) { | ||
parameters.package.ecosystem = "npm"; | ||
} | ||
|
||
const { data } = await httpie.post<{ vulns: OSV[] }>( | ||
new URL("v1/query", ROOT_API), | ||
{ | ||
body: parameters | ||
} | ||
); | ||
|
||
return data.vulns; | ||
} | ||
|
||
export function findOneBySpec( | ||
spec: string | ||
) { | ||
const { name, version } = utils.parseNpmSpec(spec); | ||
|
||
return findOne({ | ||
version, | ||
package: { | ||
name | ||
} | ||
}); | ||
} | ||
|
||
export async function findMany<T extends string = string>( | ||
specs: T[] | ||
): Promise<Record<T, OSV[]>> { | ||
const packagesVulns = await Promise.all( | ||
specs.map(async(spec) => { | ||
return { | ||
[spec]: await findOneBySpec(spec) | ||
}; | ||
}) | ||
); | ||
|
||
// @ts-ignore | ||
return Object.assign(...packagesVulns); | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
|
||
/** | ||
* @see https://ossf.github.io/osv-schema/ | ||
*/ | ||
export interface OSV { | ||
schema_version: string; | ||
id: string; | ||
modified: string; | ||
published: string; | ||
withdraw: string; | ||
aliases: string[]; | ||
related: string[]; | ||
summary: string; | ||
details: string; | ||
severity: OSVSeverity[]; | ||
affected: OSVAffected[]; | ||
references: { | ||
type: OSVReferenceType; | ||
url: string; | ||
}[]; | ||
credits: { | ||
name: string; | ||
contact: string[]; | ||
type: OSVCreditType; | ||
}[]; | ||
database_specific: Record<string, any>; | ||
} | ||
|
||
export type OSVReferenceType = "ADVISORY" | | ||
"ARTICLE" | | ||
"DETECTION" | | ||
"DISCUSSION" | | ||
"REPORT" | | ||
"FIX" | | ||
"GIT" | | ||
"INTRODUCED" | | ||
"PACKAGE" | | ||
"EVIDENCE" | | ||
"WEB"; | ||
|
||
export type OSVCreditType = "FINDER" | | ||
"REPORTER" | | ||
"ANALYST" | | ||
"COORDINATOR" | | ||
"REMEDIATION_DEVELOPER" | | ||
"REMEDIATION_REVIEWER" | | ||
"REMEDIATION_VERIFIER" | | ||
"TOOL" | | ||
"SPONSOR" | | ||
"OTHER"; | ||
|
||
export interface OSVAffected { | ||
package: { | ||
ecosystem: "npm", | ||
name: string; | ||
purl: string; | ||
}; | ||
severity: OSVSeverity[]; | ||
ranges: OSVRange[]; | ||
versions: string[]; | ||
ecosystem_specific: Record<string, any>; | ||
database_specific: Record<string, any>; | ||
} | ||
|
||
export interface OSVRange { | ||
type: string; | ||
repo: string; | ||
events: { | ||
introduced?: string; | ||
fixed?: string; | ||
last_affected?: string; | ||
limit?: string; | ||
}[]; | ||
database_specific: Record<string, any>; | ||
} | ||
|
||
export interface OSVSeverity { | ||
type: string; | ||
score: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// Import Node.js Dependencies | ||
import { describe, test, after } from "node:test"; | ||
import assert from "node:assert"; | ||
|
||
// Import Internal Dependencies | ||
import { | ||
kHttpClientHeaders, | ||
setupHttpAgentMock | ||
} from "../strategies/utils"; | ||
import { osv } from "../../src/database/index"; | ||
|
||
describe("osv", () => { | ||
const [mockedHttpAgent, restoreHttpAgent] = setupHttpAgentMock(); | ||
const mockedHttpClient = mockedHttpAgent.get(osv.ROOT_API); | ||
|
||
after(() => { | ||
restoreHttpAgent(); | ||
}); | ||
|
||
test(`should send a POST http request to the OSV API using findOne | ||
and then return the 'vulns' property from the JSON response`, async() => { | ||
const expectedResponse = { vulns: "hello world" }; | ||
mockedHttpClient | ||
.intercept({ | ||
path: new URL("/v1/query", osv.ROOT_API).href, | ||
method: "POST", | ||
body: JSON.stringify({ package: { name: "foobar", ecosystem: "npm" } }) | ||
}) | ||
.reply(200, expectedResponse, kHttpClientHeaders); | ||
|
||
const vulns = await osv.findOne({ | ||
package: { | ||
name: "foobar", | ||
ecosystem: "npm" | ||
} | ||
}); | ||
assert.strictEqual(vulns, expectedResponse.vulns); | ||
}); | ||
|
||
test(`should send a POST http request to the OSV API using findOneBySpec | ||
and then return the 'vulns' property from the JSON response`, async() => { | ||
const expectedResponse = { vulns: "hello world" }; | ||
const packageName = "@nodesecure/js-x-ray"; | ||
|
||
mockedHttpClient | ||
.intercept({ | ||
path: new URL("/v1/query", osv.ROOT_API).href, | ||
method: "POST", | ||
body: JSON.stringify({ | ||
version: "2.0.0", | ||
package: { name: packageName, ecosystem: "npm" } | ||
}) | ||
}) | ||
.reply(200, expectedResponse, kHttpClientHeaders); | ||
|
||
const vulns = await osv.findOneBySpec(`${packageName}@2.0.0`); | ||
assert.strictEqual(vulns, expectedResponse.vulns); | ||
}); | ||
|
||
test(`should send multiple POST http requests to the OSV API using findMany`, async() => { | ||
const expectedResponse = { vulns: [1, 2, 3] }; | ||
|
||
mockedHttpClient | ||
.intercept({ | ||
path: new URL("/v1/query", osv.ROOT_API).href, | ||
method: "POST" | ||
}) | ||
.reply(200, expectedResponse, kHttpClientHeaders) | ||
.times(2); | ||
|
||
const result = await osv.findMany( | ||
["foobar", "yoobar"] | ||
); | ||
assert.deepEqual(result, { | ||
foobar: expectedResponse.vulns, | ||
yoobar: expectedResponse.vulns | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters