Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
**Vulnerability:** XSS vulnerability in `App.jsx` where `dangerouslySetInnerHTML` was used directly with unsanitized `lineHtml` strings from the custom regex-based syntax highlighter.
**Learning:** The custom syntax highlighting did not properly sanitize input beyond basic tag escaping, allowing malicious code to potentially execute in the file preview component. A direct DOM injection vulnerability existed in a code review tool.
**Prevention:** Always use a sanitization library like `DOMPurify` when rendering untrusted or partially processed strings via `dangerouslySetInnerHTML`.
## 2024-06-30 - Strictly Configured DOMPurify for File Preview Highlight
**Vulnerability:** XSS vulnerability in `App.jsx` where `DOMPurify.sanitize` was used without an explicit configuration alongside `dangerouslySetInnerHTML`.
**Learning:** Although DOMPurify strips dangerous tags by default, relying on the default configuration may be less secure or flag strict security checks. It is safer to use an explicit configuration whitelist, allowing only exactly the tags and attributes needed by the code.
**Prevention:** Use an explicit configuration with `ALLOWED_TAGS` and `ALLOWED_ATTR` when using `DOMPurify.sanitize` with `dangerouslySetInnerHTML`.
2 changes: 1 addition & 1 deletion src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4568,7 +4568,7 @@ function App(){
var isHighlighted=filePreview.line&&lineNum===filePreview.line;
return React.createElement('div',{key:i,className:'file-preview-line'+(isHighlighted?' highlighted':'')},
React.createElement('span',{className:'file-preview-linenum'},lineNum),
React.createElement('span',{className:'file-preview-text',dangerouslySetInnerHTML:{__html:DOMPurify.sanitize(lineHtml||' ')}})
React.createElement('span',{className:'file-preview-text',dangerouslySetInnerHTML:{__html:DOMPurify.sanitize(lineHtml||' ', { ALLOWED_TAGS: ['span'], ALLOWED_ATTR: ['class', 'style'] })}})
);
})
):null
Expand Down
2 changes: 1 addition & 1 deletion src/lib/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ function getSecurityScanContent(file){
function isSanitizedPreviewRenderer(content){
return content.includes("function esc(s){return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');}") &&
content.includes("var escaped=esc(line);") &&
(content.includes("dangerouslySetInnerHTML:{__html:lineHtml||' '}") || content.includes("dangerouslySetInnerHTML:{__html:DOMPurify.sanitize(lineHtml||' ')}"));
(content.includes("dangerouslySetInnerHTML:{__html:lineHtml||' '}") || content.includes("dangerouslySetInnerHTML:{__html:DOMPurify.sanitize(lineHtml||' ', { ALLOWED_TAGS: ['span'], ALLOWED_ATTR: ['class', 'style'] })}"));
}

function yieldToBrowser(){
Expand Down
Loading