Skip to content

XSS validator returns 400 for valid rich-text JSON payload in POST body #720

Description

@kouts

Environment

- Operating System: Linux
- Node Version:     v24.14.0
- Nuxt Version:     4.2.1
- CLI Version:      3.30.0
- Nitro Version:    2.12.9
- Package Manager:  yarn@1.22.19
- Builder:          -
- User Config:      -
- Runtime Modules:  -
- Build Modules:    -

Nuxt Security Version

v2.6.0

Default setup used?

Yes, the bug happens even if the security option is not customized

Security options

defineNuxtConfig({
  security: {
    xssValidator: {
      methods: ['POST'],
    },
  },
})

Reproduction

https://github.com/kouts/nuxt-security/tree/xss_issue_reproduction

Description

  • xssValidator rejects a POST JSON payload that contains rich-text-like HTML, even when payload is expected application content.
  • In the reproduction branch, test test/xssValidator.richTextFalsePositive.test.ts sends:
    • POST /api/rich-text
    • body: {"description":"<p style=\"text-align:center\">hello</p>"}
  • Expected: 200 OK (payload accepted by endpoint; app-level sanitization can handle content).
  • Actual: 400 Bad Request from middleware.
  • Root behavior appears to come from validating JSON.stringify(body) as a whole string and failing on any transformed output.

Additional context

I found this while adding a new tRPC route in my Nuxt app that accepts content from a WYSIWYG editor. The route payload includes rich-text HTML (for example: {"description":"<p style="text-align:center">hello</p>"}).

With nuxt-security XSS validator enabled, the request is rejected with 400 Bad Request, even though this is expected editor content that I sanitize in the app layer before storing/rendering.

As a temporary workaround, I had to manually exclude the affected tRPC endpoints from xssValidator in route rules and handle sanitization myself in the route logic. I opened this issue because the middleware behavior is unexpectedly blocking valid rich-text JSON payloads and forced route-level exclusions in a normal editor + API flow.

Logs

❯ test/xssValidator.richTextFalsePositive.test.ts (1 test | 1 failed)
× allows a rich-text-like JSON payload sent to POST endpoints

AssertionError: expected 400 to be 200 // Object.is equality
- Expected: 200
+ Received: 400

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