
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.1only 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 unsafehrefforms, image path traversal, mXSS/namespace-confusion corpus, Markdown→marked→sanitizer integration. - Tests for
isBranchNameand 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
exhibitaactions 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:
testruns on every pull request and push;deployruns only on push tomainor manual dispatch; pages concurrency scoped to the deploy job. npm ciwith a committed lock file; the app itself still has zero runtime dependencies.
Repository protection
mainruleset: pull request required, status checktest, 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.mdat the repo root: reporting channels, response targets, scope, accepted risks, safe-harbor rules, token-exposure steps for users.gorillatogo.appconfirmed verified under the GitHub account (blocks domain takeover via a fork'sCNAMEor 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_signersfile added sogit log --show-signatureverifies locally. - Per-account git identity via
includeIf hasconfig:remote.*.urlforgithub.com/exhibita/**andexhibitacom/**: 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.