
Agent-Fähigkeit, die eine Rails-Codebasis auf CVE-2026-66066 (KindaRails2Shell) prüft — Active Storage + libvips beliebiges Dateilesen / RCE, die Rails- und libvips-Versionen sowie Block-untrusted-Mitigationen überprüft
Ein Agent Skill, der Ruby-on-Rails-Repositories auf Exposition gegenüber CVE-2026-66066 (KindaRails2Shell) prüft — die Schwachstelle in der Variantenverarbeitung von Active Storage mit libvips, die beliebiges Lesen von Dateien und in einer Rails-Anwendung Remote-Code-Execution ermöglicht.
Der Skill ist ein Konfigurations-Auditor und eine Hilfe zur Behebung. Er enthält keinen Exploit-Code und beschreibt nicht die Angriffskette.
| CVE | CVE-2026-66066 |
| Schweregrad | Kritisch, CVSS 9.5 |
| Paket | activestorage (RubyGems) |
| Betroffen | < 7.2.3.2, >= 8.0 < 8.0.5.1, >= 8.1 < 8.1.3.1 |
| Gepatcht | 7.2.3.2, 8.0.5.1, 8.1.3.1 |
| Advisory | GHSA-xr9x-r78c-5hrm |
libvips liest und schreibt Formate über Operationen, von denen es einige als unfuzzed kennzeichnet — unsicher für nicht vertrauenswürdige Inhalte. Active Storage hat diese nicht deaktiviert, sodass ein Angreifer, der eine präparierte Datei hochladen kann, sie erreichen kann.
Eine Anwendung ist nur exponiert, wenn alle vier Bedingungen erfüllt sind:
activestorage liegt in einem betroffenen Versionsbereichconfig.active_storage.variant_processor wird zu :vips aufgelöstBedingung 3 ist die entscheidende. Der betroffene Bereich < 7.2.3.2 umfasst jede Rails-6.x-Version, aber 6.x verwendet standardmäßig :mini_magick, sodass 6.x nur unter einer nicht standardmäßigen Konfiguration exponiert ist, und Versionen vor 6.0 haben überhaupt keine variant_processor-Einstellung. Rails 7.0 und später verwenden standardmäßig :vips über config.load_defaults 7.0, weshalb die gängige Konfiguration exponiert ist. Rails 8.1 akzeptiert außerdem :disabled, wodurch Bedingung 3 falsch wird.
Als Claude-Code-Plugin über den in diesem Repository gebündelten Marketplace:
/plugin marketplace add paveg/rails-activestorage-vips-audit
/plugin install rails-activestorage-vips-audit@paveg-skills
Mit der skills CLI, die denselben Skill in Claude Code, Codex, Cursor, Copilot CLI und andere Agents installiert:
npx skills add paveg/rails-activestorage-vips-audit
Oder manuell:
git clone https://github.com/paveg/rails-activestorage-vips-audit.git
cp -r rails-activestorage-vips-audit/skills/rails-activestorage-vips-audit ~/.claude/skills/
~/.agents/skills/ dient als runtime-übergreifender Speicherort für Codex, Copilot CLI und Gemini CLI. Nichts in der Skill hängt davon ab, wo sie installiert ist — es gibt keine absoluten Pfade, und collect-evidence.sh löst alles relativ zum Anwendungsstamm auf, auf den es zeigt.
Die Skill hat zwei Modi, und beide akzeptieren mehrere Anwendungspfade.
report <app>... # read-only audit, one verdict per application
fix <app>... # applies remediation on a branch; never commits or pushes unprompted
Als Plugin installiert, ist jeder Modus auch ein Befehl, sodass der Modus nicht als Argument eingegeben werden muss:
/rails-activestorage-vips-audit:report path/to/app another/app
/rails-activestorage-vips-audit:fix path/to/app
Die Befehle sind Einstiegspunkte für dich, nicht für den Agenten: Sie sind so gekennzeichnet, dass Claude sie niemals von sich aus auslöst. Claude ruft die Skill dennoch selbst auf, wenn eine Anfrage dazu passt, weshalb fix nicht ohne eine menschliche Anforderung starten kann.
report ist der Standard. fix erfordert zuerst ein report-Urteil für dieselbe Anwendung, da die korrekte Behebung davon abhängt — Rails 6.x, 7.0.x und 7.1.x haben keinen Patch innerhalb derselben Serie, sodass fix dort die vorläufige Gegenmaßnahme anwendet und meldet, dass ein Framework-Upgrade erforderlich ist, anstatt eines zu versuchen.
Die Beweissammlung kann auch separat ausgeführt werden:
skills/rails-activestorage-vips-audit/scripts/collect-evidence.sh path/to/app another/app
Das Skript sammelt Fakten und enthält bewusst keine Urteilslogik. Übergeben Sie ein Anwendungs-Stammverzeichnis, kein undifferenziertes Monorepo-Stammverzeichnis. Übergeben Sie bei einem Monorepo jedes deploybare Rails-Verzeichnis mit eigener Gemfile.lock und config/application.rb als separates Argument. Der Collector schließt diese verschachtelten Anwendungs-Stammverzeichnisse aus dem Evidenzstrom des übergeordneten Verzeichnisses aus, behält jedoch verschachtelte Lockfile-Stammverzeichnisse bei, bei denen es sich um eingebundene Engines oder Pfadabhängigkeiten handeln kann.
vips --version dort, wo die Anwendung läuft. Berichte führen dies unter Laufzeitbereitschaft und Behebung auf, anstatt das Expositionsurteil davon abhängig zu machen.VIPS_BLOCK_UNTRUSTED in einem Dockerfile beweist nicht, dass die bereitgestellte Umgebung sie setzt. Die Skill begrenzt solche Befunde auf „vorläufige Gegenmaßnahme vorhanden, Upgrade weiterhin erforderlich“ und lässt niemals zu, dass einer davon ein sauberes Urteil erzeugt.Aktualisieren Sie auf 7.2.3.2, 8.0.5.1 oder 8.1.3.1, passend zu Ihrer Serie. Bestätigen Sie zuerst libvips zur Laufzeit >= 8.13 und ruby-vips >= 2.2.1: Wo ruby-vips installiert ist, löst das gepatchte Active Storage beim Booten einen Fehler aus, sofern nicht beides zutrifft, und diese Prüfung gilt auch für :mini_magick-Anwendungen.
Vorläufige Gegenmaßnahmen, von denen keine einen Ersatz für das Upgrade darstellt:
VIPS_BLOCK_UNTRUSTED (libvips >= 8.13; keine Gem-Änderung erforderlich)Vips.block_untrusted(true) aus einem Initializer auf (ruby-vips >= 2.2.1, plus libvips >= 8.13)Bei ruby-vips < 2.2.1 ruft der Initializer-Weg eine Methode auf, die noch nicht existiert; heben Sie daher zuerst das Gem an oder wählen Sie den Weg über die Umgebungsvariable, der nicht davon abhängt.
Wenn eine Anwendung exponiert war, behandeln Sie jedes Geheimnis, das der Anwendungsprozess lesen kann, als kompromittiert und rotieren Sie es: secret_key_base, den Master Key, die Zugangsdaten des Active-Storage-Dienstes, Datenbank-Zugangsdaten und Tokens von Drittanbietern.
Eine WAF ist hier keine Gegenmaßnahme. Ob sie die Nutzlast sehen kann, hängt vom Speicherdienst und der Upload-Methode ab, sodass ihre Wirksamkeit zu stark von der Konfiguration abhängt, um sich darauf zu verlassen.