hono icon indicating copy to clipboard operation
hono copied to clipboard

Validate signed cookie throws on malformed URI

Open eduardvercaemer opened this issue 1 year ago • 2 comments

What version of Hono are you using?

3.12.0

What runtime/platform is your app running on?

Cloudflare Workers

What steps can reproduce the bug?

  1. Call await getSignedCookie on some cookie.
  2. Then send a request where the cookie signature has an invalid URI encoding (e.g. remove a character from a sequence such as %3D -> %3)
  3. The function throws instead of returning false as expected of invalid signatures.

What is the expected behavior?

The function should return false.

What do you see instead?

The function throws.

Additional information

That's it.

eduardvercaemer avatar Jan 06 '24 21:01 eduardvercaemer

Hi @eduardvercaemer !

Please give us a minimum reproducible code example so that we can debug easily.

yusukebe avatar Jan 07 '24 19:01 yusukebe

Hello everyone, perhaps this code example illustrates an error scenario by deliberately crafting a malformed cookie to trigger the error. Although I believe the execution example is for Cloudflare Workers, I think it's also applicable to Node.js. I'm not sure in what scenarios a modified cookie like this would occur. Nevertheless, the server does not break or crash; it simply returns a status 500 error, which should be handled from the controller. Perhaps this is a misguided opinion—please enlighten me! 😄

@eduardvercaemer isn't it?

import { serve } from '@hono/node-server'
import { Hono } from 'hono'
import { getSignedCookie, setSignedCookie } from 'hono/cookie'

const app = new Hono()

const cookieSecret = 'supersecret'


// FIRST EXECUTE THIS ENDPOINT TO SET THE COOKIE
app.get('/', async (c) => {
  await setSignedCookie(c, 'signed', 'signed value', cookieSecret)
  return c.text('Creating the signed cookie!')
})

// SECONDLY EXECUTE THIS TO FAKE THE MALFORMED COOKIE AND SEE THE ERROR
app.get('/issue', async (c) => {

  // Simulating a scenario where the cookie is malformed upon reception from the client
  const regex = /signed=([^;]+)/;
  const match = c.req.headers.get('Cookie')?.match(regex);

  if(match && match.length >= 1) {
    // Modifying the URI encoding to simulate potential manipulation by the client
    match[0] = match[0].replace('%20', '%2') + ';'
    c.req.headers.set('Cookie', match[0])
  }
  // Checking if the cookie should be invalid due to tampering
  const shouldBeFalse = await getSignedCookie(c, cookieSecret, 'signed')
  console.log(shouldBeFalse) // This would never be executed due to the error and the HTTP status code 500 response 
  return c.text('Issue with the cookie')
})

const port = 3000
console.log(`Server is running on port ${port}`)

serve({
  fetch: app.fetch,
  port
})

And the error:

URIError: URI malformed
    at decodeURIComponent (<anonymous>)
    at <anonymous> (c:\Users\ilan\Desktop\hono-projects\issue-1906\node_modules\hono\dist\cjs\utils\cookie.js:65:49)
    at Array.reduce (<anonymous>)
    at parse (c:\Users\ilan\Desktop\hono-projects\issue-1906\node_modules\hono\dist\cjs\utils\cookie.js:53:16)
    at parseSigned (c:\Users\ilan\Desktop\hono-projects\issue-1906\node_modules\hono\dist\cjs\utils\cookie.js:72:45)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at getSignedCookie (c:\Users\ilan\Desktop\hono-projects\issue-1906\node_modules\hono\dist\cjs\helper\cookie\index.js:47:18)
    at Array.<anonymous> (c:\Users\ilan\Desktop\hono-projects\issue-1906\src\index.ts:29:25)
    at responseViaResponseObject (c:\Users\ilan\Desktop\hono-projects\issue-1906\node_modules\@hono\node-server\dist\index.js:295:11)

ifritzler avatar Jan 28 '24 20:01 ifritzler