Skip to content

Fix: sanitize innerHTML to prevent stored DOM-based XSS#312

Open
namann5 wants to merge 1 commit into
PatelHarsh2006:mainfrom
namann5:fix/stored-xss-innerhtml-sanitization
Open

Fix: sanitize innerHTML to prevent stored DOM-based XSS#312
namann5 wants to merge 1 commit into
PatelHarsh2006:mainfrom
namann5:fix/stored-xss-innerhtml-sanitization

Conversation

@namann5
Copy link
Copy Markdown

@namann5 namann5 commented May 27, 2026

Summary

Applies escapeHTML() to all user-influenced data before rendering through innerHTML.

The escapeHTML() utility already existed in js/sanitization.js but was never used throughout the application, leaving multiple persistent XSS injection points.

Vulnerabilities Fixed

Location | Field | Source -- | -- | -- createCard() (line 102) | item.image, item.name, item.description | localStorage (chaatRecentlyViewed), menu.json renderCart() (line 284) | item.image, item.name | localStorage (chaatCart) renderOrdersList() (line 428) | ci.item.name | localStorage (chaatOrders) Search suggestions (line 719) | item.category | menu.json

Attack Scenario

An attacker capable of writing to localStorage (e.g. via malicious browser extensions, shared/public systems, or supply-chain compromise) can inject arbitrary HTML/JavaScript into item fields that are later rendered unsafely through innerHTML.

This results in persistent XSS across multiple pages of the application.

Proof of Concept

localStorage.setItem(
  'chaatRecentlyViewed',
  JSON.stringify([
    {
      id: 99,
      name: '<img src=x onerror=alert(1)>',
      image: 'x',
      price: 10,
      description: ''
    }
  ])
);

location.reload();

Fixes Applied

  • Escaped all user-influenced values using escapeHTML()

  • Sanitized:

    • item.image

    • item.name

    • item.description

    • item.category

  • Escaped item.name and item.description before passing them into highlightText() to prevent HTML injection through search highlighting

  • Sanitized dynamic aria-label attributes used in cart action buttons

Security Impact

Prevents persistent DOM-based XSS through:

  • localStorage

  • JSON-fed UI rendering

  • Search suggestion rendering

  • Dynamic attribute injection

Relates to #311

Apply escapeHTML() to all user-influenced data (item.image,
item.name, item.description, item.category) before rendering
via innerHTML. The escapeHTML() function was already defined
in sanitization.js but never used.

Fixes Stored XSS where localStorage data (chaatRecentlyViewed,
chaatCart, chaatOrders) is rendered unsanitized through
createCard(), renderCart(), renderOrdersList(), and search
suggestions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant