fix: escape scenario id when serialising saved page
PostTeamEditor interpolated the scenario id into a <script> block as
'localStorage.setItem("scenario:<id>", ...)', so an id containing
'</script><script>...</script>' would break out of the JS-string context
and execute in the browser. Use json_encode with JSON_HEX_TAG / HEX_AMP /
HEX_APOS / HEX_QUOT so the id is always a safe JS string literal.
Adds a PostTeamEditorTest case that submits '</script><script>alert(1)</script>'
and asserts the literal '<script>alert(1)</script>' substring is absent
from the response. Updates the existing happy-path and FullFlowTest
assertions to match the new 'scenario:"demo"' (quoted) form.
This commit is contained in:
@@ -34,6 +34,7 @@ final class PostTeamEditor
|
||||
|
||||
$json = json_encode($this->scenarioToArray($scenario), JSON_THROW_ON_ERROR);
|
||||
$url = (string) ($params['id'] ?? $scenario->id);
|
||||
$safeUrl = json_encode($url, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
|
||||
$body = <<<HTML
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
@@ -41,7 +42,7 @@ final class PostTeamEditor
|
||||
<body>
|
||||
<p>Scenario saved.</p>
|
||||
<script type="module">
|
||||
localStorage.setItem('scenario:{$url}', $json);
|
||||
localStorage.setItem('scenario:{$safeUrl}', $json);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user