From 7061612271e96cf5c48d96763295260384ea7329 Mon Sep 17 00:00:00 2001 From: jleo3 Date: Tue, 18 Aug 2026 16:16:49 -0400 Subject: [PATCH] Harden gemspec files list to an explicit git-tracked allowlist (herb-embedded-78l) spec.files now builds from git ls-files filtered by per-directory regex (lib/**/*.rb, vendor/**/*.js, js/**/*.js, exe/* non-recursive) instead of Dir[] globs, per guides.rubygems.org/security's explicit recommendation: a pushed gem is public and widely mirrored, so a stray file matching a broad glob would ship with no review catching it before gem push, and a published version can only be yanked, not recalled. Verified byte-for-byte identical to the old file set (including correctly excluding js/entry.mjs, a git-tracked but non-.js build-time file the old glob never matched either), and confirmed via a real gem build + install + herb-lint-rb run that Bridge#boot's direct references to vendor/herb-linter.js and js/*.js still resolve correctly. --- herb-embedded.gemspec | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/herb-embedded.gemspec b/herb-embedded.gemspec index b47e19b..524be4f 100644 --- a/herb-embedded.gemspec +++ b/herb-embedded.gemspec @@ -9,7 +9,18 @@ Gem::Specification.new do |spec| spec.summary = "Embedded Herb linter for Ruby via a pluggable JavaScript engine adapter" spec.required_ruby_version = ">= 3.2" - spec.files = Dir["lib/**/*.rb"] + Dir["vendor/**/*.js"] + Dir["js/**/*.js"] + Dir["exe/*"] + # An explicit git-tracked allowlist, not Dir[] globs: a pushed gem is + # public and widely mirrored, so a stray file that happens to match a + # broad glob (a local debug script, an untracked scratch file) would + # ship with no review catching it before `gem push` — and a published + # version can only be yanked, not recalled from whoever already has it. + # See guides.rubygems.org/security. + spec.files = `git ls-files -z`.split("\x0").select do |file| + file.match?(%r{\Alib/.*\.rb\z}) || + file.match?(%r{\Avendor/.*\.js\z}) || + file.match?(%r{\Ajs/.*\.js\z}) || + file.match?(%r{\Aexe/[^/]+\z}) + end spec.require_paths = ["lib"] spec.bindir = "exe" spec.executables = ["herb-lint-rb"]