catalog-model: improve location reference validation

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Co-authored-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
Patrik Oldsberg
2023-02-11 10:54:25 +01:00
parent 5637ebed92
commit aece6c57d2
3 changed files with 31 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/catalog-model': patch
---
Add additional validation for location references.
@@ -50,6 +50,9 @@ describe('parseLocationRef', () => {
expect(() => parseLocationRef('https://bleh')).toThrow(
"Invalid location ref 'https://bleh', please prefix it with 'url:', e.g. 'url:https://bleh'",
);
expect(() => parseLocationRef('url:javascript:alert()')).toThrow(
"Invalid location ref 'url:javascript:alert()', target is a javascript: URL",
);
});
});
@@ -70,6 +73,12 @@ describe('stringifyLocationRef', () => {
expect(() => stringifyLocationRef({ type: 'hello', target: '' })).toThrow(
'Unable to stringify location ref, empty target',
);
expect(() =>
// eslint-disable-next-line no-script-url
stringifyLocationRef({ type: 'url', target: 'javascript:alert()' }),
).toThrow(
"Invalid location ref 'url:javascript:alert()', target is a javascript: URL",
);
});
});
@@ -17,6 +17,11 @@
import { Entity, stringifyEntityRef } from '../entity';
import { ANNOTATION_LOCATION, ANNOTATION_SOURCE_LOCATION } from './annotation';
// See https://github.com/facebook/react/blob/f0cf832e1d0c8544c36aa8b310960885a11a847c/packages/react-dom-bindings/src/shared/sanitizeURL.js
const scriptProtocolPattern =
// eslint-disable-next-line no-control-regex
/^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i;
/**
* Parses a string form location reference.
*
@@ -56,6 +61,12 @@ export function parseLocationRef(ref: string): {
);
}
if (scriptProtocolPattern.test(target)) {
throw new TypeError(
`Invalid location ref '${ref}', target is a javascript: URL`,
);
}
return { type, target };
}
@@ -78,6 +89,12 @@ export function stringifyLocationRef(ref: {
throw new TypeError(`Unable to stringify location ref, empty target`);
}
if (scriptProtocolPattern.test(target)) {
throw new TypeError(
`Invalid location ref '${type}:${target}', target is a javascript: URL`,
);
}
return `${type}:${target}`;
}