Skip to content

Commit

Permalink
Backport xss fix for the 2023-07 release (#1844)
Browse files Browse the repository at this point in the history
  • Loading branch information
blittle authored Mar 12, 2024
1 parent 891c12b commit 7a642a5
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/clever-pans-tap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/hydrogen': patch
---

Fix XSS vulnerability
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions packages/hydrogen/src/seo/escape.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// This is taken from remix: https://github.com/remix-run/remix/blob/main/packages/remix-server-runtime/markup.ts

const ESCAPE_LOOKUP: {[match: string]: string} = {
'&': '\\u0026',
'>': '\\u003e',
'<': '\\u003c',
'\u2028': '\\u2028',
'\u2029': '\\u2029',
};

const ESCAPE_REGEX = /[&><\u2028\u2029]/g;

export function escapeHtml(html: string) {
return html.replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]);
}
5 changes: 4 additions & 1 deletion packages/hydrogen/src/seo/generate-seo-tags.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {ComponentPropsWithoutRef} from 'react';
import type {Maybe} from '@shopify/hydrogen-react/storefront-api-types';
import type {Thing, WithContext} from 'schema-dts';
import {escapeHtml} from './escape';

const ERROR_PREFIX = 'Error in SEO input: ';

Expand Down Expand Up @@ -500,7 +501,9 @@ export function generateSeoTags<
'script',
{
type: 'application/ld+json',
children: JSON.stringify(block),
children: JSON.stringify(block, (k, value) => {
return typeof value === 'string' ? escapeHtml(value) : value;
}),
},
// @ts-expect-error
`json-ld-${block?.['@type'] || block?.name || index++}`,
Expand Down
29 changes: 29 additions & 0 deletions packages/hydrogen/src/seo/seo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,35 @@ describe('seo', () => {
</DocumentFragment>
`);
});

it('escapes script content', async () => {
vi.mocked(useMatches).mockReturnValueOnce([
fillMatch({
data: {
seo: {
jsonLd: {
'@context': 'https://schema.org',
'@type': 'Organization',
name: 'Hydrogen Root',
description: '</script><script>alert("hacked")</script>',
},
},
},
}),
]);

const {asFragment} = render(createElement(Seo));

expect(asFragment()).toMatchInlineSnapshot(`
<DocumentFragment>
<script
type="application/ld+json"
>
{"@context":"https://schema.org","@type":"Organization","name":"Hydrogen Root","description":"\\\\u003c/script\\\\u003e\\\\u003cscript\\\\u003ealert(\\"hacked\\")\\\\u003c/script\\\\u003e"}
</script>
</DocumentFragment>
`);
});
});

function fillMatch(partial: Partial<RouteMatch> = {}) {
Expand Down

0 comments on commit 7a642a5

Please sign in to comment.