Skip to content

Commit 061ce91

Browse files
authored
Add IRI Validation for externalReference URL (#1140)
* Adding IRI validation/filtering Signed-off-by: Tim Messing <[email protected]> * Run linting Signed-off-by: Tim Messing <[email protected]> * Add debug logging for failed IRI that fail validation Signed-off-by: Tim Messing <[email protected]> --------- Signed-off-by: Tim Messing <[email protected]>
1 parent e34cfc1 commit 061ce91

File tree

8 files changed

+73
-6
lines changed

8 files changed

+73
-6
lines changed

index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import {
6666
getSwiftPackageMetadata,
6767
getTimestamp,
6868
includeMavenTestScope,
69+
isValidIriReference,
6970
parseBazelActionGraph,
7071
parseBazelSkyframe,
7172
parseBdistMetadata,
@@ -726,7 +727,9 @@ function addExternalReferences(opkg) {
726727
}
727728
}
728729
}
729-
return externalReferences;
730+
return externalReferences
731+
.map((reference) => ({ ...reference, url: reference.url.trim() }))
732+
.filter((reference) => isValidIriReference(reference.url));
730733
}
731734

732735
/**

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@
9191
"tar": "^6.2.1",
9292
"uuid": "^9.0.1",
9393
"xml-js": "^1.6.11",
94-
"yargs": "^17.7.2"
94+
"yargs": "^17.7.2",
95+
"validate-iri": "^1.0.1"
9596
},
9697
"optionalDependencies": {
9798
"@appthreat/atom": "2.0.12",

pnpm-lock.yaml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

types/index.d.ts.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

types/utils.d.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,6 +1119,18 @@ export function addEvidenceForDotnet(pkgList: any, slicesFile: any): any;
11191119
* @returns {Object} pkgFilesMap Object with package name and list of files
11201120
*/
11211121
export function parseMakeDFile(dfile: string): any;
1122+
/**
1123+
* Function to validate an externalReference URL for conforming to the JSON schema or bomLink
1124+
* https://github.com/CycloneDX/cyclonedx-core-java/blob/75575318b268dda9e2a290761d7db11b4f414255/src/main/resources/bom-1.5.schema.json#L1140
1125+
* https://datatracker.ietf.org/doc/html/rfc3987#section-2.2
1126+
* https://cyclonedx.org/capabilities/bomlink/
1127+
*
1128+
* @param {String} iri IRI to validate
1129+
*
1130+
* @returns {Boolean} Flag indicating whether the supplied URL is valid or not
1131+
*
1132+
*/
1133+
export function isValidIriReference(iri: string): boolean;
11221134
export const dirNameStr: string;
11231135
export const isWin: boolean;
11241136
export const isMac: boolean;

types/utils.d.ts.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

utils.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import {
4646
satisfies,
4747
valid,
4848
} from "semver";
49+
import { IriValidationStrategy, validateIri } from "validate-iri";
4950
import { xml2js } from "xml-js";
5051
import { getTreeWithPlugin } from "./piptree.js";
5152

@@ -10593,3 +10594,27 @@ export function parseMakeDFile(dfile) {
1059310594
pkgFilesMap[pkgName] = Array.from(filesList);
1059410595
return pkgFilesMap;
1059510596
}
10597+
10598+
/**
10599+
* Function to validate an externalReference URL for conforming to the JSON schema or bomLink
10600+
* https://github.com/CycloneDX/cyclonedx-core-java/blob/75575318b268dda9e2a290761d7db11b4f414255/src/main/resources/bom-1.5.schema.json#L1140
10601+
* https://datatracker.ietf.org/doc/html/rfc3987#section-2.2
10602+
* https://cyclonedx.org/capabilities/bomlink/
10603+
*
10604+
* @param {String} iri IRI to validate
10605+
*
10606+
* @returns {Boolean} Flag indicating whether the supplied URL is valid or not
10607+
*
10608+
*/
10609+
export function isValidIriReference(iri) {
10610+
const result = validateIri(iri, IriValidationStrategy.Strict);
10611+
10612+
if (result instanceof Error) {
10613+
if (DEBUG_MODE) {
10614+
console.log(`IRI failed validation ${iri}`);
10615+
}
10616+
return false;
10617+
}
10618+
10619+
return true;
10620+
}

utils.test.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
getNugetMetadata,
1414
getPyMetadata,
1515
guessPypiMatchingVersion,
16+
isValidIriReference,
1617
parseBazelActionGraph,
1718
parseBazelBuild,
1819
parseBazelSkyframe,
@@ -2658,8 +2659,8 @@ test("parsePnpmLock", async () => {
26582659
},
26592660
});
26602661
parsedList = await parsePnpmLock("./pnpm-lock.yaml");
2661-
expect(parsedList.pkgList.length).toEqual(643);
2662-
expect(parsedList.dependenciesList.length).toEqual(643);
2662+
expect(parsedList.pkgList.length).toEqual(644);
2663+
expect(parsedList.dependenciesList.length).toEqual(644);
26632664
expect(parsedList.pkgList[0]).toEqual({
26642665
group: "@ampproject",
26652666
name: "remapping",
@@ -4066,3 +4067,20 @@ test("parseMakeDFile tests", () => {
40664067
],
40674068
});
40684069
});
4070+
4071+
test.each([
4072+
["", false],
4073+
["[email protected]:behat-chrome/chrome-mink-driver.git", false],
4074+
[" [email protected]:behat-chrome/chrome-mink-driver.git ", false],
4075+
["${repository.url}", false],
4076+
// bomLink - https://cyclonedx.org/capabilities/bomlink/]
4077+
["urn:cdx:f08a6ccd-4dce-4759-bd84-c626675d60a7/1#componentA", true],
4078+
// http uri - https://www.ietf.org/rfc/rfc7230.txt]
4079+
["https://gitlab.com/behat-chrome/chrome-mink-driver.git", true],
4080+
[" https://gitlab.com/behat-chrome/chrome-mink-driver.git ", false],
4081+
["http://gitlab.com/behat-chrome/chrome-mink-driver.git", true],
4082+
["git+https://github.com/Alex-D/check-disk-space.git", true],
4083+
["UNKNOWN", false],
4084+
])("isValidIriReference tests: %s", (url, isValid) => {
4085+
expect(isValidIriReference(url)).toBe(isValid);
4086+
});

0 commit comments

Comments
 (0)