Essay

Adventures in Security Hardening

Adventures in Security Hardening

The realization hit me just this morning that in launching Gorilla To Go I really should have done a full security audit before going live. Yes, we had done a good job of securing things and thinking through all the angles but having a "security expert" has been super helpful; especially in securing our CI pipeline.

So, without any more ado, here are the remediation steps (as defined by Claude Fable 5.1) taken to ensure that this web application (PWA) is safe from takeovers and other issues that might allow miscreants to affect the use of this tool on your Vanilla Gorilla website.

Security hardening — Gorilla To Go, 2026-10-21

Application code (shipped in 0.13.0, PR #28)

  • Frame-buster: the app refuses to run inside another page (boot-check.js + window.__gtgFramed), closing the clickjacking gap that a <meta> CSP cannot cover.
  • Branch names are validated with git's own rules (isBranchName), so ..// tricks can never reach a GitHub API path.
  • Front-matter parser writes keys with Object.defineProperty, so a __proto__: key cannot alter the prototype of the parsed object.
  • Token is never placed in the Add-site markup (set via .value), and the in-memory draft is cleared when leaving for any screen other than a help page.
  • Remove-site dialog tells the user the token still works on GitHub and where to delete it.
  • Dev server binds 127.0.0.1 only and answers 400 to malformed % sequences and NUL bytes instead of crashing.

Tests

  • New sanitize.test.js (14 tests, jsdom/parse5): dropped elements, attribute stripping, DOM clobbering, 19 unsafe href forms, image path traversal, mXSS/namespace-confusion corpus, Markdown→marked→sanitizer integration.
  • Tests for isBranchName and the __proto__ key. Suite now 245 tests.

CI / supply chain

  • Every GitHub Action pinned to a full commit SHA with the version in a comment.
  • Repository policy: only GitHub-authored and exhibita actions allowed; SHA pinning required.
  • Dependabot enabled for GitHub Actions and npm (weekly), plus security updates (grouped); first bump (jsdom 30) reviewed and merged.
  • Workflow split: test runs on every pull request and push; deploy runs only on push to main or manual dispatch; pages concurrency scoped to the deploy job.
  • npm ci with a committed lock file; the app itself still has zero runtime dependencies.

Repository protection

  • main ruleset: pull request required, status check test, CodeQL results required, signed commits required, deletion and force-push blocked, branches must be up to date, no bypass actors.
  • Secret scanning with push protection; git history scanned (85 commits, 0 findings).
  • Private vulnerability reporting enabled.
  • CodeQL default setup (JavaScript, plus Actions workflows) scanning on PRs and schedule.
  • Dependency graph and Dependabot alerts enabled.
  • SECURITY.md at the repo root: reporting channels, response targets, scope, accepted risks, safe-harbor rules, token-exposure steps for users.
  • gorillatogo.app confirmed verified under the GitHub account (blocks domain takeover via a fork's CNAME or dangling Pages).

Documentation

  • README: test setup and Node requirement; hosting.md: PR checks, SHA pinning, Dependabot.
  • CHANGELOG 0.13.0 entry so users see the security changes in "What is new".

Developer workstation

  • SSH commit signing confirmed verified by GitHub; allowed_signers file added so git log --show-signature verifies locally.
  • Per-account git identity via includeIf hasconfig:remote.*.url for github.com/exhibita/** and exhibitacom/**: correct email, signing key, and GCM account auto-selected; no cross-account commits by accident.
  • Node updated to 24.22.1 (meets jsdom 30's engine floor); package.json/README state the real requirement (PR #30).

Explicitly accepted (documented, not changed)

  • Token stored in plaintext in IndexedDB — device/browser profile is the boundary.
  • No in-app lock screen.
  • Repository stays public — client-only app, so visibility hides nothing; openness buys trust and free security tooling.