diff --git a/ts/package-lock.json b/ts/package-lock.json index 713a62f4f..00d637262 100644 --- a/ts/package-lock.json +++ b/ts/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "Apache-2.0", "dependencies": { + "ip-regex": "^5.0.0", "memoizee": "^0.4.17", "psl": "^1.15.0", "structured-headers": "^2.0.1", @@ -2173,6 +2174,17 @@ "node": ">=10.13.0" } }, + "node_modules/ip-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-5.0.0.tgz", + "integrity": "sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", diff --git a/ts/package.json b/ts/package.json index 71bb40785..862d45b20 100644 --- a/ts/package.json +++ b/ts/package.json @@ -16,6 +16,7 @@ "author": "", "license": "Apache-2.0", "dependencies": { + "ip-regex": "^5.0.0", "memoizee": "^0.4.17", "psl": "^1.15.0", "structured-headers": "^2.0.1", diff --git a/ts/src/header-validator/source.test.ts b/ts/src/header-validator/source.test.ts index bc0144d0c..330da4298 100644 --- a/ts/src/header-validator/source.test.ts +++ b/ts/src/header-validator/source.test.ts @@ -28,7 +28,7 @@ const testCases: TestCase[] = [ "aggregation_keys": {"a": "0xf"}, "debug_key": "1", "debug_reporting": true, - "destination": "https://a.test", + "destination": ["https://a.test", "https://1.2.3.4"], "destination_limit_priority": "1", "event_report_window": "3601", "expiry": "86400", @@ -61,7 +61,7 @@ const testCases: TestCase[] = [ aggregationKeys: new Map([['a', 15n]]), debugKey: 1n, debugReporting: true, - destination: new Set(['https://a.test']), + destination: new Set(['https://a.test', 'https://1.2.3.4']), destinationLimitPriority: 1n, eventLevelEpsilon: 14, expiry: 86400, @@ -116,7 +116,7 @@ const testCases: TestCase[] = [ }, { name: 'destination-url-components', - input: `{"destination": ["https://a.test/b?c=d#e", "https://x.Y.test", "https://sub.A.test/z"]}`, + input: `{"destination": ["https://a.test/b?c=d#e", "https://x.Y.test", "https://sub.A.test/z", "https://1.2.3.4/5"]}`, expectedWarnings: [ { path: ['destination', 0], @@ -134,6 +134,10 @@ const testCases: TestCase[] = [ path: ['destination', 2], msg: 'duplicate value https://a.test', }, + { + msg: 'URL components other than site (https://1.2.3.4) will be ignored', + path: ['destination', 3], + }, ], }, diff --git a/ts/src/header-validator/validate.ts b/ts/src/header-validator/validate.ts index d728e86d3..1359eba01 100644 --- a/ts/src/header-validator/validate.ts +++ b/ts/src/header-validator/validate.ts @@ -1,3 +1,4 @@ +import ipRegex from 'ip-regex' import * as psl from 'psl' import { Context, PathComponent } from './context' import { Maybe } from './maybe' @@ -376,6 +377,9 @@ export function suitableOrigin(s: string, ctx: Context): Maybe { export function suitableSite(s: string, ctx: Context): Maybe { return suitableScope(s, ctx, 'site', (u) => { + if (ipRegex({ exact: true }).test(u.hostname)) { + return `${u.protocol}//${u.hostname}` + } let site = psl.get(u.hostname) if (site === null) { ctx.warning(