Four weeks ago, we blogged about the issue with Rails' built-in anti-CSRF mechanism, protect_from_forgery, where we calculated that over 50,000 Ruby developers were impacted by Cross-site Request Forgery (CSRF) attacks.
Recap
The default configuration for Rails' ActionController::Base
does not automatically include the anti-CSRF mechanism, protect_from_forgery
. There is an open PR in Rails made in December 2016 to change this. Details about the cause of the issue, the vulnerability, and the fix can be read in a previous blog post about the same CSRF issue, in the Rails_admin
gem, here.
The SourceClear platform has evolved to the point where we can run simple experiments like this at will (and automatically on all existing and new releases) and increasingly are able to run much much more sophisticated ones at scale (using true data-science and machine-learning) across Java, Python, Ruby, Go Lang, JavaScript, Objective-C, Swift and Scala. In short we have now evolved into a data company and are starting to put that knowledge and technology into production.
There have been many lessons learned along this journey including starting to understand just how many vulnerabilities, backdoors and signs of malware there are in the open-source ecosystem and how hard some are to detect at scale. I am pretty sure Mark Curphey's keynote at Hack in the Box in Singapore will now be called Hiding in Plain Sight.
One lesson we learned is that given the size of the vulnerability pool (see above) and the responsiveness of the majority of open-source maintainers is that we fundamentally need to re-think our approach to disclosure in open-source. We have run several tests like this and all show similar results.
CSRF Disclosure Summary
We contacted 50 maintainers of affected Rails engines to tell them that they had the issue and suggesting a simple fix. A summary of the state of disclosures can be seen in the chart below.
Of the 50 contacts, 16 promptly resolved the issue. Well done you. 11 others acknowledged the mail but have not yet released a fix 30 days later and one fixed it in silence. The other 23 have not responded to the initial contact or a subsequent reminder.
For most cases, the fix was as simple as adding the protect_from_forgery with: :exception
line right after the Controller which inherits from ActionController::Base
. For more information, the summary of the affected Rails projects can be viewed at this link.
Fix
A fix to enable the anti-CSRF mechanism is simple and usually only requires an additional line in the affected areas. An example fix for most Rails Application would be as follows:
class ApplicationController < ActionController::Base
+ protect_from_forgery with: :exception
+
For APIs, it would be as follows:
class ApplicationController < ActionController::Base
+ protect_from_forgery with: :null_session
+
Conclusion
This type of CSRF vulnerabilities in Rails Applications can be easily prevented and we think CSRF Protection should be on by default.
Disclosure in open-source projects is hard. In our experience the majority of projects when notified neither acknowledge or respond to disclosures and most simply do fix issues issues when reported.