From 4508bf6a96d45c1a116eeb9245e916b7ce41794a Mon Sep 17 00:00:00 2001 From: Chingis S Date: Wed, 16 Sep 2026 16:31:29 +0400 Subject: [PATCH 1/3] Replace vulnerable bundled Ruby gems Update JSON within its 2.x line and net-imap within its 0.5 line. Remove the replaced default JSON implementation so the old vulnerable code is not retained beside the updated gem. --- .github/workflows/workflow.yml | 2 +- Dockerfile | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 2692202..9254134 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -74,7 +74,6 @@ jobs: make test echo "image=$(make --no-print-directory -s image-ref)" >> "$GITHUB_OUTPUT" - name: Scan image - if: github.event_name == 'push' uses: ./.github/actions/grype with: image: docker:${{ steps.build-image.outputs.image }} @@ -114,6 +113,7 @@ jobs: steps: - uses: actions/checkout@v6 - uses: docker/login-action@v4 + if: github.event_name == 'push' with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} diff --git a/Dockerfile b/Dockerfile index e9a4351..89346c8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,6 +28,19 @@ ARG TARGETPLATFORM # Upgrade inherited packages even when their existing versions satisfy dependencies. RUN set -xe; \ apk upgrade --no-cache; \ + # Replace bundled gems, including the old default JSON implementation. + apk add --no-cache --virtual .wodby-gem-build-deps build-base; \ + gem install --no-document json -v '~> 2.19.9'; \ + gem install --no-document net-imap -v '~> 0.5.15'; \ + ruby -rjson -rnet/imap -e 'abort unless Gem.loaded_specs.fetch("json").version >= Gem::Version.new("2.19.9")'; \ + ruby -rrbconfig -rfileutils -e ' \ + root = RbConfig::CONFIG.fetch("rubylibdir"); \ + arch = RbConfig::CONFIG.fetch("archdir"); \ + FileUtils.rm_rf([File.join(root, "json"), File.join(root, "json.rb"), File.join(arch, "json")]); \ + Gem.path.each { |path| Dir.glob(File.join(path, "specifications/default/json-*.gemspec")).each { |spec| FileUtils.rm_f(spec) } }'; \ + gem cleanup json net-imap; \ + ruby -rjson -rnet/imap -e 'abort unless JSON.parse(%q({"ok":true})).fetch("ok")'; \ + apk del .wodby-gem-build-deps; \ \ # Delete existing user/group if uid/gid occupied. existing_group=$(getent group "${WODBY_GROUP_ID}" | cut -d: -f1); \ From f7c7962af1efcd8e428797d2759c29b463272de9 Mon Sep 17 00:00:00 2001 From: Chingis S Date: Wed, 16 Sep 2026 16:34:51 +0400 Subject: [PATCH 2/3] Keep system gem updates outside the application bundle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Install patched bundled gems in Ruby’s system gem directory so root-owned dependency files do not prevent the application user from installing Rails into GEM_HOME. --- Dockerfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 89346c8..5a9627a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,15 +30,16 @@ RUN set -xe; \ apk upgrade --no-cache; \ # Replace bundled gems, including the old default JSON implementation. apk add --no-cache --virtual .wodby-gem-build-deps build-base; \ - gem install --no-document json -v '~> 2.19.9'; \ - gem install --no-document net-imap -v '~> 0.5.15'; \ + system_gems="$(ruby -e 'print Gem.default_dir')"; \ + gem install --install-dir "$system_gems" --no-document json -v '~> 2.19.9'; \ + gem install --install-dir "$system_gems" --no-document net-imap -v '~> 0.5.15'; \ ruby -rjson -rnet/imap -e 'abort unless Gem.loaded_specs.fetch("json").version >= Gem::Version.new("2.19.9")'; \ ruby -rrbconfig -rfileutils -e ' \ root = RbConfig::CONFIG.fetch("rubylibdir"); \ arch = RbConfig::CONFIG.fetch("archdir"); \ FileUtils.rm_rf([File.join(root, "json"), File.join(root, "json.rb"), File.join(arch, "json")]); \ Gem.path.each { |path| Dir.glob(File.join(path, "specifications/default/json-*.gemspec")).each { |spec| FileUtils.rm_f(spec) } }'; \ - gem cleanup json net-imap; \ + gem cleanup --install-dir "$system_gems" json net-imap; \ ruby -rjson -rnet/imap -e 'abort unless JSON.parse(%q({"ok":true})).fetch("ok")'; \ apk del .wodby-gem-build-deps; \ \ From 34a67f909097f082336b2112f812c831a9227e27 Mon Sep 17 00:00:00 2001 From: Chingis S Date: Wed, 16 Sep 2026 16:38:01 +0400 Subject: [PATCH 3/3] Select the system gem directory for cleanup Use GEM_HOME when cleaning up the system gems, since gem cleanup does not accept the install-dir flag. Verified installing and cleaning both patched gems without creating application bundle files. --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 5a9627a..cf6eab8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,7 +39,7 @@ RUN set -xe; \ arch = RbConfig::CONFIG.fetch("archdir"); \ FileUtils.rm_rf([File.join(root, "json"), File.join(root, "json.rb"), File.join(arch, "json")]); \ Gem.path.each { |path| Dir.glob(File.join(path, "specifications/default/json-*.gemspec")).each { |spec| FileUtils.rm_f(spec) } }'; \ - gem cleanup --install-dir "$system_gems" json net-imap; \ + GEM_HOME="$system_gems" gem cleanup json net-imap; \ ruby -rjson -rnet/imap -e 'abort unless JSON.parse(%q({"ok":true})).fetch("ok")'; \ apk del .wodby-gem-build-deps; \ \