Direct answer: CVE-2026-122006 lets 1 file upload write files on a Rails server, with no login. With the Disk service, server files can also be read, including secret_key_base. Today, check the version, update to activestorage 8.1.4.1 or 8.0.5.2 with mini_magick 5.1 or later, then restart the app.
Rails rates this flaw critical with CVSS 3.1 9.8. The same release closes 21 advisories: 1 critical, 4 high, 13 medium, and 3 low.
Main condition: your app uses the :mini_magick processor and accepts uploads from users that you do not know. Limit: this article has no malicious file contents, payloads, or attack sequence.
We read the Rails advisory GHSA-f3w6-w445-fwh9, the Rails advisory GHSA-v924-7rp8-4mxh, the Rails security advisory list, the CVE-2026-122006 record, the Rails 8.1.4.1 release, the Rails 8.0.5.2 release, the Rails maintenance page, the Help Net Security report on CVE-2026-66066, and CISA KEV on 5 November 2026, from 20.36 to 20.50 WIB. We tested 3 check scripts in a podman container with the official ruby:3.4-bookworm image and a dummy Rails 8.0.5.1 app, then updated it to 8.0.5.2. We did not test Rails 8.1, Rails 7.2, ImageMagick 7, or an attack.
The problem: 1 image upload can open your Rails server
Active Storage examines every file when the file is attached, so any upload form becomes an entry point.
Active Storage is the Rails part for file uploads: profile photos, order attachments, payment proofs, and documents. When a file is attached, Rails runs an analyzer to read the image size. The image analyzer uses libvips or ImageMagick.
On 4 November 2026, Rails released 8.0.5.2 and 8.1.4.1. These releases close the flaw in the ImageMagick analyzer. The CVE-2026-122006 record came out on the same day, at 14.12 UTC.

The 8.1.4 and 7.2.4 releases of 24 September do not close this flaw. So an app that you updated last month is still vulnerable.
How it works: the ImageMagick analyzer at attach time
This section uses the official advisory summaries. Its purpose is to help you choose the right steps, not to explain an attack.
Summary of CVE-2026-122006
According to the Rails advisory GHSA-f3w6-w445-fwh9, ImageMagick picks a coder from the file contents, and some coders read other files that the image names. Active Storage did not limit the ImageMagick coders. The analyzer runs when a file is attached, so an upload alone starts the flaw.
As a result, an attacker with no login can write files on the server. With the Disk service, the attacker can also read files that the app process can read. The advisory says that this access can grow into code execution or access to other systems.
The advisory gives 3 conditions, and all must be true:
- The app uses
config.active_storage.variant_processor = :mini_magick. This is the default forload_defaults 6.1or older. - The ImageMagick policy on the server does not deny that coder. The Debian and Ubuntu package policies do not deny it.
- The app accepts uploads from untrusted users.

