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

ResponseCookies#delete does not work with __Secure-/__Host- cookie prefixes. #56632

Open
1 task done
simoncave opened this issue Oct 9, 2023 · 4 comments · May be fixed by vercel/edge-runtime#890
Open
1 task done
Labels
bug Issue was opened via the bug report template.

Comments

@simoncave
Copy link

simoncave commented Oct 9, 2023

Link to the code that reproduces this issue

https://codesandbox.io/p/sandbox/suspicious-worker-939hzv

To Reproduce

  1. Open the CodeSandbox.
  2. Open Web Inspector.
  3. Click "Delete Cookie".
  4. Click "Delete Cookie (with set)".
  5. Observe the set-cookie headers for the two requests in Web Inspector:
    • The first one is unexpectedly blocked by the browser.
    • The second one works as expected.

Current vs. Expected behavior

The two buttons both attempt to delete a cookie. The "Delete Cookie" button demonstrates the current unexpected behavior. The "Delete Cookie (with set)" button demonstrates a workaround.

Delete Cookie

This button uses ResponseCookies#delete. It attempts to delete a cookie that uses the __Secure- prefix. When a cookie uses this prefix, it must use the Secure attribute, both when setting the cookie and deleting it, otherwise the set-cookie header will be blocked by the browser.

cookies().delete({
  name: "__Secure-UsingDelete",
  secure: true,
  httpOnly: true,
  sameSite: "none",
})
Expected Behavior

The set-cookie header should include the Secure, HttpOnly, and SameSite=none attributes.

Set-Cookie: __Secure-UsingDelete=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Secure; HttpOnly; SameSite=none
Current Behavior

The set-cookie header does not include the Secure, HttpOnly, and SameSite=none attributes.

Set-Cookie: __Secure-UsingDelete=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT

Warning

As the set-cookie header has the __Secure-, but does not use the Secure attribute, it is blocked by the browser:

Screenshot 2023-10-10 at 9 58 44 am

Delete Cookie (with set)

This button uses ResponseCookies#set as a workaround. It attempts to delete a cookie that uses the __Secure- prefix. When a cookie uses this prefix, it must use the Secure attribute, both when setting the cookie and deleting it, otherwise the set-cookie header will be blocked by the browser.

cookies().set({
  name: "__Secure-UsingSet",
  value: "",
  expires: 0,
  secure: true,
  httpOnly: true,
  sameSite: "none",
})

The set-cookie header does include the Secure, HttpOnly, and SameSite=None attributes, as expected.

Set-Cookie: __Secure-UsingSet=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Secure; HttpOnly; SameSite=none

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #1 SMP PREEMPT_DYNAMIC Sun Aug  6 20:05:33 UTC 2023
Binaries:
  Node: 20.7.0
  npm: 10.1.0
  Yarn: 1.22.19
  pnpm: N/A
Relevant Packages:
  next: 13.5.5-canary.4
  eslint-config-next: 13.5.4
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.2.2
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

App Router

Additional context

No response

@simoncave simoncave added the bug Issue was opened via the bug report template. label Oct 9, 2023
@joseocabarcas
Copy link

any news for that ? I have the same issue

@isoroka-plana
Copy link

isoroka-plana commented Mar 5, 2024

I just ran into the same issue. Any reason why it doesn't work as expected? And what is the recommended workaround?

EDIT: I didn't read the issue attentively enough originally. cookies().set({ ... }) with correct options indeed works correctly. But so should cookies.delete({ ... }) too.

@joseocabarcas
Copy link

joseocabarcas commented Mar 8, 2024

In my case a workaround I used cookies().set({ ... }) with expire = Date(0)

@ykzts
Copy link
Contributor

ykzts commented Mar 19, 2024

Although not documented, cookies().delete can be given an object as an argument.

// app/test/route.ts
import { cookies } from 'next/headers'

export function POST() {
  const cookieStore = cookies()

  cookieStore.delete({
    name: 'test',
    domain: '.example.com',
    path: '/test',
    secure: true,
  })

  return new Response(null, { status: 204 })
}
$ curl -sI http://localhost:3000/test | grep set-cookie
set-cookie: test=; Path=/test; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Domain=.example.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template.
Projects
None yet
4 participants