Skip to content

Instantly share code, notes, and snippets.

@bf4
Forked from claudijd/update.rb
Last active October 16, 2017 15:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bf4/4223e83e8becacfb2a8e to your computer and use it in GitHub Desktop.
Save bf4/4223e83e8becacfb2a8e to your computer and use it in GitHub Desktop.
ways to manually update RubyGems without susceptibility to CVE-2015-3900 ref: http://blog.rubygems.org/2015/05/14/CVE-2015-3900.html

ways to manually update RubyGems without susceptibility to CVE-2015-3900 (until there is a new ruby release)

because gem update --system uses rubygems to get the newest rubygems-update gem, and the vulnernability is in rubygems...

via ruby:

\curl -sSL https://gist.github.com/bf4/4223e83e8becacfb2a8e/download | \
  tar xzvf - --include 'update.rb' -O | ruby

via bash:

copy and paste update.bash or

\curl -sSL https://gist.github.com/bf4/4223e83e8becacfb2a8e/download | \
  tar xzvf - --include 'update.bash' -O | bash

refs:

#!/usr/bin/env bash
set -eou pipefail
unset CDPATH
VERSION="${VERSION:-2.6.13}"
# sha256hash reference: http://blog.rubygems.org/2017/08/27/2.6.13-released.html
CHECKSUM="${CHECKSUM:-20abbf7754b82c46aacf12c831339870f4cd1ec069d256d338f1041298badda9}"
GEM_NAME="rubygems-update-${VERSION}.gem"
# USING CDN url, redirected from
# https://api.rubygems.org/gems/rubygems-update-2.6.11.gem and \
# https://rubygems.org/downloads/rubygems-update-2.6.11.gem
# see \curl -sSLI https://api.rubygems.org/gems/rubygems-update-2.6.11.gem
DOWNLOAD_URL="https://rubygems.global.ssl.fastly.net/gems/${GEM_NAME}"
DEBUG="${DEBUG:-false}"
info() { echo -e "[INFO] $*" >&2 ; }
debug() { if [ "$DEBUG" = "true" ]; then echo -e "[DEBUG] $*" >&2 ; fi ; }
error() { echo -e "[ERROR] $*" >&2 ; }
fatal() { echo -e "[ERROR] $*" >&2 ; exit 1 ; }
# Always log finish, bash pseudo-signal: EXIT
# Usage:
# trap finish EXIT
# Optional:
# Will execute a 'cleanup' function if defined.
finish() {
debug "Ran script: ${0##*/}"
command -v cleanup &>/dev/null && cleanup
}
# Log errors, if any, bash pseudo-signal: ERR
# Usage:
# trap 'finish_error $LINENO' ERR
finish_error() {
errcode=$?
error "Ran script: ${0##*/}:$1: exited with '${errcode}'."
}
check_deps() {
info "\n"
if command -v ruby &>/dev/null; then
info "Using $(ruby -e 'puts RUBY_DESCRIPTION')\n"
else
info "No Ruby found"
fatal "Aborting..."
fi
}
cleanup() {
debug "Removing '${GEM_NAME}'"
rm -f "${GEM_NAME}" # ensure gem is not present
}
download() {
debug "Downloading '${GEM_NAME}' from '${DOWNLOAD_URL}'"
# shellcheck disable=SC1001
\curl -sSL "$DOWNLOAD_URL" -o "$GEM_NAME"
}
sha256hash() {
openssl dgst -sha256 < "$GEM_NAME"
}
main() {
trap 'finish' EXIT
trap 'finish_error $LINENO' ERR
check_deps
cleanup
if download; then
info "Successfully Downloaded ${GEM_NAME}\n"
else
info "Failed to Download ${GEM_NAME}"
fatal "Aborting...\n"
fi
local expected_hash
expected_hash="$(sha256hash)"
if [ "$CHECKSUM" = "${expected_hash}" ]; then
info "${GEM_NAME} is Verified\n"
else
info "${GEM_NAME} is Not Verified"
debug "Expected\t'$CHECKSUM'"
debug "Actual\t'$expected_hash'"
fatal "Aborting...\n"
fi
info "installing..\n"
gem install "${GEM_NAME}"
update_rubygems
}
main
require 'digest'
require 'net/http'
gem_file = 'rubygems-update-2.4.8.gem'
# Reference: https://rubygems.org/gems/rubygems-update/versions/2.4.8
sha256hash = "dbed858db605923d9cc77080de1a5f1ce6ac3c68924877c78665e0d85d7b3e73"
##################################################
# Download the Gem from RubyGems.org (over HTTPS)
##################################################
puts "Downloading #{gem_file}"
if File.exists?(gem_file)
File.unlink(gem_file)
end
puts `wget https://rubygems.org/downloads/#{gem_file}`
if File.exists?(gem_file)
puts "Successfully Downloaded #{gem_file}"
else
puts "Failed to Download #{gem_file}"
puts "Aborting..."
exit
end
##################################################
# Verify the Gem against the SHA265 Hash from RubyGems.org
##################################################
puts "Verifying File against SHA256 hash"
if Digest::SHA256.hexdigest(File.read(gem_file)) == sha256hash
puts "#{gem_file} is Verified"
else
puts "#{gem_file} is Not Verified"
puts "Aborting..."
exit
end
##################################################
# Install the gem manually from downloaded file
##################################################
puts `gem install #{gem_file}`
`update_rubygems`
@bf4
Copy link
Author

bf4 commented Jun 18, 2015

Notes to self:

looks like I need to update https://github.com/bf4/gem-checksum to use sha256. (I wrote this before rubygems.org add checksums to all the gems

@bf4
Copy link
Author

bf4 commented Aug 29, 2017

per http://blog.rubygems.org/2017/08/27/2.6.13-released.html via https://www.ruby-lang.org/en/news/2017/08/29/multiple-vulnerabilities-in-rubygems/

Instead of using rubygems to update rubygems ( gem update --system) let's just download the gem, verify the checksum from the blog post, and install that gem

( \
  export VERSION=2.6.13; \
  export CHECKSUM=20abbf7754b82c46aacf12c831339870f4cd1ec069d256d338f1041298badda9; \
  \curl -sSL https://gist.github.com/bf4/4223e83e8becacfb2a8e/download | \
   tar xzvf - --include '*update.bash' -O | bash
)

The ( .. ) executes the command in a subshell so that it doesn't actually change any environment variables in your terminal session

@bf4
Copy link
Author

bf4 commented Oct 16, 2017

http://blog.rubygems.org/2017/10/09/2.6.14-released.html


( \
  export VERSION=2.6.14; \
  export CHECKSUM=ecaedf77483549e73a33a6779f4769aff6198c7f50df124256cc869cc905ffae; \
  \curl -sSL https://gist.github.com/bf4/4223e83e8becacfb2a8e/download | \
   tar xzvf - --include '*update.bash' -O | bash
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment