core-components: better URL validation in Link component

Co-authored-by: Fredrik Adelöw <freben@gmail.com>
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2023-02-10 11:27:29 +01:00
parent 92444b3521
commit e81a6e0ab5
3 changed files with 25 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-components': patch
---
Updated Link URL validation to be more strict.
@@ -173,4 +173,13 @@ describe('<Link />', () => {
});
});
});
it('throws an error when attempting to link to script code', () => {
expect(() =>
// eslint-disable-next-line no-script-url
render(wrapInTestApp(<Link to="javascript:alert('hello')">Script</Link>)),
).toThrowErrorMatchingInlineSnapshot(
`"Link component rejected javascript: URL as a security precaution"`,
);
});
});
@@ -55,6 +55,11 @@ const useStyles = makeStyles(
export const isExternalUri = (uri: string) => /^([a-z+.-]+):/.test(uri);
// 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;
export type LinkProps = Omit<MaterialLinkProps, 'to'> &
Omit<RouterLinkProps, 'to'> & {
to: string;
@@ -144,6 +149,12 @@ export const Link = React.forwardRef<any, LinkProps>(
const external = isExternalUri(to);
const newWindow = external && !!/^https?:/.exec(to);
if (scriptProtocolPattern.test(to)) {
throw new Error(
'Link component rejected javascript: URL as a security precaution',
);
}
const handleClick = (event: React.MouseEvent<any, MouseEvent>) => {
onClick?.(event);
if (!noTrack) {