Summary of GHSA-v924-7rp8-4mxh
According to the Rails advisory GHSA-v924-7rp8-4mxh, Active Storage names its temporary file with the extension of the uploaded file name. FFmpeg and ImageMagick pick a decoder from that extension when the contents are not clear. FFmpeg with AviSynth can open server files or load a library.
FFmpeg packages from common Linux distributions do not use AviSynth. The GPL builds from ffmpeg.org use it. The same release closes this flaw.
Critical and high advisories in the 4 November release
| ID | Area | CVSS 3.1 | Severity | Entry |
|---|---|---|---|---|
| GHSA-f3w6-w445-fwh9 (CVE-2026-122006) | Active Storage: ImageMagick image analysis writes and reads server files | 9.8 | Critical | File upload, no login |
| GHSA-v924-7rp8-4mxh | Active Storage: the file name extension picks the video, audio, and image decoder | 8.8 | High | File upload |
| GHSA-wm3x-v3qw-4jh3 | Action Pack: Strong Parameters bypass in Parameters#each_key | 7.5 | High | HTTP request |
| GHSA-8474-xrp6-wh69 | Active Support: DoS in safe_constantize | 7.5 | High | HTTP request |
| GHSA-2gff-2mmg-m73p | Action Dispatch RemoteIp: IP spoofing (8.1 only) | 7.4 | High | Proxy header |
The full list is in the Rails security advisory list. Only GHSA-f3w6-w445-fwh9 has a CVE ID on 5 November 2026.
Exploitation status on 5 November 2026
We found no attack reports, no public attack code, and no CISA KEV entry for CVE-2026-122006. But CVE-2026-66066, an Active Storage flaw in the libvips path, was attacked about 1 month after its patch, according to the Help Net Security report on CVE-2026-66066.
Rama Digital analysis: the Rails patch is public, so attackers can read the code change. Treat this flaw as urgent, and update today.
Who is most at risk
The risk depends on the image processor, the file storage, and who can upload, not only on the version.
| Rails app condition | Risk | Reason |
|---|---|---|
:mini_magick and a public upload form | Highest | 1 upload already starts the analyzer |
Disk service (service: Disk in config/storage.yml) | High | Server files can be read, including secrets |
| ImageMagick with the Debian or Ubuntu default policy | High | The default policy does not deny that coder |
| Rails 7.2 or older | No patch | No fix release exists. Use step 4, then move up a line |
Moved from :vips to :mini_magick after CVE-2026-66066 | Check | That choice avoided the old flaw, but it opens the new flaw |
:vips on a CVE-2026-66066 safe version, or no outside uploads | Low | Still update for the 20 other advisories |

In August 2026, some reports said that ImageMagick users were not affected by CVE-2026-66066. Rama Digital analysis: teams that moved to :mini_magick because of those reports must check again today.
File upload flaws also show up in other online stores, for example in the Magento PolyShell CVE-2026-48356 warning. Teams that use other runtimes must also read the Node2Shell CVE-2026-111497 warning and the PHP2Shell CVE-2026-109618 warning.
Vulnerable and safe versions
The flaw is in the activestorage gem, so the version in Gemfile.lock decides, not the Ruby version.
| Gem | Vulnerable versions | Status on 5 November 2026 | Action |
|---|---|---|---|
| activestorage 8.1 | 8.1.0 to 8.1.4 | Vulnerable | Update to 8.1.4.1 |
| activestorage 8.0 | 8.0.0 to 8.0.5.1 | Vulnerable | Update to 8.0.5.2, then plan 8.1 |
| activestorage 7.2 | All, including 7.2.4 | No patch | Move to 8.1.4.1. Until then, step 4 |
| activestorage 7.1 and older | All | No patch | Move up a line. Until then, step 4 |
| mini_magick | Below 5.1 | A :mini_magick app fails to boot after the update | Update to 5.1 or later (latest 5.4.0) |

