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.
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):Security model (
docs/specification/permalink.md, Security Considerations):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=Strictwould, 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.