fix: remove ProjectComments innerHTML usage (#6522)#6545
fix: remove ProjectComments innerHTML usage (#6522)#6545dmetzner merged 6 commits intoCatrobat:developfrom
Conversation
|
Please review this PR |
|
@dmetzner please review this pr |
|
@dmetzner please review this pr? |
|
please make sure alle pipelines are green. |
Okay |
|
@dmetzner please review this PR... icorrected all the isues |
dmetzner
left a comment
There was a problem hiding this comment.
Thanks for tackling the innerHTML removal — this is a good security improvement. A few things need fixing before this can merge:
Must Fix
1. Don't hand-edit auto-generated files
src/Api/OpenAPI/Server/Model/CommentResponse.php is auto-generated by yarn run generate-api. Hand-editing it will be overwritten on the next generation.
Fix: Add user_approved to CommentResponse in src/Api/OpenAPI/specification.yaml, then run:
yarn run generate-api
bin/rector process src/Api/OpenAPI/Server/
bin/php-cs-fixer fix src/Api/OpenAPI/Server/ --using-cache=noAlso update the spec to remove the rendered field (or mark it deprecated) since we're no longer populating it.
2. innerHTML still used in createLoadingSpinner()
The PR's goal is to remove innerHTML usage, but createLoadingSpinner() (around line 438) still uses spinnerWrapper.innerHTML = ... with a large HTML string. While this is static content (no user data = no XSS risk), it's inconsistent with the PR's goal. Either:
- Convert to DOM API for consistency, or
- Add a comment explaining why innerHTML is acceptable here (static SVG, no user data)
3. rendered field set to empty string is wasteful
$response->setRendered('');This sends an empty "rendered": "" in every API response forever. Instead:
- Remove
renderedfrom the OpenAPI spec entirely (breaking change but the right move), or - Set it to
nulland mark asdeprecatedin the spec
Should Fix
4. Missing Behat test updates
Comments are now rendered client-side from API data. Many web-comments Behat tests may need I wait for AJAX to finish steps added (similar to what you did for language_switcher.feature). Otherwise tests could be flaky or fail because they check for elements before AJAX completes.
5. Report button condition review
if (!isDeleted && !isApproved && (isAdmin || !isOwnComment || !isLoggedIn))The !isLoggedIn means non-logged-in users see report buttons. Is this intentional? If clicking redirects to login, that's fine, but please confirm this matches the original Twig template behavior.
Nitpick
The createCommentElement function is ~200 lines of imperative DOM creation. Consider extracting a small helper like createElement(tag, className, textContent) to reduce repetition. Not blocking, but would improve readability significantly.
Overall direction is good — removing Twig rendering from the API response is the right architectural move. The main blocker is fixing the auto-generated file edit via the OpenAPI spec workflow.
dmetzner
left a comment
There was a problem hiding this comment.
Scope Concern — PR is too large for the issue
Issue #6522 identifies 2 specific innerHTML lines (312 and 395) that use data.rendered from the API. The suggested fix was either:
- Build DOM client-side with
escapeHtml(), or - Audit and document the security contract
This PR goes much further: it removes server-side Twig rendering entirely, rewrites the full comment rendering as 200+ lines of imperative DOM construction, modifies auto-generated API model files, adds new data attributes, and changes the API response shape. That's a full client-side migration of the comment system — a much bigger scope than fixing the innerHTML XSS risk.
Simpler alternative (2-3 line fix)
Replace innerHTML with DOMParser which safely parses HTML without executing scripts:
// Before (XSS risk):
tempDiv.innerHTML = data.rendered
const newComment = tempDiv.firstChild
// After (safe):
const doc = new DOMParser().parseFromString(data.rendered, 'text/html')
const newComment = doc.body.firstChildThis eliminates the innerHTML XSS vector while keeping server-rendered HTML. 2 changes, same result, zero risk of breaking comment rendering.
If the full client-side migration IS desired
That's fine architecturally, but it should be a separate ticket (like the other CSR migrations tracked in #6580-#6584). The current PR has several issues that would need fixing first:
- Hand-edited auto-generated file (
CommentResponse.php) — must go throughspecification.yaml+yarn run generate-api innerHTMLstill used increateLoadingSpinner()— inconsistent with PR goalrenderedfield set to empty string — wasteful, should be removed from spec or set to null- Missing Behat test AJAX waits — client-side rendering needs wait steps in web-comments tests
- 200-line
createCommentElement— hard to review/maintain; consider helpers
Recommendation
Either scope this PR down to the DOMParser fix (matching the issue), or split into two PRs: the quick DOMParser fix for #6522, and a separate CSR migration PR with proper OpenAPI spec changes.
|
Okay i will fix everything |
|
@dmetzner is this fine now? |
Your checklist for this pull request
Please review the contributing guidelines and wiki pages of this repository.
SHARE-666 The devils ticketCode Reviewsection in JiraAdditional Description
TODO: Add additional information that is not in your commit-message here