The
nokogiri
Show archive.org snapshot
gem provides different packages for several platforms. Each platform-specific variant ships pre-built binaries of libxml2
, e.g. x86_64-linux
includes binaries for 64bit Linux on Intel/AMD. This significantly speeds up installation of the gem, as Nokogiri no longer needs to compile libxml2
.
However, this also means that for each security issue with libxml2
, Nokogiri maintainers have to update their pre-built binaries and release a new version of the gem. Then, you need to update and deploy each of your applications that are using nokogiri.
There were numerous security issues with libxml2
in the past, and we maintain a lot of applications.
We want to use our (regularly updated) system libraries because of that.
# Quick check
Nokogiri::VersionInfo.instance.libxml2_using_system?
Instructions
Nokogiri can compile its C extensions against system libraries, but if any matching pre-built binaries are available, it will not compile anything. Hence, we need a variant without binaries.
The following steps summarize what the Nokogiri documentation covers Show archive.org snapshot , with some added explanations.
-
Force installing the
ruby
platform variant of thenokogiri
gem.In your
Gemfile
, specify theforce_ruby_platform
option for the gem. This will download theruby
variant which includes no binaries, only the libxml2 extension source.gem 'nokogiri', force_ruby_platform: true
If you are on Bundler < 2.3.18, either upgrade Bundler (if possible) or use the alternative approaches from the nokogiri docs Show archive.org snapshot .
-
Make sure that the
--use-system-libraries
build option is set when installing thenokogiri
gem.If the
--use-system-libraries
flag is not set, Nokogiri will compile libxml2 from its included sources. This is the same as using the pre-built binaries, just slower to install.Our application environments
If you are a makandra employee and are running your app on makandra servers, you can skip this step.
All servers and developer machines at makandra are already configured using the global Bundler configuration.You need to specify that using the Bundler configuration, either globally, or locally (per project).
-
Locally:
bundle config --local build.nokogiri --use-system-libraries
This writes to a file
.bundle/config
in your project directory. Ensure that it is not gitignored, or your changes are only valid for your machine, not any servers. Inside a Docker environment, this file might be ignored. How to fix. -
Globally:
bundle config --global build.nokogiri --use-system-libraries
This writes to a file in your user home,
~/.bundle/config
.
Use this approach only when your servers are configured the same way, or when they use matching env variables.
-
-
Make sure your
Gemfile.lock
has a correct settings forPLATFORMS
-
Install gems.
bundle install
If you were already using the
ruby
variant of Nokogiri, you must re-install the gem so it compiles against system libraries.bundle pristine nokogiri
-
Your
Gemfile.lock
should now only contain one entry for nokogiri (e.g.nokogiri (1.16.6)
), without any platform-specific suffix. -
Verify that you are using you system's libxml2:
Nokogiri::VersionInfo.instance.libxml2_using_system?
You may also check
Nokogiri::VersionInfo.instance.warnings
for any warnings (though they should appear e.g. when launching a Rails console) orNokogiri::VersionInfo.instance.to_hash
to view more information.Note
If your application uses Spring, run
spring stop
before verifying.