Skip to content

Permalink can attach state changes to an authenticated buyer session on an unauthenticated GET: what protects against CSRF? #666

Description

@vishkaty

Summary

The shopping permalink (#523) is an unauthenticated browser GET that a Business MAY act on to change server-side state, and one of the permitted actions is merging items into an existing cart. When that existing cart belongs to a signed-in buyer, a cross-site link that mutates it on load is a cross-site request forgery. I could not find guidance on what is expected to protect this case, and the usual mitigations are not straightforward for a top-level GET, so this is a question rather than a proposed fix.

Observed

State construction (docs/specification/permalink.md, Redirect Resolution):

it MAY merge the permalink items into an existing cart, create a new cart, or stage a separate checkout

Security model (docs/specification/permalink.md, Security Considerations):

A permalink endpoint is an unauthenticated browser GET.

The Security Considerations section covers open redirect, header injection, mass assignment, log injection, and privacy, but a search for csrf, samesite, or forgery returns nothing.

The irreversible risks are already closed by the existing rule that a Business MUST NOT treat loading a permalink as authorization to place an order, charge payment, or complete checkout, so the residual case is narrower: an automated merge into an authenticated buyer's cart on a cross-site GET.

Why the mitigation is not obvious

The usual CSRF defenses do not map cleanly here. SameSite=Lax (the browser default) still sends cookies on top-level cross-site GET navigations, which is exactly how a permalink arrives, so it does not defend this case; SameSite=Strict would, but it would also break the legitimate flow of a buyer clicking a shared or campaign link and landing in their authenticated session. A CSRF token cannot ride an inbound top-level GET from an external link either.

Question

What is the intended protection for the automated-merge-into-authenticated-session case? One option would be to construct only anonymous, unattached state on load and require an explicit buyer action before attaching it to the signed-in session, but I did not want to assume that is the intended model. Guidance here (even a short note that the merge is expected to be anonymous-until-confirmed) would help implementers avoid shipping an accidental CSRF.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions