Skip to content

Commit f8f7ef3

Browse files
authored
Merge pull request #543 from GetStream/fix/CRS-276-improve-attachment-sanitization
[CRS-276] Sanitize URL image sources in Image component
2 parents 70c9a1e + df5a8aa commit f8f7ef3

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

src/components/Gallery/Image.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React from 'react';
33
import PropTypes from 'prop-types';
44

55
import ModalWrapper from './ModalWrapper';
6+
import { sanitizeUrl } from '@braintree/sanitize-url';
67

78
/**
89
* Image - Small wrapper around an image tag, supports thumbnails
@@ -32,13 +33,14 @@ class Image extends React.PureComponent {
3233

3334
render() {
3435
const { image_url, thumb_url, fallback } = this.props;
35-
const formattedArray = [{ src: image_url || thumb_url }];
36+
const imageSrc = sanitizeUrl(image_url || thumb_url);
37+
const formattedArray = [{ src: imageSrc }];
3638
return (
3739
<React.Fragment>
3840
<img
3941
className="str-chat__message-attachment--img"
4042
onClick={this.toggleModal}
41-
src={thumb_url || image_url}
43+
src={imageSrc}
4244
alt={fallback}
4345
data-testid="image-test"
4446
/>

src/components/Gallery/__tests__/Image.test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,37 @@ describe('Image', () => {
1717
expect(tree).toMatchSnapshot();
1818
});
1919

20+
describe('it should prevent unsafe image uri protocols in the rendered image src', () => {
21+
it('should prevent javascript protocol in image src', () => {
22+
// eslint-disable-next-line no-script-url
23+
const xssJavascriptUri = 'javascript:alert("p0wn3d")';
24+
const { getByTestId } = render(<Image image_url={xssJavascriptUri} />);
25+
expect(getByTestId('image-test')).not.toHaveAttribute(
26+
'src',
27+
xssJavascriptUri,
28+
);
29+
});
30+
it('should prevent javascript protocol in thumbnail src', () => {
31+
// eslint-disable-next-line no-script-url
32+
const xssJavascriptUri = 'javascript:alert("p0wn3d")';
33+
const { getByTestId } = render(<Image thumb_url={xssJavascriptUri} />);
34+
expect(getByTestId('image-test')).not.toHaveAttribute(
35+
'src',
36+
xssJavascriptUri,
37+
);
38+
});
39+
it('should prevent dataUris in image src', () => {
40+
const xssDataUri = 'data:image/svg+xml;base64,DANGEROUSENCODEDSVG';
41+
const { getByTestId } = render(<Image image_url={xssDataUri} />);
42+
expect(getByTestId('image-test')).not.toHaveAttribute('src', xssDataUri);
43+
});
44+
it('should prevent dataUris in thumb src', () => {
45+
const xssDataUri = 'data:image/svg+xml;base64,DANGEROUSENCODEDSVG';
46+
const { getByTestId } = render(<Image thumb_url={xssDataUri} />);
47+
expect(getByTestId('image-test')).not.toHaveAttribute('src', xssDataUri);
48+
});
49+
});
50+
2051
it('should open modal on image click', async () => {
2152
jest.spyOn(console, 'warn').mockImplementation(() => null);
2253
const { getByTestId, getByTitle } = render(

src/components/Gallery/__tests__/__snapshots__/Image.test.js.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ exports[`Image should render component with default props 1`] = `
55
className="str-chat__message-attachment--img"
66
data-testid="image-test"
77
onClick={[Function]}
8+
src="about:blank"
89
/>
910
`;

0 commit comments

Comments
 (0)