Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rails is not compliant with FIPS 140-2 mode #31203

Closed
jdshewey opened this issue Nov 22, 2017 · 7 comments
Closed

Rails is not compliant with FIPS 140-2 mode #31203

jdshewey opened this issue Nov 22, 2017 · 7 comments

Comments

@jdshewey
Copy link

Steps to reproduce

Enable FIPS 140-2 mode as outlined at https://access.redhat.com/solutions/137833 by:

#install dracut-fips
yum install dracut-fips
#disable prelinking
rpm -q prelink && sed -i '/^PRELINKING/s,yes,no,' /etc/sysconfig/prelink
rpm -q prelink && prelink -uav
#back up existing initramfs
mv -v /boot/initramfs-$(uname -r).img{,.bak}
#rebuild initramfs
dracut
#add fips=1 to kernel command in grub boot menu to enable FIPS
grubby --update-kernel=$(grubby --default-kernel) --args=fips=1
#inform kernel of /boot's uuid during boot (won't boot without this in FIPS mode)
uuid=$(findmnt -no uuid /boot)
[[ -n $uuid ]] && grubby --update-kernel=$(grubby --default-kernel) --args=boot=UUID=${uuid}
#reboot 
reboot

Then verify FIPS mode is enforced:

sysctl crypto.fips_enabled

Now, with this enabled, rails applications may fail - particularly anything that uses Digest::MD5. For example: http://projects.theforeman.org/issues/3511#note-5

A few ways to mitigate this:

  • Use Digest::SHA256 instead
  • Use an MD5 library that does not use OpenSSL. This might be used as a backup, so check if FIPS mode is enabled, then use an alternate (probably slower) library if so.
@vipulnsward
Copy link
Member

Can you also share an example failure when running in this mode.

@jdshewey
Copy link
Author

Sure, with The Foreman example, this results in:

Web application could not be started

An error occurred while starting up the preloader. It exited before signalling successful startup back to 
Phusion Passenger. Please read this article for more information about this problem.
Raw process output:

 --> passenger_native_support was compiled for Ruby API version 2.0.0, but you're currently running a 
Ruby interpreter with API version 2.2.0.
     Refusing to load existing passenger_native_support.
 --> No passenger_native_support.so found for current Ruby interpreter.
     This library provides various optimized routines that make
 Phusion Passenger faster. Please run 'sudo yum install passenger-devel-4.0.53'
     so that Phusion Passenger can compile one on the next run.
 --> Continuing without passenger_native_support.so.
md5_dgst.c(82): OpenSSL internal error, assertion failed: Digest MD5 forbidden in FIPS mode!
/tmp/tmp.uzeojJPxvN: line 1:  3999 Aborted                 ruby /usr/share/passenger/helper-scripts/rack-preloader.rb

At a lower level level:

> ruby -rdigest -e "puts Digest::MD5.hexdigest('hi')"
md5_dgst.c(82): OpenSSL internal error, assertion failed: Digest MD5 forbidden in FIPS mode!
Aborted

@guilleiguaran
Copy link
Member

Rails use MD5 mostly to generate cache keys but changing it in Rails won't be enough, e.g in the example you posted it's failing due to Passenger, not to Rails itself.

@jdshewey
Copy link
Author

jdshewey commented Nov 22, 2017

Regardless of what rails is using MD5 for, it is not compatible with the FIPS 140-2 standard. This means that anybody who faces a NIST audit can't use any Ruby on Rails software that would trigger an MD5 hash (so pretty much no ROR period.) Also, It's not actually passenger that is throwing this error according to passenger. Passenger is spawning another application. I believe that application is The Foreman using ROR. They document this here:

https://github.com/phusion/passenger/wiki/Debugging-application-startup-problems

The application itself may freeze during startup for any reason. It might be loading a huge file that takes forever, it might be frozen while trying to access an NFS share that is down, it might be trying to download a file from S3 during network problems, or it might have an infinitely looping algorithm somewhere.

Solution for this problem: isolate the offending code in your application.

Further reading: https://www.phusionpassenger.com/library/indepth/ruby/spawn_methods/

Or in this case, it's not slow, but crashing due to the fact that Digest MD5 forbidden in FIPS mode! and they seem to think it might be and issue with ActiveRecord. Foreman certainly has a few instances where MD5 is used, but they are working on remediating that but there's no point in cleaning up the Foreman code, if Rails is just going to crash instead.

In short, whether or not it is passenger crashing in this instance is moot: Rails has some work to do to meet the FIPS 140-2 standard.

@guilleiguaran
Copy link
Member

they seem to think it might be an issue with ActiveRecord

Yes, we are using MD5 to generate the cache key for collections in ActiveRecord:

query_signature = Digest::MD5.hexdigest(collection.to_sql)

All the other usages of MD5 are in ActionPack (for cache keys and ETags) and ActiveStorage (for the integrity of uploads).

I think that moving all the uses of MD5 to SHA256 isn't easy as swap the constant, making this change will blow all the existing cache entries during the upgrade of Rails so we should treat this carefully.

@matthewd
Copy link
Member

Rails has some work to do to meet the FIPS 140-2 standard

No, someone who cares about Rails "meeting" the FIPS 140-2 standard has some work to do.

I'm closing this as a feature request (which we don't use issues for). PRs welcome, but I don't see "use a different MD5 library" as a compelling option; if you want to pursue that route, I'd suggest pushing the change upstream into Digest itself (though it feels like a rather pointless workaround).

@patrickwilkes
Copy link

For anyone else who struggles with FIPS and stumbles across this issue, the problem has been addressed in Rails 5.2, have a look at these two PRs - #31289 & #31651.

Use the Rails.application.config.active_support.use_sha1_digests = true configuration option, which appears in new_framework_defaults_5_2.rb.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants