diff --git a/tests/test_editor_actions_panel_security.py b/tests/test_editor_actions_panel_security.py new file mode 100644 index 000000000..269941964 --- /dev/null +++ b/tests/test_editor_actions_panel_security.py @@ -0,0 +1,50 @@ +import json +from pathlib import Path +import subprocess + + +ROOT = Path(__file__).resolve().parents[1] + + +def test_action_names_and_unknown_steps_are_literal_text(): + script = r''' + const fs = require('fs'); + const { chromium } = require('playwright'); + (async () => { + const browser = await chromium.launch({ headless: true }); + try { + const page = await browser.newPage(); + await page.route('http://actions.test/**', route => route.fulfill({ + status: 200, contentType: 'text/html', body: '', + })); + await page.goto('http://actions.test/'); + const source = fs.readFileSync(process.argv[1], 'utf8'); + const moduleUrl = 'data:text/javascript;base64,' + Buffer.from(source).toString('base64'); + const result = await page.evaluate(async url => { + const attack = ''; + localStorage.setItem('ge-actions', JSON.stringify({ [attack]: ['flip-h'] })); + const { createActionsPanel } = await import(url); + const panel = createActionsPanel(); + document.body.append(panel.element); + panel.setSteps([attack]); + return { + images: panel.element.querySelectorAll('img').length, + saved: panel.element.querySelector('.ge-actions-saved-row button').textContent, + step: panel.element.querySelector('.ge-actions-step-label').textContent, + executed: Boolean(window.__actionsXss), + attack, + }; + }, moduleUrl); + console.log(JSON.stringify(result)); + } finally { await browser.close(); } + })().catch(error => { console.error(error); process.exit(1); }); + ''' + result = subprocess.run( + ['node', '-e', script, str(ROOT / 'static/js/editor/actions-panel.js')], + cwd=ROOT, capture_output=True, text=True, timeout=30, + ) + assert result.returncode == 0, result.stderr + observed = json.loads(result.stdout) + assert observed['images'] == 0 + assert observed['saved'] == observed['step'] == observed['attack'] + assert not observed['executed']