Skip to content

[FE-04] Sanitize user-generated content to prevent XSS - contact messages rendered without escaping #272

Description

@Leothosine

Problem

Contact form messages submitted by restaurant customers are stored in the database and later displayed in the admin panel without HTML sanitization. Menu item descriptions can also be edited by admins and displayed publicly without escaping. If any path allows HTML to reach the DOM unescaped, it creates an XSS vector. Additionally, next.config.ts has no Content Security Policy headers.

Proposed Solution

  1. Install dompurify and @types/dompurify
  2. Create frontend/lib/utils/sanitize.ts with a sanitize(input: string): string function wrapping DOMPurify.sanitize() with a strict allowlist (no <script>, no event handler attributes, no javascript: URIs)
  3. Apply sanitize() to: contact messages in ContactDetailsModal, menu item descriptions in the public menu
  4. Add CSP headers in next.config.ts via the headers() config function
  5. Add an ESLint rule to flag any new dangerouslySetInnerHTML usage for review

Acceptance Criteria

  • Submitting <script>alert(1)</script> as a contact message renders as escaped text, not executable markup
  • Content-Security-Policy header present on all page responses
  • dompurify allowlist is explicit and documented in the sanitize util
  • ESLint rule no-danger (or equivalent) added to .eslintrc
  • Sanitize function has unit tests covering: plain text, HTML tags, script injection, event attributes

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions