<feed xmlns='http://www.w3.org/2005/Atom'>
<title>typerpunk/web/src/devApiOrigin.js, branch main</title>
<subtitle>Rust + WASM typing game.
</subtitle>
<id>https://srdusr.com/git/typerpunk/atom?h=main</id>
<link rel='self' href='https://srdusr.com/git/typerpunk/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://srdusr.com/git/typerpunk/'/>
<updated>2025-12-15T18:44:00+00:00</updated>
<entry>
<title>Harden for production: dependencies, headers, admin roles, docs</title>
<updated>2025-12-15T18:44:00+00:00</updated>
<author>
<name>srdusr</name>
<email>99972264+srdusr@users.noreply.github.com</email>
</author>
<published>2025-12-15T18:44:00+00:00</published>
<link rel='alternate' type='text/html' href='https://srdusr.com/git/typerpunk/commit/?id=1740327557074df0c8b99635ee949e2540ac94d0'/>
<id>urn:sha1:1740327557074df0c8b99635ee949e2540ac94d0</id>
<content type='text'>
Dependencies
- The server build carried 37 known advisories, including RUSTSEC-2024-0363
  in sqlx 0.7, which is the database layer. sqlx moved to 0.8 with
  default-features off, which also drops the MySQL and SQLite drivers and
  with them rsa and RUSTSEC-2023-0071. reqwest moved to 0.12, which brings
  hyper 1.x and was the sole source of every remaining advisory: h2 0.3,
  rustls-webpki 0.101, rustls-pemfile 1.0 and idna 0.3.
- The server build now reports no known vulnerabilities against OSV. cargo
  audit itself would not compile, so the check queries OSV with the crate
  versions cargo tree reports for the server binary.
- Cargo.lock is committed. This workspace produces binaries, so the lockfile
  is what makes a deployed build reproducible and the audit above meaningful.

Headers
- The application sent no security headers at all. The static server now
  sends a Content-Security-Policy, nosniff, frame options, a referrer policy
  and a permissions policy; the API sends a policy of its own, since it
  serves JSON and should load and frame nothing.
- The one inline script in index.html moved to a file so script-src needs no
  unsafe-inline. WebAssembly needs wasm-unsafe-eval, without which nothing
  types at all, so that is present and explained.
- Five style attributes moved to the CSSOM rather than adding unsafe-inline
  for styles. A style attribute in markup is refused by the policy; the same
  property set through element.style is not.

Production configuration
- With TYPERPUNK_ENV=production the server refuses to start if COOKIE_SECURE
  is off, if DATABASE_URL is still the development default, or if
  FRONTEND_ORIGIN is http on a non-local host. These were warnings, and a
  warning in a log nobody reads is not a safeguard.

Administration
- Moderators were appointed with psql. There is now an admin role,
  bootstrapped from TYPERPUNK_ADMIN_USERNAME at startup, and a UI to appoint
  and remove moderators. An administrator's own role cannot be changed
  through the API, so a mistake cannot lock everyone out of moderation.

Corpus
- scripts/export_approved.js writes approved submissions back into
  data/packs/community-*.json. Approved passages are served from the database
  and merged at startup, so without this the repository dataset and the live
  corpus drift apart, and a fresh checkout or the TUI sees only what shipped.

Documentation
- README rewritten for the repository: what it does, how to run it, the pack
  format, the server variables, deployment, and what the security posture
  actually is. Plain English, no em dashes, no emoji.

Checked and found already correct: every private endpoint refuses anonymous
callers, session cookies are HttpOnly and SameSite=Lax, CORS names a single
origin, internal errors are logged rather than returned, and every query is
parameterised.
</content>
</entry>
</feed>
