Skip to content

[BUG] Stored XSS via Unsanitized Avatar URL in user profiles #308

Description

@Siddh2024

Description

The avatar URL stored via PUT /api/profile has no server-side validation and is rendered client-side using innerHTML without escaping, enabling stored cross-site scripting (XSS).

Vulnerable Code

Server � server.js:713 � avatar stored as-is with no sanitization:
js avatar: req.body.avatar ?? existing?.avatar ?? '',

Client � public/js/app.js:269 � avatar rendered via innerHTML with no escaping:
js avatarEl.innerHTML = <img src="" alt="" />;

The escapeHtml() function exists in the same file (line 388) but is never used for the avatar field.

Exploit Scenario

An attacker sends a direct PUT /api/profile request with a crafted avatar payload containing an onerror event handler. The stored payload is then served to every visitor of any public profile page. Since src="" is invalid, the onerror handler executes immediately, running arbitrary JS in every visitor's browser.

Impact

  • Stored XSS � payload persists in DB, fires on every page load
  • No auth required to view public profiles � reaches all visitors
  • Cookie theft, session hijacking, phishing, defacement

Suggested Fix

Server-side (server.js in PUT /api/profile handler):
js const avatar = req.body.avatar ?? existing?.avatar ?? ''; if (avatar && !/^https?:\/\/.+/i.test(avatar)) { return res.status(400).json({ error: 'Avatar must be a valid URL starting with http:// or https://' }); }

Client-side (public/js/app.js:269): Replace innerHTML with safe DOM API:
js const img = document.createElement('img'); img.src = profile.avatar; img.alt = profile.name || ''; avatarEl.innerHTML = ''; avatarEl.appendChild(img);

File References

  • server.js line 713
  • public/js/app.js line 269

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions