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:
@@ -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}`;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user