Skip to content

Use the configured secret when signing and verifying CSRF tokens#584

Draft
Copilot wants to merge 6 commits intomainfrom
copilot/fix-csrf-secret-parameter-usage
Draft

Use the configured secret when signing and verifying CSRF tokens#584
Copilot wants to merge 6 commits intomainfrom
copilot/fix-csrf-secret-parameter-usage

Conversation

Copy link
Copy Markdown

Copilot AI commented Mar 24, 2026

The CSRF class accepted a secret option but did not incorporate its value into the token signature. As a result, signed tokens were effectively derived from the token payload alone instead of the configured secret.

  • Signing behavior

    • Replace the token-only SHA-256 hash with an HMAC-SHA256 signature keyed by secret.
    • Keep the existing unsigned-token behavior unchanged when no secret is configured.
  • Verification behavior

    • Verify signed tokens against the HMAC produced from the same secret.
    • Reject tokens signed with a different secret as tampered.
  • Regression coverage

    • Add a focused test that generates a token with one secret and verifies that validation fails with another.
let token = new CSRF({ cookie, secret: "my-secret" }).generate();

await expect(
  new CSRF({ cookie, secret: "different-secret" }).validate(formData, headers),
).rejects.toThrow(
  new CSRFError("tampered_token_in_cookie", "Tampered CSRF token in cookie."),
);
Original prompt

This section details on the original issue you should resolve

<issue_title>CSRF does not use value of secret parameter</issue_title>
<issue_description>### Describe the bug

The value of the secret parameter in the CSRF class is never read

Your Example Website or App

https://github.com/sergiodxa/remix-utils/blob/main/src/server/csrf.ts

Steps to Reproduce the Bug or Issue

Search for any use of this.secret. It will only do a boolean check of whether it is present

Expected behavior

The value of the secret should be part of the signature:

return encodeBase64url(sha256(new TextEncoder().encode(token)));

Screenshots or Videos

No response

Platform

N/A

Additional context

No response</issue_description>

<agent_instructions>Made use of this.secret when signing/verifying the CSRF token</agent_instructions>

Comments on the Issue (you are @copilot in this section)


⌨️ Start Copilot coding agent tasks without leaving your editor — available in VS Code, Visual Studio, JetBrains IDEs and Eclipse.

Copilot AI and others added 3 commits March 24, 2026 17:57
Co-authored-by: sergiodxa <1312018+sergiodxa@users.noreply.github.com>
Agent-Logs-Url: https://github.com/sergiodxa/remix-utils/sessions/fc7d0948-723d-4c89-94cf-e54238606193
Co-authored-by: sergiodxa <1312018+sergiodxa@users.noreply.github.com>
Agent-Logs-Url: https://github.com/sergiodxa/remix-utils/sessions/fc7d0948-723d-4c89-94cf-e54238606193
Co-authored-by: sergiodxa <1312018+sergiodxa@users.noreply.github.com>
Agent-Logs-Url: https://github.com/sergiodxa/remix-utils/sessions/fc7d0948-723d-4c89-94cf-e54238606193
@sergiodxa sergiodxa requested a review from Copilot March 24, 2026 18:00
Copilot AI changed the title [WIP] Fix CSRF to use value of secret parameter Use the configured secret when signing and verifying CSRF tokens Mar 24, 2026
Copilot AI requested a review from sergiodxa March 24, 2026 18:00
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the server-side CSRF token signing to incorporate the configured secret value into the signature, and adds a regression test ensuring tokens signed with one secret are rejected when validated with another.

Changes:

  • Replace plain hashing with HMAC-SHA256 keyed by the configured secret for CSRF token signatures.
  • Add a test that validates secret-specific signing/verification behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/server/csrf.ts Switches CSRF signing from hash-only to secret-keyed HMAC signing.
src/server/csrf.test.ts Adds coverage to ensure tokens are rejected when validated with a different secret.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +347 to +348
let encoder = new TextEncoder();
return encodeBase64url(hmac(SHA256, encoder.encode(this.secret), encoder.encode(token)));
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verifySignature compares the provided signature to the expected signature using plain string equality. For authentication/verification primitives like HMAC, this can leak information via timing differences. Consider switching to a timing-safe comparison (e.g., compare decoded bytes in constant time, or reuse the repo’s timing-safe helper pattern) when checking the signature.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied in c96353b. CSRF signature verification now uses a timing-safe comparison, and I also fixed the CSRF test formatting so the Code Quality check passes.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: sergiodxa <1312018+sergiodxa@users.noreply.github.com>
Agent-Logs-Url: https://github.com/sergiodxa/remix-utils/sessions/c5e1ab17-b229-448b-867e-6801c944186b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CSRF does not use value of secret parameter

3 participants