Summary
Restore rendering of existing JSXGraph problems by removing the frontend's incompatible semantic JavaScript allowlist after the GraphSandbox iframe has been hardened, while retaining lightweight input limits and syntax/error reporting.
Background / Context
On June 14, 2026, commit bc5b113 replaced the previous lightweight frontend validation with a hand-written strict parser in GraphSandbox.tsx. The parser permits only:
- Selected
board.create(...) calls.
- Single-variable declarations directly assigned from
board.create(...).
board.setBoundingBox(...) with exactly one array argument containing four numeric literals.
The authenticated problem page below now displays:
Rendering Error: board.setBoundingBox must use four numeric literals
Reproduction:
http://localhost:8080/problems/6a17020044f95e79a52c15ca
Its stored DSL starts with:
board.setBoundingBox([-2, 2, 4, -3], true);
JSXGraph officially supports setBoundingBox(bbox, keepaspectratio, setZoom), so the boolean second argument is valid. Both active problems with non-empty graph DSL use this valid two-argument form.
The same historical DSL also uses arithmetic, assignments, Math.sqrt, point X()/Y() calls, and multi-variable declarations. Therefore, merely widening the bounding-box regular expression would expose the next validation failure and would not restore compatibility.
The validator rejects the DSL before it is posted to the iframe; JSXGraph itself loads successfully and the browser console shows no JSXGraph runtime error.
Problem
The frontend validator is functioning as a second, incomplete JavaScript parser rather than validating JSXGraph correctness. It rejects valid previously stored graphs and creates an undocumented DSL compatibility boundary that differs from historical ingestion behavior and JSXGraph's actual API.
Existing tests only use simplified one-argument bounding boxes and do not include representative stored graph DSL, so the regression was not detected.
Goal / Expected Behavior
After the sandbox-hardening dependency is complete:
- Existing stored graph DSL renders again on problem detail, practice, exam, ingestion preview, and coaching surfaces.
- The frontend does not attempt to semantically parse or allowlist JSXGraph JavaScript.
- Empty input, excessive input size, JavaScript syntax errors, iframe runtime errors, and render timeouts remain handled and reported.
- Security isolation is provided by the hardened iframe rather than a divergent hand-written JavaScript grammar.
- Backend validation for newly generated coaching
whiteboard_dsl remains unchanged.
Scope
This issue should cover:
- Remove the frontend semantic allowlists for element types, option keys, statement forms, and blocked JavaScript tokens.
- Replace
validateDsl with lightweight checks limited to input size and JavaScript syntax compilation, or remove it if equivalent syntax/error handling is performed safely inside the hardened iframe.
- Add regression fixtures based on the currently stored graph DSL.
- Verify all
GraphSandbox consumers continue to render and report errors correctly.
- Update stale comments that claim the frontend is enforcing a strict DSL allowlist.
Out of Scope
This issue should not cover:
- Weakening iframe sandbox flags or CSP.
- Modifying stored MongoDB graph data to fit the current parser.
- Building or maintaining a fuller JavaScript parser.
- Changing the backend
_is_allowed_graph_dsl sanitizer used for VLM-generated coaching whiteboards.
- Adding unrelated JSXGraph features or refactoring consumer pages.
- Migrating graph DSL to another representation.
Chosen Implementation Approach
Do not extend the hand-written parser. Remove frontend semantic authorization and rely on the hardened opaque-origin iframe plus CSP for security containment.
Retain only:
- A clear maximum DSL length.
- JavaScript syntax validation where useful for immediate user-facing errors.
- Existing iframe runtime exception reporting.
- Existing timeout/reset behavior.
The historical problem DSL must be treated as a compatibility fixture and rendered without rewriting it.
Implementation Plan
The implementor should:
- Confirm the sandbox-hardening dependency has merged and its browser security tests pass.
- Add regression tests containing the full or representative stored DSL for problem IDs
6a17020044f95e79a52c15ca and 6a25846d7fc2a674734411f5.
- Demonstrate those tests fail under the current semantic validator.
- Remove the frontend element, option, token, statement, and literal allowlist parser from
GraphSandbox.tsx.
- Preserve a size limit and useful syntax/runtime error reporting without rejecting valid JSXGraph/JavaScript semantics.
- Update GraphSandbox tests to distinguish syntax errors from iframe runtime/rendering errors.
- Verify problem detail, practice, exam, ingestion preview, and coaching GraphSandbox consumers still behave correctly.
- Manually confirm the cited problem renders instead of showing the validator error.
Relevant Files / Areas
Likely relevant areas:
frontend/src/components/GraphSandbox.tsx
frontend/src/components/GraphSandbox.test.tsx
frontend/src/pages/ProblemDetailPage.tsx
frontend/src/pages/ActivePracticePage.tsx
frontend/src/pages/ActiveExamPage.tsx
frontend/src/pages/ExamDetailPage.tsx
frontend/src/pages/CoachingPage.tsx
frontend/src/components/ingestion/EditingStep.tsx
frontend/src/components/ingestion/ConfirmingStep.tsx
Reference behavior:
- JSXGraph
Board#setBoundingBox: setBoundingBox(bbox, keepaspectratio, setZoom)
- Regression URL:
http://localhost:8080/problems/6a17020044f95e79a52c15ca
Tests Required
The implementor must add or update automated tests covering:
board.setBoundingBox([-2, 2, 4, -3], true) is accepted.
- Representative historical DSL using arithmetic, assignments,
Math.sqrt, point coordinate methods, and multi-variable declarations reaches the iframe and renders.
- Oversized DSL is rejected with a clear error.
- Invalid JavaScript syntax produces a clear error.
- Runtime JSXGraph/JavaScript exceptions are surfaced through the existing iframe error protocol.
- Reset, timeout, graph switching, and duplicate-render prevention still work.
- Existing GraphSandbox consumers still render when
graphDsl is present.
At minimum, tests should verify:
- The exact current bug reproduction would fail before the fix and pass after it.
- Both active stored graph shapes are represented by compatibility fixtures.
- Security tests from the sandbox-hardening dependency continue to pass after semantic validation is removed.
Manual Verification / Self-Check
Before claiming this issue is done, the implementor must:
- Run the focused GraphSandbox tests.
- Run the relevant frontend unit and browser/smoke tests.
- Open
http://localhost:8080/problems/6a17020044f95e79a52c15ca while authenticated and confirm the graph renders.
- Verify the other active graph problem renders.
- Verify graph rendering in at least one practice or exam flow.
- Confirm browser security tests still show blocked parent access and outbound requests.
- Record exact commands and results in the PR description.
Suggested verification commands:
cd frontend
npm test -- --run src/components/GraphSandbox.test.tsx
npm test
npm run build
npm run test:smoke:compose
Reviewer Acceptance Checklist
The reviewer should verify that:
Dependencies
Depends on:
Follow-Up Work
Potential future work, not required here:
- Replace JavaScript graph DSL with a structured declarative format if stronger semantic validation becomes a product requirement.
- Add a larger persisted graph fixture corpus as more historical examples become available.
Definition of Done
This issue is done when:
- Both active stored graph problems render successfully without modifying their stored DSL.
- The frontend no longer rejects valid JSXGraph JavaScript through a custom semantic allowlist.
- Lightweight size/syntax checks and iframe error/timeout behavior remain tested.
- Sandbox security regression tests continue to pass.
- The PR includes exact automated and manual verification results.
Summary
Restore rendering of existing JSXGraph problems by removing the frontend's incompatible semantic JavaScript allowlist after the GraphSandbox iframe has been hardened, while retaining lightweight input limits and syntax/error reporting.
Background / Context
On June 14, 2026, commit
bc5b113replaced the previous lightweight frontend validation with a hand-written strict parser inGraphSandbox.tsx. The parser permits only:board.create(...)calls.board.create(...).board.setBoundingBox(...)with exactly one array argument containing four numeric literals.The authenticated problem page below now displays:
Rendering Error: board.setBoundingBox must use four numeric literalsReproduction:
http://localhost:8080/problems/6a17020044f95e79a52c15caIts stored DSL starts with:
JSXGraph officially supports
setBoundingBox(bbox, keepaspectratio, setZoom), so the boolean second argument is valid. Both active problems with non-empty graph DSL use this valid two-argument form.The same historical DSL also uses arithmetic, assignments,
Math.sqrt, pointX()/Y()calls, and multi-variable declarations. Therefore, merely widening the bounding-box regular expression would expose the next validation failure and would not restore compatibility.The validator rejects the DSL before it is posted to the iframe; JSXGraph itself loads successfully and the browser console shows no JSXGraph runtime error.
Problem
The frontend validator is functioning as a second, incomplete JavaScript parser rather than validating JSXGraph correctness. It rejects valid previously stored graphs and creates an undocumented DSL compatibility boundary that differs from historical ingestion behavior and JSXGraph's actual API.
Existing tests only use simplified one-argument bounding boxes and do not include representative stored graph DSL, so the regression was not detected.
Goal / Expected Behavior
After the sandbox-hardening dependency is complete:
whiteboard_dslremains unchanged.Scope
This issue should cover:
validateDslwith lightweight checks limited to input size and JavaScript syntax compilation, or remove it if equivalent syntax/error handling is performed safely inside the hardened iframe.GraphSandboxconsumers continue to render and report errors correctly.Out of Scope
This issue should not cover:
_is_allowed_graph_dslsanitizer used for VLM-generated coaching whiteboards.Chosen Implementation Approach
Do not extend the hand-written parser. Remove frontend semantic authorization and rely on the hardened opaque-origin iframe plus CSP for security containment.
Retain only:
The historical problem DSL must be treated as a compatibility fixture and rendered without rewriting it.
Implementation Plan
The implementor should:
6a17020044f95e79a52c15caand6a25846d7fc2a674734411f5.GraphSandbox.tsx.Relevant Files / Areas
Likely relevant areas:
frontend/src/components/GraphSandbox.tsxfrontend/src/components/GraphSandbox.test.tsxfrontend/src/pages/ProblemDetailPage.tsxfrontend/src/pages/ActivePracticePage.tsxfrontend/src/pages/ActiveExamPage.tsxfrontend/src/pages/ExamDetailPage.tsxfrontend/src/pages/CoachingPage.tsxfrontend/src/components/ingestion/EditingStep.tsxfrontend/src/components/ingestion/ConfirmingStep.tsxReference behavior:
Board#setBoundingBox:setBoundingBox(bbox, keepaspectratio, setZoom)http://localhost:8080/problems/6a17020044f95e79a52c15caTests Required
The implementor must add or update automated tests covering:
board.setBoundingBox([-2, 2, 4, -3], true)is accepted.Math.sqrt, point coordinate methods, and multi-variable declarations reaches the iframe and renders.graphDslis present.At minimum, tests should verify:
Manual Verification / Self-Check
Before claiming this issue is done, the implementor must:
http://localhost:8080/problems/6a17020044f95e79a52c15cawhile authenticated and confirm the graph renders.Suggested verification commands:
Reviewer Acceptance Checklist
The reviewer should verify that:
Dependencies
Depends on:
Follow-Up Work
Potential future work, not required here:
Definition of Done
This issue is done when: