Patch reachable security advisories; add bin/security-scan #12
Loading…
Reference in a new issue
No description provided.
Delete branch "armin-bot/impress:claude/security-backlog"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Clears the current security-advisory backlog and adds
bin/security-scan, the script a daily automated watch will run.The rule: patch what's likely to affect us, and hold what clearly can't, with the reason written down next to the ignore entry (
.bundler-audit.ymlfor gems,.security-scan-ignore.ymlfor JS and news posts) so it can be reviewed and revisited.On reachability: a closer read of the trigger conditions showed that none of the patched advisories was actually exploitable against DTI as deployed (details per row). They were patched because each fix was a cheap patch or minor bump on code we do run, not because we were exposed. Nothing here calls for a follow-up investigation.
Ruby gems (bundler-audit)
match/extract) against an attacker's URI, and we onlyexpandour own templates. The URLs wenormalize!come from Neopets' asset data.intlength overflow).Sanitize::Config::BASIC, which allows no<style>elements orstyleattributes, so CSS is stripped and never parsed. (Trivial to patch if you'd rather not lean on that.):confirmableisn't enabled onAuthUser. Fix is in Devise 5 (major).:timeoutwarden message, which only:timeoutablesets, and it isn't enabled.Rails itself is clean at 8.1.4.1.
JS packages (yarn npm audit)
<BrowserRouter>, which is what we use.<Link>/useNavigate)/outfits/. Only fixed in v7.<BrowserRouter>. Only fixed in v7.items/show), but the practical impact is tiny: a logout racing an in-flight frame request could leave you logged in..replaceReDoS)wrapRegExpuse (Chakra'sparseGradient) calls.exec()on a constant regex, never.replace().@emotion/babel-plugin→ babel-plugin-macros, which only runs inside Babel. We bundle with esbuild.bin/neopass-server(local NeoPass mock).Dev-only holds live under
yarn_development:, which only applies while the advisory is reachable solely via devDependencies. If one of those packages ever lands in production deps, the scan reports it again.Ruby itself
We run Ruby 3.4.5. 3.4.12 is out, and two security posts landed since:
Regexp.newon attacker-supplied patterns, and DTI never compiles regexes from user input.Resolv, but the attacks need us to look up an attacker-chosen hostname, and we only fetch fixed hosts (Neopets, NeoPass, Lebron, Impress 2020).Neither is urgent, but I'd recommend moving to 3.4.12 on the next convenient deploy, via the
ruby_version_latest/ruby_version_livedance indeploy/deploy.yml. bundler-audit can't see Ruby or its default gems, which is why the scan reads the Ruby news feed. It also prints a non-failing note while we're behind the latest patch release.bin/security-scan.bundler-audit.ymlitself, so it can also report stale ignore entries.yarn npm audit, run twice (--alland--environment production) so each JS finding is taggedscope: production|development. Gems get the same tag from Gemfile groups.feeds:ignore list). Ruby posts are filtered to security posts and new releases in our 3.4 series.--osvadds CVE aliases and fixed versions from api.osv.dev.incomplete/ exit 2:Right now it reports
clearwith 49 advisories ignored.Testing
bundle exec rspec: 383 examples, 0 failures.yarn build:devrebuilt fine.<script>,<style>and ajavascript:link (Markdown rendered, the rest stripped); Turbo Drive navigation (page state survived, so it was a Drive visit); and the wardrobe at/outfits/new, where React Router mounted and rewrote the URL vianavigate(…, { replace: true }). The wardrobe's "no data for this pet color" toast is expected: the dev DB has no pet data and Impress 2020 isn't running.Closet list, logged in (Markdown rendered; the
<script>,<style>andjavascript:link from the description are stripped):Wardrobe (React Router mounted and rewrote the URL; the error toast is expected with an empty dev DB):
🤖 Generated with Claude Code
https://claude.ai/code/session_014PWWczv69upP3Ha8B5J3zF