Skip to content

Common pattern with readBody may lead to CSRF #875

Description

@OhB00

Environment

N/A

Reproduction

The following pattern for creating endpoints is common, and may lead to a CSRF attack, provided it is a GET/POST handler, and only requires strings, or arrays of strings in the body.

The following is an example of what a vulnerable handler might look like:

export default defineEventHandler(async e => {
  // Authenticated endpoint
  await VerifyAuthenticationHere(e)

  // Assumption here that content-type is validated.
  const body = await readBody(e)

  // Optional validation here ...

  // Some sensitive action that relies upon body
  if (body.action === "update") {
    await UpdateUser(body.new_username)
  }
})

Describe the bug

The readBody utility will accept multiple different content type's, including application/json application/x-www-form-urlencoded and text/plain.

There is an assumption that the readBody handler will only emit an object for the application/json content type, however, this also occurs for application/x-www-form-urlencoded.

This has implications for security as cross-site requests can be sent when using the application/x-www-form-urlencoded, but they cannot be sent when using application/json.

If readBody is called without appropriate CSRF protections, or without verifying the content-type header, the application may be at risk of a CSRF attack.

Additional context

The following handler is an example of how an attacker could exploit one of these issues:

await fetch('https://whatever.io/api/edit', {
    method: 'POST',
    headers:{
      'Content-Type': 'application/x-www-form-urlencoded'
    },    
    body: new URLSearchParams({
        'username': 'hacked!',
    }),
    mode: 'no-cors'
}

Logs

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions