Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

Sign and verify session tokens (HS256) with WebCrypto

Ouverte
#230 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Difficulté
4/5
Temps estimé
1-2 jours
Accessibilité débutants
55/100
Type d'issue
Fonctionnalité
Clarté
Clairement spécifiée
Activité
Active
Stack technique
node.js, typescript

Piste de recherche

Read packages/server/src/webhook.ts for the existing crypto.subtle HMAC usage, then create packages/server/src/security/session-token.ts and its tests at packages/server/tests/security/session-token.test.ts. Implement the specified compact HS256 token format, claim validation, origin and conversation checks, expiry skew, and key rotation; use RFC 7515 Appendix A.1 as a verification vector. Done means the listed acceptance tests pass, including malformed and tampered tokens.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

enhancement hacktoberfest help wanted server

Right now the widget picks its own conversationId and the server trusts it. With a shared store (Redis, Postgres), anyone who guesses another visitor's id can read that conversation's context and add to it. The fix in the next release is a short-lived signed session token: the server gives the widget a token bound to one conversation and one origin, and checks it on every request. This issue is the token format itself, as a new file with no dependencies. The /session route that hands tokens out comes later.

This one needs care, so it's for someone who has had a couple of PRs merged. I'll review it closely.

What to do
Create packages/server/src/security/session-token.ts. Use a compact JWS (header.payload.signature, base64url, no padding) with HS256 through crypto.subtle, so it runs on Node 22, Workers, Bun and Deno with no dependency.

export interface SessionClaims {
  v: 1;
  sid: string;       // session id
  cid: string;       // conversation id
  org: string;       // origin the token was issued for
  uid?: string;
  tier?: string;
  iat: number;       // seconds
  exp: number;       // seconds
}

/** Imports a secret (at least 32 bytes as UTF-8) as an HMAC key. */
export function importSessionKey(secret: string): Promise<CryptoKey>;

/** Signs with keys[0] and puts its index in the header as `kid`. */
export function signSession(claims: SessionClaims, keys: CryptoKey[]): Promise<string>;

export function verifySession(
  token: string,
  keys: CryptoKey[],
  opts: { origin: string | null; conversationId: string; now?: number; clockSkewSec?: number }
): Promise<
  | { ok: true; claims: SessionClaims }
  | { ok: false; code: 'malformed' | 'bad_signature' | 'expired' | 'origin_mismatch' | 'conversation_mismatch' }
>;
  • Header: {"alg":"HS256","typ":"JWT","kid":"<index>"}. Reject any other alg, including none.
  • Verify with crypto.subtle.verify, never by comparing strings. Try the key named by kid first, then the others, so rotating secrets doesn't log everyone out.
  • clockSkewSec defaults to 60 and applies to exp.
  • Check the signature before trusting anything in the payload. Return malformed for a token that doesn't have three parts, isn't valid base64url or JSON, or has a missing or wrongly typed claim.
  • importSessionKey throws a clear error when the secret is shorter than 32 bytes.
  • Don't create keys or call crypto.subtle at module load. Workers don't allow that at global scope.

Where to look

  • packages/server/src/webhook.ts already uses crypto.subtle HMAC for webhook signatures
  • RFC 7515, Appendix A.1, has an HS256 example with its key, usable as a test vector for verification

Acceptance criteria

  • New packages/server/src/security/session-token.ts and packages/server/tests/security/session-token.test.ts
  • Round trip: sign, then verify, gives back the same claims
  • Tests for an expired token, expired but within the skew, a changed payload, a changed signature, alg: none, a wrong origin, a wrong conversation, a malformed token, and rotation (signed with an old key that's second in the list)
  • The RFC 7515 A.1 token verifies with its key (the claims check can be skipped for it)
  • A secret shorter than 32 bytes throws
  • Not exported from @chatcops/server yet, and no changeset needed (pnpm changeset --empty)
  • pnpm test:coverage and pnpm lint pass

Want to work on this? Comment below and I'll assign it to you. Please take one issue at a time, branch off dev, and open your PR against dev with Closes #<this issue number>. Setup notes (pnpm, build before test) are in CONTRIBUTING.md.

Langage dominant
TypeScript
Étoiles
13
Forks
7
Merge moyen
4 h 11 min
PR mergées (30 j)
122

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de codercops/chatcops

Toutes les issues de codercops/chatcops

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.