Remix V2 Meta Sessions Review
/install remix-v2-meta-sessions-review
Remix v2 Meta, Sessions, Auth, and CSRF Code Review
Reviews Remix v2 meta/SEO, session, auth-gate, and CSRF code paths. Loaded
by the umbrella review-remix-v2 reviewer when a diff touches any of:
meta/links exports, root.tsx, *.server.ts session/cookie modules,
loaders/actions reading or writing session, or \x3CForm>/useFetcher
mutations.
See beagle-remix-v2:remix-v2-meta-sessions for canonical patterns.
Quick Reference
| Issue Type | Reference |
|---|---|
meta returning v1 object shape (BREAKING), OG shorthand, document.title in effect, missing \x3CMeta />/\x3CLinks />, parent merge |
references/meta-v2-shape.md |
Missing httpOnly/secure, hardcoded secrets, single-string secrets, replace-not-prepend rotation |
references/cookie-security.md |
Auth check in component, logout in loader, missing commitSession, flash without commit |
references/auth-gates.md |
Manual fetch POST bypassing CSRF, token in session cookie, no CSRF protection, shared secrets |
references/csrf.md |
Highest-stakes detection — call out first: v1 meta object shape (return { title, description }) in a v2 codebase. It typechecks, but the runtime ignores it and the page renders with no title and no meta tags. Grep every export const meta and confirm the return value starts with [, not {.
Review Checklist
-
metareturnsMetaDescriptor[](array starts with[), NOT the v1 object shape - OG / Twitter tags use
{ property, content }, NOT v1 shorthand{ "og:title": "..." } - No
document.title = "..."oruseEffect(() => { document.title = ... })— meta is set via themetaexport -
root.tsxincludes\x3CMeta />and\x3CLinks />inside\x3Chead> - Child
metathat wants parent values usesmatches.flatMap((m) => m.meta ?? []) -
metanull-guardsdata(loader may not have run / returnedundefinedon 404) - Cookie config sets
httpOnly: trueandsecure: process.env.NODE_ENV === "production" -
secretsis read fromprocess.env(no hardcoded strings, no committed.env.examplevalues) -
secretsis an array supporting rotation (prepend new, keep old) — not a single value - Every
session.set/session.unset/session.flashis followed by a response with"Set-Cookie": await commitSession(session) - Auth gate is in
loader(oraction) viarequireUserId(request)— NOT a component-level redirect - Logout is an
action(POST), not aloader(GET) - Mutating actions call
csrf.validate(request)when CSRF protection is in use - CSRF token uses a dedicated
createCookie("csrf", ...), NOT the session cookie - Mutations use
\x3CForm>/useFetchersoAuthenticityTokenInputattaches the token (no manualfetchPOST)
Valid Patterns (Do NOT Flag)
These are correct usage — do not report as issues:
sameSite: "lax"— acceptable default. Not every app needs"strict"; flag only when threat model warrants stricter (e.g. CSRF protection is otherwise absent).metareturning[]— legitimate when the route intentionally emits no meta (inherits root tags or relies on a sibling).linksreturning[]— legitimate when the route has no route-specific stylesheets or preloads.session.flash(...)followed on the next line bycommitSession(session)— the standard 2-line flash pattern. The separation is correct; do not flag it as "missing commit".- Auth check in
action(notloader) — correct for POST-only routes (e.g. logout, delete). Loaders gate GETs; actions gate mutations. charsetandviewportas plain JSX\x3Cmeta>inroot.tsx's\x3Chead>— preferred over themetaexport to avoid duplicate-tag warnings under v2's no-merge behavior.secrets: [process.env.X!, process.env.X_OLD!]—!non-null assertion is acceptable when a fail-fast guard above (if (!process.env.X) throw) is present.throw redirect(...)inside a loader/action — canonical Remix pattern; the thrown response is intentional.commitSessioncalled in a loader (not just an action) — required when a loader reads a flash message and must clear it.
Context-Sensitive Rules
Only flag these issues when the specific context applies:
| Issue | Flag ONLY IF |
|---|---|
| Missing CSRF validation in action | App declares remix-utils/csrf as its protection mechanism, OR the action is public-facing (not internal/VPN-gated) AND no Origin check is present |
sameSite: "lax" |
App has no library-based CSRF protection AND no Origin check — "lax" then becomes the only defense and is insufficient |
Missing secure flag |
Cookie config is the production session/CSRF cookie (not a test fixture or commented example) |
meta returning [] |
The route is documented as needing route-specific tags (e.g. a public landing page) — empty is usually intentional inheritance, do not flag by default |
Auth check in action not loader |
Route is GET-renderable (has a loader) — for POST-only routes, action is the correct gate |
Logout in action AND \x3CForm method="post"> |
Never flag — that is the canonical pattern |
Manual fetch POST |
The target is an internal Remix action AND no CSRF token is attached via headers |
secrets: [singleValue] |
App is in production OR has been deployed for long enough to need rotation — flag as recommendation, not CRITICAL |
Hard gates (before writing findings)
Run these in order. Do not draft user-facing findings until every gate passes for the batch you are about to report.
-
Location evidence — Pass: Each issue lists a repo path and either a line range or a short verbatim quote from the file you read. Diff-only or memory-based claims do not pass. For meta/links/session issues, the cited file is a
.ts/.tsxroute module,root.tsx, or*.server.ts— not a generic config file. -
Exemption check — Pass: For each issue, you can state in one line why it is not covered by Valid Patterns (Do NOT Flag). In particular:
sameSite: "lax", emptymeta/linksarrays, and the standardflash+commitSessiontwo-line pattern must be explicitly cleared. -
Meta-shape check — Pass: Before flagging anything about
meta, you read the actual function body and confirmed what it returns. TypeScript may have masked the shape (a v1 object can satisfy a poorly-typedMetaFunctionalias). The check is: the return expression starts with[and every element is a descriptor object. If it starts with{, that is the v1 shape — flag as CRITICAL. If it is[], that is valid (do not flag). -
Protocol — Pass: You completed the Pre-Report Verification Checklist in review-verification-protocol for this review.
When to Load References
- Reviewing any
export const metaorexport const links, orroot.tsx→ meta-v2-shape.md - Reviewing
createCookieSessionStorage,createCookie, or any*.server.tsthat configures cookies → cookie-security.md - Reviewing loaders/actions that read or write
session, or any auth helper → auth-gates.md - Reviewing forms, fetchers, or any mutating route → csrf.md
Review Questions
- Does every
metaexport return an array, and is every OG/Twitter tag{ property, content }? - Does
root.tsxinclude\x3CMeta />and\x3CLinks />inside\x3Chead>? - Are cookies
httpOnly+secure: NODE_ENV === 'production'withsecretsfrom env in an array (rotation-ready)? - Is every session mutation followed by a
Set-Cookie: await commitSession(session)header? - Is auth gated in the loader/action via a throwing helper, never in a component?
- Is logout an
action(POST), and do mutating actions validate CSRF (or document the threat model)?
Additional Documentation
- references/meta-v2-shape.md — v1 object shape in v2 codebases (BREAKING), OG shorthand,
document.titleantipatterns, root scaffolding, parent merging - references/cookie-security.md —
httpOnly/secure/sameSite, hardcoded secrets, rotation hygiene - references/auth-gates.md — loader-level gates, logout-must-be-action, commit pairing, flash patterns
- references/csrf.md —
remix-utils/csrfwiring, manual-fetch bypass, dedicated cookie, shared-secret hygiene
Before Submitting Findings
Complete Hard gates (especially gate 3 — meta-shape check), then report only issues that still pass the review-verification-protocol pre-report checks.
- Make sure OpenClaw is installed (local or Docker)
- Run the install command in chat:
/install remix-v2-meta-sessions-review - After installation, invoke the skill by name or use
/remix-v2-meta-sessions-review - Provide required inputs per the skill's parameter spec and get structured output
What is Remix V2 Meta Sessions Review?
Reviews Remix v2 code for v1-shape meta exports (BREAKING in v2), cookie security gaps (httpOnly, secure, secrets rotation), auth gates in wrong layer, and m... It is an AI Agent Skill for Claude Code / OpenClaw, with 51 downloads so far.
How do I install Remix V2 Meta Sessions Review?
Run "/install remix-v2-meta-sessions-review" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.
Is Remix V2 Meta Sessions Review free?
Yes, Remix V2 Meta Sessions Review is completely free, licensed under MIT-0. You can download, install and use it at no cost.
Which platforms does Remix V2 Meta Sessions Review support?
Remix V2 Meta Sessions Review is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).
Who created Remix V2 Meta Sessions Review?
It is built and maintained by Kevin Anderson (@anderskev); the current version is v1.0.0.