The version data comes from the Rails advisory GHSA-f3w6-w445-fwh9, the Rails 8.1.4.1 release, and the Rails 8.0.5.2 release. According to the Rails maintenance page, Rails 8.0 security support ends on 7 November 2026, and Rails 8.1 support runs to 10 October 2027. The 7.2 line is no longer on the list.
Rama Digital analysis: the 4 November release has no 7.2.4.1. So apps on 7.2 and older only have step 4 until they move to 8.1.
Prerequisites before you start
- Access to the app repository and to the server that runs the app.
sudoaccess on the server, for the ImageMagick policy and the restart.- A test suite or a list of pages that you check after the deploy.
- A backup of the database and the
storage/folder if you use the Disk service. - A deploy window of 15 to 30 minutes. The restart stops requests and jobs for a short time.
Step 1: Check the activestorage and mini_magick versions
Save this script as check-version-rails.sh in the app folder. The script reads Gemfile.lock, rates the activestorage and mini_magick versions, and prints the ImageMagick version on the server.
#!/usr/bin/env bash
# Check the activestorage and mini_magick versions for CVE-2026-122006 (GHSA-f3w6-w445-fwh9).
# The script only reads. Use: bash check-version-rails.sh [app folder]
# or type versions by hand: bash check-version-rails.sh activestorage=7.2.4 mini_magick=5.0.1
set -u
older_than() { [ "$1" != "$2" ] && [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n 1)" = "$1" ]; }
rate_activestorage() {
local v=$1
case "$v" in
8.1.*) if older_than "$v" 8.1.4.1; then echo "VULNERABLE: update to 8.1.4.1"; else echo "SAFE from CVE-2026-122006"; fi ;;
8.0.*) if older_than "$v" 8.0.5.2; then echo "VULNERABLE: update to 8.0.5.2, then plan 8.1 (8.0 security support ends 7 Nov 2026)"
else echo "SAFE from CVE-2026-122006, plan 8.1 (8.0 security support ends 7 Nov 2026)"; fi ;;
*) echo "NO PATCH: move to 8.1.4.1, until then do step 4" ;;
esac
}
rate_66066() {
local v=$1 limit
case "$v" in
8.1.*) limit=8.1.3.1 ;; 8.0.*) limit=8.0.5.1 ;; 7.*) limit=7.2.3.2 ;; *) echo "check: old line"; return ;;
esac
if older_than "$v" "$limit"; then echo "VULNERABLE too (safe in $limit)"; else echo "safe"; fi
}
rate_minimagick() {
if older_than "$1" 5.1; then echo "CHECK: below 5.1, a :mini_magick app fails to boot after the update. Run bundle update mini_magick"
else echo "OK (5.1 or later)"; fi
}
show() {
local as=$1 mm=$2
echo "activestorage $as: $(rate_activestorage "$as")"
echo " CVE-2026-66066 (libvips, July 2026): $(rate_66066 "$as")"
if [ -n "$mm" ]; then echo "mini_magick $mm: $(rate_minimagick "$mm")"; else echo "mini_magick: not in Gemfile.lock"; fi
}
if [ $# -gt 0 ] && [[ "$1" == *=* ]]; then
AS=""; MM=""
for arg in "$@"; do
case "$arg" in activestorage=*) AS=${arg#*=} ;; mini_magick=*) MM=${arg#*=} ;; esac
done
[ -n "$AS" ] && show "$AS" "$MM"
exit 0
fi
APP=${1:-.}
LOCK="$APP/Gemfile.lock"
[ -f "$LOCK" ] || { echo "Gemfile.lock not found in $APP"; exit 1; }
AS=$(sed -n 's/^ activestorage (\([0-9][^)]*\))$/\1/p' "$LOCK" | head -n 1)
MM=$(sed -n 's/^ mini_magick (\([0-9][^)]*\))$/\1/p' "$LOCK" | head -n 1)
RAILS=$(sed -n 's/^ rails (\([0-9][^)]*\))$/\1/p' "$LOCK" | head -n 1)
echo "== App: $(cd "$APP" && pwd), rails ${RAILS:-none}"
if [ -z "$AS" ]; then echo "activestorage: not used. CVE-2026-122006 does not apply"; exit 0; fi
show "$AS" "$MM"
if command -v magick >/dev/null 2>&1; then IM=$(magick -version | head -n 1)
elif command -v convert >/dev/null 2>&1; then IM=$(convert -version | head -n 1)
else IM="not installed on this machine"; fi
echo "ImageMagick: ${IM#Version: }"
# In the Rails app folder (the folder that holds Gemfile.lock)
bash check-version-rails.sh .
# Check versions that you copied from another server
bash check-version-rails.sh activestorage=7.2.4 mini_magick=5.0.1
# Manual check without the script
bundle exec rails -v
grep -E '^ (activestorage|mini_magick) ' Gemfile.lock
convert -version | head -n 1

The script also rates CVE-2026-66066, because an app that is behind on one flaw is often behind on another.
Check the result: "VULNERABLE" or "NO PATCH" means go to steps 2 and 3 today. "SAFE" still means run step 5, because the flaw existed before you updated.
Step 2: Check the processor, the policy, and the file storage
This step answers the 3 advisory conditions for your app.
Save this script as check-exposure-rails.sh. The script reads variant_processor and load_defaults, the ImageMagick policy, the service in config/storage.yml, the models with attachments, and the video analyzers.
#!/usr/bin/env bash
# Check the 3 conditions of CVE-2026-122006 and the video analyzers of GHSA-v924-7rp8-4mxh in a Rails app.
# The script only reads. Use: bash check-exposure-rails.sh [app folder] [environment]
set -u
APP=${1:-.}
ENVN=${2:-production}
cd "$APP" || exit 1
CFG="config/application.rb config/environments/$ENVN.rb"
[ -d config/initializers ] && CFG="$CFG $(ls config/initializers/*.rb 2>/dev/null | tr '\n' ' ')"
echo "== 1. Image processor (condition 1)"
VP=$(grep -h -E '^[^#]*variant_processor *=' $CFG 2>/dev/null | tail -n 1 | sed 's/.*= *//')
LD=$(grep -h -E '^[^#]*load_defaults' config/application.rb | head -n 1 | grep -o -E '[0-9]+\.[0-9]+')
if [ -n "$VP" ]; then echo "variant_processor = $VP (set in config)"
elif [ -n "$LD" ] && [ "$(printf '%s\n6.1\n' "$LD" | sort -V | tail -n 1)" = "6.1" ]; then VP=":mini_magick"; echo "variant_processor = :mini_magick (default of load_defaults $LD)"
else VP=":vips"; echo "variant_processor = :vips (default of load_defaults ${LD:-?})"; fi
case "$VP" in *mini_magick*) echo " OPEN: the ImageMagick analyzer runs when a file is attached" ;; *) echo " Condition 1 is not met for CVE-2026-122006" ;; esac
echo "== 2. ImageMagick policy (condition 2)"
if command -v magick >/dev/null 2>&1; then IM="magick"; elif command -v convert >/dev/null 2>&1; then IM="convert"; else IM=""; fi
rate_policy() {
local POL RULES result="" item kind pat
POL=$($IM -list policy 2>/dev/null)
echo "$POL" | grep -E '^Path:' | sed 's/^/ /'
# One line per rule: kind, rights, pattern. Example: Coder None MSL
RULES=$(echo "$POL" | awk '/Policy:/{t=$2; r=""} /rights:/{r=$2} /pattern:/{print t, r, $2}')
for item in "Coder MSL" "Delegate gs" "Coder PS" "Coder PDF"; do
kind=${item% *}; pat=${item#* }
if echo "$RULES" | grep -q -E "^$kind None (.*[{,]$pat[,}].*|$pat|\*)$"; then result="$result $pat=denied"
else result="$result $pat=NOT-DENIED"; fi
done
echo " $result"
}
SP=$(ls -d "$(bundle exec ruby -e 'print Gem.loaded_specs["activestorage"]&.full_gem_path' 2>/dev/null)"/lib/active_storage/image_magick/policy.xml 2>/dev/null)
if [ -z "$IM" ]; then echo "ImageMagick is not installed on this machine"
else
echo "System policy:"; rate_policy
if [ -n "$SP" ]; then echo "Policy from activestorage (active through MiniMagick.cli_env after a restart):"; MAGICK_CONFIGURE_PATH=$(dirname "$SP") rate_policy
else echo "Policy from activestorage: NONE (vulnerable version, or bundle did not run)"; fi
fi
echo "== 3. File storage"
SV=$(grep -h -E '^[^#]*active_storage\.service *=' config/environments/$ENVN.rb 2>/dev/null | tail -n 1 | sed 's/.*= *:*//')
if [ -n "$SV" ] && [ -f config/storage.yml ]; then
JN=$(awk -v s="$SV:" '$1==s{f=1;next} f&&/^[^ ]/{f=0} f&&$1=="service:"{print $2; exit}' config/storage.yml)
echo "service = $SV ($JN)"
[ "$JN" = "Disk" ] && echo " HIGH: with the Disk service, files on the server can be read. Replace secrets after the update"
else echo "No service found for $ENVN"; fi
echo "== 4. Models that accept attachments (condition 3, manual check)"
grep -r -l -E 'has_(one|many)_attached' app/models 2>/dev/null | sed 's/^/ /'
echo " Check which ones users without a login or unknown users can fill"
echo "== 5. Video and audio analyzers (GHSA-v924-7rp8-4mxh)"
if grep -q -E '^[^#]*(analyzers|previewers) *(=|-=|\.delete)' $CFG 2>/dev/null; then echo " The analyzer or previewer list is changed in config"; else echo " Default list: VideoAnalyzer, AudioAnalyzer, and VideoPreviewer are on"; fi
if command -v ffmpeg >/dev/null 2>&1; then
ffmpeg -hide_banner -buildconf 2>/dev/null | grep -q -i avisynth && echo " HIGH: ffmpeg uses AviSynth" || echo " ffmpeg without AviSynth"
else echo " ffmpeg is not installed: the video analyzers do not run"; fi
bash check-exposure-rails.sh .
# Another environment, for example staging
bash check-exposure-rails.sh . staging

The script reads config files, so it does not see values that you set another way. For the value at run time, use bin/rails runner 'p ActiveStorage.variant_processor'. In our test, this command printed :mini_magick.
Check the result: write down the processor, the MSL and gs results, and the service type. "OPEN" in part 1 and "NOT-DENIED" in part 2 mean the app meets the first 2 conditions.
Step 3: Update, restart, and replace secrets
The update is the only step that closes this flaw and the 20 other advisories. The server reads the new code only after a restart.
# 3a. Update Rails, then mini_magick (tested from 8.0.5.1 to 8.0.5.2)
bundle update rails --conservative
bundle update mini_magick --conservative
grep -E '^ (activestorage|mini_magick) ' Gemfile.lock
# 3b. Check that the app boots and the activestorage policy is active
bin/rails runner 'puts MiniMagick.cli_env["MAGICK_CONFIGURE_PATH"]'
bash check-exposure-rails.sh . | grep -A 11 '== 2'
# Commit Gemfile.lock, deploy, then restart the app server and the job workers.
# systemd example (not tested): sudo systemctl restart puma sidekiq

In our test, bundle update rails did not move mini_magick 5.0.1. The app then failed to boot with a message that Active Storage needs mini_magick 5.1. So always update both gems, then check the boot before the deploy.

3a. Rails 8.1, 8.0, and apps in containers
- Rails 8.1: use the same commands. The correct result: activestorage 8.1.4.1.
- Rails 8.0: update to 8.0.5.2 today. Plan a move to 8.1, because 8.0 security support ends on 7 November 2026.
- Docker image: commit
Gemfile.lock, build the image again, then replace all web and worker containers. - Rails 7.2 or older: no patch exists. Use step 4 today, then plan a move to 8.1.4.1.
3b. Check the active policy after the restart
The safe releases carry an ImageMagick policy inside the gem. Rails sets that policy folder through MiniMagick.cli_env, so every ImageMagick command from MiniMagick uses that policy.
This policy does not apply when the app replaces MiniMagick.cli_env, uses MiniMagick.cli_prefix, or installs its own MiniMagick::Shell. GraphicsMagick also does not read ImageMagick policies. In those cases, use step 4a too.
Apps that make PDF or PostScript previews through ImageMagick can fail after the update. The advisory asks you to allow the gs delegate and the coders that you need again in the host policy.
3c. Replace secrets if you use the Disk service
The update closes the flaw, but it does not undo files that were already read. The Rails advisory GHSA-f3w6-w445-fwh9 asks you to replace secret_key_base and every secret that the app process can read.
# 3c. Disk service: make a new secret_key_base (not tested)
bin/rails secret
# Write the new value in credentials or in the SECRET_KEY_BASE env
EDITOR=nano bin/rails credentials:edit --environment production
Also replace the master key, the contents of config/credentials.yml.enc, the database password, the storage keys, and third-party APIAPIThe official door 2 systems use to exchange data, without anybody copying it by hand.Open the glossary tokens. Do not keep an old secret as a fallback. All login sessions end, and signed Active Storage URLs stop working.

Check the result: the version script prints "SAFE", MiniMagick.cli_env points to the policy folder in the activestorage gem, and the merged policy denies MSL and gs.
Step 4: Reduce the impact until the update is done
This step reduces the impact, but it does not replace the update. The 4 November release closes 20 other advisories that this step does not touch.
Rama Digital analysis: we chose 2 official workarounds from the advisories. Condition: the update cannot run today, or the app uses Rails 7.2 or older. Limit: the advisory says that other attack chains can exist.
4a. Add the activestorage policy to the system ImageMagick policy
# 4a. Take the policy from the activestorage 8.1.4.1 gem, then add it to the system policy
mkdir -p /tmp/work && cd /tmp/work
gem fetch activestorage -v 8.1.4.1 && gem unpack activestorage-8.1.4.1.gem
grep '<policy ' activestorage-8.1.4.1/lib/active_storage/image_magick/policy.xml > rules.xml
# Make sure that the policy file has only 1 </policymap> line
grep -c '</policymap>' /etc/ImageMagick-6/policy.xml
sudo cp /etc/ImageMagick-6/policy.xml /etc/ImageMagick-6/policy.xml.bak
sudo sed -i '/<\/policymap>/e cat /tmp/work/rules.xml' /etc/ImageMagick-6/policy.xml
# Check the result, then check 1 normal image. Replace /srv/toko with your app folder.
bash /srv/toko/check-exposure-rails.sh /srv/toko | grep -A 5 '== 2'
identify /srv/toko/public/icon.png
# ImageMagick 7: replace /etc/ImageMagick-6 with /etc/ImageMagick-7

The gem policy holds 33 rules. The advisory gives 3 minimum rules: deny the MSL coder, the Ghostscript coders, and the gs delegate. We copied all 33 rules, because that matches the behaviour of the safe releases.
In our test, the Debian policy file had only 1 </policymap> line, so the sed command puts the rules just before that line. If the grep -c result is not 1, paste the rules with an editor. Also read the ImageMagick security policy guide.
4b. Remove the video and audio analyzers (GHSA-v924-7rp8-4mxh)
# 4b. config/initializers/active_storage_no_video.rb (GHSA-v924-7rp8-4mxh)
Rails.application.config.active_storage.previewers -= [ActiveStorage::Previewer::VideoPreviewer]
Rails.application.config.active_storage.analyzers -= [ActiveStorage::Analyzer::VideoAnalyzer, ActiveStorage::Analyzer::AudioAnalyzer]
In our test, this initializer left only the 2 image analyzers in the analyzer list, and only the 2 PDF previewers in the previewer list. As a result, video previews and duration data stop until you update.
Check the result: the exposure script prints "MSL=denied gs=denied" for the system policy, normal images still load, and part 5 prints "The analyzer or previewer list is changed".
Step 5: Look for signs of use
The flaw existed before you updated, so look for signs from the time before the update too.
Save this script as check-signs-rails.sh. The script looks for text or XML files in the storage folder, new files in the app folder, and ImageMagick errors in the production log.
#!/usr/bin/env bash
# Find signs of CVE-2026-122006 use in a Rails app. The script only reads.
# Use: bash check-signs-rails.sh <app folder> <since YYYY-MM-DD> [Disk service folder]
set -u
APP=${1:?app folder}
SINCE=${2:?start date, example 2026-10-01}
STORE=${3:-$APP/storage}
LOG="$APP/log/production.log"
SIGNS=0; CHECKS=0
sign() { echo " SIGN: $1"; SIGNS=$((SIGNS + 1)); }
check() { echo " CHECK: $1"; CHECKS=$((CHECKS + 1)); }
echo "== 1. Files in the storage folder that are not images, video, or PDF"
if [ -d "$STORE" ]; then
while IFS= read -r f; do
m=$(file -b --mime-type "$f")
case "$m" in
image/svg+xml|text/*|application/postscript|application/xml) check "$m ${f#"$STORE"/}" ;;
esac
done < <(find "$STORE" -type f -newermt "$SINCE" ! -name '*.sqlite3*' 2>/dev/null)
else echo " Folder $STORE not found (not the Disk service, check your bucket another way)"; fi
echo "== 2. New or changed files in the app folder, outside storage, tmp, and log"
while IFS= read -r f; do
rel=${f#"$APP"/}
case "$rel" in
public/*.rb|public/*.erb|public/*.php|public/*.sh|public/*.html) sign "new script or page file in $rel" ;;
app/*|config/*|lib/*|public/*|bin/*) check "changed since $SINCE: $rel" ;;
esac
done < <(find "$APP" \( -path "$APP/storage" -o -path "$APP/tmp" -o -path "$APP/log" -o -path "$APP/.git" -o -path "$APP/node_modules" -o -path "$APP/vendor" \) -prune -o -type f -newermt "$SINCE" -print 2>/dev/null)
echo "== 3. ImageMagick and analyzer errors in the log"
if [ -f "$LOG" ]; then
n=$(grep -c -E 'not allowed by the security policy|MiniMagick::(Error|Invalid)|ActiveStorage::AnalyzeJob.*(Error|failed)' "$LOG")
if [ "$n" -gt 0 ]; then check "$n ImageMagick or AnalyzeJob error lines in ${LOG#"$APP"/}"
grep -E 'not allowed by the security policy|MiniMagick::(Error|Invalid)|ActiveStorage::AnalyzeJob.*(Error|failed)' "$LOG" | tail -n 3 | cut -c1-110 | sed 's/^/ /'; fi
else echo " ${LOG#"$APP"/} not found"; fi
echo "== Result: SIGNS $SIGNS, CHECKS $CHECKS"
echo "No sign does not prove safety. Disk service: replace secret_key_base and credentials after the update."
bash check-signs-rails.sh . 2026-10-01
# Disk service with a folder outside the app
bash check-signs-rails.sh . 2026-10-01 /var/lib/app/storage


Normal PDF and image uploads do not show in the result. Text or XML files in storage can be valid, for example CSV or SVG, so the result is CHECK, not SIGN. For S3 or GCS buckets, look for blobs with an image content_type whose contents are not an image.
Check the result: the script prints "SIGNS 0", and every CHECK has an explanation. An attacker can delete logs, so no sign does not prove safety.
If you find even 1 sign, keep the logs and the storage folder as evidence. Then replace all secrets with step 3c, compare every file in public/ and app/ with the last commit, and deploy again from a clean repository.
If the app holds customer data, Indonesian Law 27/2022 on Personal Data Protection requires a written notice within 3 times 24 hours after a personal data breach. Also read the WordPress core CVE-2026-119977 warning.
Example: 1 morning of response for 3 Rails apps
This simulation uses dummy data. The app names, times, and results are not customer data.
| Time (WIB) | Dummy app | What was checked | Result | Action |
|---|---|---|---|---|
| 08.00 | shop-web (Rails 8.0.5.1, Disk service) | Steps 1 and 2 | VULNERABLE, :mini_magick, Disk | Update this afternoon, then step 3c |
| 08.30 | partner-portal (Rails 7.2.4, S3) | Steps 1 and 2 | NO PATCH, :mini_magick | Step 4a now, plan 8.1 |
| 09.00 | internal-admin (Rails 8.1.4, :vips) | Steps 1 and 2 | VULNERABLE, condition 1 not met | Update in the afternoon window for the 20 other advisories |
| 09.30 | shop-web | Step 5 | SIGNS 1: new page in public/ | Keep evidence, replace secrets, deploy again |
The lesson from the simulation: a safe version does not prove that the app is clean. Step 5 is still needed on every app.
Who installs the patch
This patch is in your app code, so your server provider does not install it for you.
| Service type | Patch owner | What you do |
|---|---|---|
| Rails app on a VPS or your own server | Your team | Steps 1 to 5 |
| Rails app on a PaaS (Heroku, Render, Fly.io) | Your team | Update Gemfile.lock and deploy again. The PaaS only manages servers and system packages |
| App built by an agency or vendor | The vendor, as the contract says | Ask for written proof of the version and the step 5 result |
| App in Docker or Kubernetes | Your team | Build the image again, replace web and worker containers, then step 5 |
Rama Digital recommendation: keep uploads in separate storage, run analyzers in a worker with few permissions, and update gems in the same pipeline as other panels, for example for the GitLab CVE-2026-97229 warning.
Checklist for today
- List all Rails apps that accept uploads. Owner: engineering team. Evidence: a list of names and versions.
- Check the version with step 1. Owner: app developer. Evidence: script output.
- Check exposure with step 2. Owner: app developer. Evidence: script output.
- Apply step 4 on every app that cannot update today. Owner: ops team. Evidence: exposure script output.
- Update Rails and mini_magick, deploy, then restart. Owner: developer and ops team. Evidence: script output after the update.
- Replace secrets if you use the Disk service. Owner: ops team. Evidence: rotation notes.
- Look for signs with step 5. Owner: ops team and security team. Evidence: script output.
Questions and answers
Has this flaw been used in attacks?
On 5 November 2026, we found no attack reports, and CVE-2026-122006 is not on CISA KEV. But an earlier Active Storage flaw was attacked about 1 month after its patch, so update today.
My app uses :vips. Am I safe?
Condition 1 is not met, so CVE-2026-122006 does not apply. Still update, because the same release closes 20 other advisories, including GHSA-v924-7rp8-4mxh.
I use S3, not the Disk service. Must I still update?
Yes. Without the Disk service, the file read risk is smaller, but the file write risk on the server stays.
I still use Rails 7.2. What do I do?
Rails 7.2 gets no patch. Apply steps 4a and 4b today, then plan a move to 8.1.4.1.
Why does my app fail to boot after the update?
The safe releases need mini_magick 5.1 or later when your processor is :mini_magick. Run bundle update mini_magick --conservative, then check the boot again.
Can the ImageMagick policy on the server replace the update?
No. The policy closes the coder path of this flaw, but it does not close the 20 other advisories in the same release.
Do the check scripts change anything on my server?
No. The 3 scripts only read. The commands that change something are only in steps 3 and 4, and each command is written separately.
Next steps
Limits that still apply: step 4 does not replace the update, and the update does not undo secrets that were already read. If your Rails app shows signs in step 5, or you need help with the update and an audit, use Vibe Code Rescue. For 1 urgent problem today, book a 30-minute session.
Sources
- Rails advisory GHSA-f3w6-w445-fwh9: summary, 3 conditions, CVSS 3.1 9.8, safe versions, the policy workaround, and secret rotation.
- Rails advisory GHSA-v924-7rp8-4mxh: the file extension flaw, the AviSynth condition, and the video analyzer workaround.
- Rails security advisory list: 21 advisories on 4 November 2026.
- CVE-2026-122006 record: the official description, CWE-1188, and the publication date of 4 November 2026.
- Rails 8.1.4.1 release and Rails 8.0.5.2 release: the release date of 4 November 2026.
- Rails maintenance page: the end of security support for Rails 8.0 and 8.1.
- Help Net Security report on CVE-2026-66066: attacks on CVE-2026-66066.
- ImageMagick security policy guide: how the ImageMagick policy works.
- CISA KEV: status on 5 November 2026.
- Indonesian Law 27/2022 on Personal Data Protection: the duty to report a personal data breach.




