Skip to content

Repository files navigation

Astro Session Storage Key Collision Reproduction

Minimal reproduction for Astro issue #17718.

Environment

  • Astro 7.2.2
  • Node.js 26
  • pnpm

Description

Astro accepts the client-controlled astro-session cookie value as the session ID.

When the session storage shares its key namespace with unrelated application data, a crafted session cookie can collide with an existing storage key.

For example, this storage driver contains unrelated application data:

important-data → {"message":"THIS DATA MUST NOT BE DELETED"}

The client then sends:

Cookie: astro-session=important-data

Astro uses important-data as the session ID.

Because the value stored under that key is not valid Astro session data, Astro fails to parse the session and subsequently removes the same storage key.

Reproduction

Install dependencies:

pnpm install

Start the development server:

pnpm dev

In another terminal, send a request with a crafted session cookie:

curl -i \
  -H 'Cookie: astro-session=important-data' \
  http://localhost:4321/

The server output should contain:

[Astro #17718] ACCEPTED cookie as session ID: important-data
[DRIVER] GET: important-data
[DRIVER] DELETE: important-data
[DRIVER] BEFORE DELETE: true
[DRIVER] AFTER DELETE: false

The important part is:

[DRIVER] BEFORE DELETE: true
[DRIVER] AFTER DELETE: false

This demonstrates that the unrelated important-data entry was removed from the shared storage.

The request also results in a session parsing error because the value is not valid Astro session data.

Reproduction Flow

Client
  |
  | Cookie: astro-session=important-data
  v
Astro #ensureSessionID()
  |
  | accepts cookie value
  v
Session ID = "important-data"
  |
  v
storage.getItem("important-data")
  |
  | unrelated application data
  v
Session parsing fails
  |
  v
destroy()
  |
  v
storage.removeItem("important-data")
  |
  v
Unrelated application data is deleted

Mitigation Test

As a separate local experiment, #ensureSessionID() in Astro's installed runtime was modified to reject cookie values that are not valid UUIDs.

The same request:

Cookie: astro-session=important-data

then resulted in Astro generating a new UUID instead of using important-data as the storage key.

For example:

[Astro #17718] session cookie: important-data
[DRIVER] GET: e4568201-54c9-4b04-9ad0-730512450a29

There was no:

[DRIVER] DELETE: important-data

and the important-data entry remained in storage.

The Astro runtime modification was made only for this mitigation test and is not included in this repository.

Files

.
├── src/
│   ├── pages/
│   │   └── index.astro
│   └── session-driver.ts
├── astro.config.mjs
├── package.json
├── pnpm-lock.yaml
└── README.md

Notes

This reproduction intentionally uses a custom session driver whose storage namespace is shared with unrelated application data.

The purpose is to demonstrate the consequence of accepting an arbitrary client-controlled session ID when storage keys are not isolated or namespaced.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages