Skip to content

Fix: default cookies to HttpOnly, matching the CookieData JSDoc#3239

Open
morgan-coded wants to merge 2 commits into
Shopify:mainfrom
morgan-coded:fix/3207-cookie-httponly-default
Open

Fix: default cookies to HttpOnly, matching the CookieData JSDoc#3239
morgan-coded wants to merge 2 commits into
Shopify:mainfrom
morgan-coded:fix/3207-cookie-httponly-default

Conversation

@morgan-coded
Copy link
Copy Markdown

WHY are these changes introduced?

Fixes #3207

CookieData.httpOnly is documented as "true by default", but Cookies.set
never applies that default — it only spreads the caller's options. No caller in
lib/auth/oauth/oauth.ts passes httpOnly, so the OAuth shopify_app_state
cookie (and the non-embedded session cookie) are emitted without the
HttpOnly flag. An OWASP ZAP baseline scan flags this as "Cookie No HttpOnly
Flag". These cookies have no legitimate need for client-side JavaScript access.

WHAT is this pull request doing?

  • Cookies.set (and therefore Cookies.setAndSign) now defaults httpOnly to
    true, matching the existing CookieData.httpOnly JSDoc. The default is
    applied before spreading caller options, so callers can still opt out by
    explicitly passing httpOnly: false. This fixes every call site at once,
    including the non-embedded session cookie.
  • Extends the existing OAuth begin/callback tests to assert that the state
    cookie, its .sig companion, and the non-embedded session cookie all carry
    HttpOnly.
  • Adds focused coverage for the Cookies.set default, explicit opt-out, and
    preservation of other caller options.

No behavior change other than the added flag; existing callers that relied on
the absence of HttpOnly can pass httpOnly: false.

How was this verified?

  • Targeted jest --selectProjects library --testPathPatterns "oauth\\.test" in
    packages/apps/shopify-api: 23/23 pass.
  • Red→green: with the change reverted, the new assertions fail
    (httpOnly is undefined); with it applied they pass.
  • eslint . and tsc --noEmit: both clean.

Type of change

  • Patch: Bug (non-breaking change which fixes an issue)
  • Minor: New feature
  • Major: Breaking change

Checklist

  • I have used pnpm changeset to create a draft changelog entry
  • I have added/updated tests for this change
  • I have documented new APIs/updated the documentation for modified APIs — n/a (no public API surface change; the JSDoc already documented this default)

morgan-coded and others added 2 commits May 29, 2026 01:54
…opify#3207)

Cookies.set (and therefore setAndSign) now applies httpOnly: true by
default, matching the long-standing CookieData.httpOnly JSDoc which
already documented true as the default. Previously the default was never
applied, so the OAuth shopify_app_state cookie (and the non-embedded
session cookie) were emitted without the HttpOnly flag, which an OWASP
ZAP baseline scan flags. Callers that need client-side JS access can
still opt out by explicitly passing httpOnly: false.

Adds assertions to the existing OAuth begin/callback tests verifying the
state cookie, its signature companion, and the non-embedded session
cookie all carry HttpOnly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 29, 2026 15:14
@github-actions github-actions Bot added cla-needed devtools-gardener Post the issue or PR to Slack for the gardener labels May 29, 2026
@morgan-coded
Copy link
Copy Markdown
Author

I have signed the CLA!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

devtools-gardener Post the issue or PR to Slack for the gardener

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OAuth state cookie set without HttpOnly (CookieData JSDoc claims default true)

1 participant