Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Common pattern with readBody may lead to CSRF #875

Open
OhB00 opened this issue Sep 2, 2024 · 0 comments
Open

Common pattern with readBody may lead to CSRF #875

OhB00 opened this issue Sep 2, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@OhB00
Copy link

OhB00 commented Sep 2, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant