Fix bugs and harden against XSS across the extension#340
Merged
vict0rsch merged 13 commits intorefactor-es-modulesfrom Apr 13, 2026
Merged
Fix bugs and harden against XSS across the extension#340vict0rsch merged 13 commits intorefactor-es-modulesfrom
vict0rsch merged 13 commits intorefactor-es-modulesfrom
Conversation
The .last() implementation called this.reverse() which mutates the array in place. Every call permanently reversed the array, corrupting data when called more than once. Use index-based access instead. Made-with: Cursor
- Fix regex capturing only last character of OpenReview IDs by moving the + quantifier inside the capture group. - Remove unreachable dead code in fetchPWCData (after early return). - Replace undefined setTitleCode/setFaviconCode with MV3-compatible chrome.scripting.executeScript using func + args. - Remove unused identifier variable in pushSyncPapers. Made-with: Cursor
- data.js: add const to major/minor in versionToSemantic (implicit globals) - parsers.js: replace undefined error() with logError() in extractCrossrefData - content_script.js: add const to abstractH2 in huggingfacePapers - options.js: add i parameter to validateImportPaper, add const to pwcMatch Made-with: Cursor
- Fix inverted addDate comparison in syncMerge: use < instead of > to keep the oldest add date as intended by the comment. - Add done() to default contentScriptCallbacks to prevent TypeError when callers don't provide it. Made-with: Cursor
Object.entries().map((k, v) => ...) was using the index as v instead of the value. Fix to destructure as ([k, v]) and filter empty arrays. Made-with: Cursor
Replace while(1) with a bounded loop (max 20 iterations) to prevent the function from running indefinitely for the lifetime of the tab. Made-with: Cursor
- Add escapeHtml utility to functions.js for shared use. - Escape paper.venue and bibtex year in makePaperMemoryHTMLDiv, displayPaperVenue, and huggingfacePapers. - Validate codeLink protocol and escape in displayPaperCode to prevent javascript: URI injection. - Escape paper.id in updateCompleteSecretHTML content attribute. Made-with: Cursor
- templates.js: escape paper.title, note, codeLink, author, and tag names before HTML insertion in getMemoryItemHTML and getPopupEditFormHTML. - options.js: escape title/authors in getAutoTagHTML value attributes, paper.title in addPreprintUpdate, URLs in import feedback, update content values in startMatching, and error objects in sync feedback. Made-with: Cursor
- functions.js: escape URL and title in copyHyperLinkToClipboard, escape error stack lines in stringifyError. - data.js: escape validation warning keys and values in prepareOverwriteData. - bibMatcher.js: escape paper titles, citation keys, venues, and sources in updateMatchedTitles and matchBibliography status output. Made-with: Cursor
…nd.js - Validate sender.id matches extension ID on all messages to reject messages from external extensions/web pages. - Improve filename sanitization to strip all filesystem-unsafe chars, collapse consecutive dots, and limit length. - Validate pdfUrl protocol before initiating download. Made-with: Cursor
- Redact GitHub PAT from console log output in options.js. - Replace regex-based autoTag matching with case-insensitive string includes to eliminate ReDoS risk from user-supplied patterns. Made-with: Cursor
Made-with: Cursor
The WXT migration removed pre-committed bundles, so dist/chrome-mv3 must be built before Puppeteer can load the extension. Made-with: Cursor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR
Fix a collection of bugs (scoping, logic, infinite loops) and harden the extension against XSS by escaping all user-controlled data injected into HTML via a new
escapeHtmlutility.Breaking changes 🔥
None.
Changes
escapeHtml()utility and apply it across allinnerHTML/template-literal injection points in popup templates, options page, content script, bib matcher, and shared utils. Covers paper titles, authors, tags, notes, code links, venue names, URLs, and error messages.pdfUrlishttps?://before downloading.chrome.runtime.onMessagemessages not originating from the extension itself.[REDACTED]instead.chrome.scripting.executeScript({ code: ... })with the safer{ func, args }form (MV3-compatible).makeTitle) with a local iteration counter instead of the uncappedwhile(1).Array.prototype.lastmutating the original array via.reverse(); fixmergePaperskeeping the neweraddDateinstead of the oldest; fixprepareOverwriteData.map()destructuring; fix implicit globals (major,minor,pwcMatch,abstractH2); fix OpenReview regex capturing only the last character; remove dead code after earlyreturninfetchPWCData; add missingdonecallback default inaddOrUpdatePaper; replace undefinederror()calls withlogError()in parsers; add null guards on OpenReview URL regex matches.Review hints
escapeHtmlinsrc/shared/js/utils/functions.jsis the central utility — verify it covers the five OWASP-recommended characters (& < > " ').cutAuthors(escapeHtml(paper.author))call order intemplates.jsmeans entity-encoded strings are measured for truncation length — acceptable tradeoff but worth noting.autoTagPaperchange inparsers.jskeepsnew RegExp()with a try/catch instead of switching to.includes(), preserving regex UX as documented in the options UI.sender.idcheck inbackground.jssilently drops external messages — callers getundefinedresponses, which existing code handles.