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:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user