Integrate Brakeman in your workflow

A while ago I wrote an article about integrating Rubocop into your workflow. Now that we are checking for code style, it is time to improve the workflow even further with a security scanner.

This is where Brakeman enters the scene. Brakeman is a security scanner for your Ruby on Rails apps. Most security scanners require your app to run; Brakeman is different. By looking at the source code, it can detect possible problems!

Why Brakeman

Security is important, but at the same time your team usually does not much time or resources to spend on it. Brakeman makes this easy for you, it will check your entire app for known security flaws in your code. This will help you save time, and eventually money.

Please keep in mind that Brakeman is no silver bullet for security. Keep educating yourself on the aspects of security to make sure you are writing secure software.

Installing Brakeman

To install Brakeman, you simply install a gem. Add the following line to your gem file; preferably in a [:development, :test] block. It is recommended not to lock down to a version, that way you're always using the latest version.

gem "brakeman", require: false  

Running Brakeman

After installing you can directly run Brakeman, there is no need for any configuration.

Run Brakeman like this: $ brakeman.

You get an output similar to the following:

+BRAKEMAN REPORT+

Application path: /Users/jeroen/Development/project_name  
Rails version: 4.2.5.1  
Brakeman version: 3.3.1  
Started at 2016-06-06 09:06:28 +0200  
Duration: 0.784352 seconds  
Checks run: BasicAuth, BasicAuthTimingAttack, ContentTag, CreateWith, CrossSiteScripting, DefaultRoutes, Deserialize, DetailedExceptions, DigestDoS, DynamicFinders, EscapeFunction, Evaluation, Execute, FileAccess, FileDisclosure, FilterSkipping, ForgerySetting, HeaderDoS, I18nXSS, JRubyXML, JSONEncoding, JSONParsing, LinkTo, LinkToHref, MailTo, MassAssignment, MimeTypeDoS, ModelAttrAccessible, ModelAttributes, ModelSerialize, NestedAttributes, NestedAttributesBypass, NumberToCurrency, QuoteTableName, Redirect, RegexDoS, Render, RenderDoS, RenderInline, ResponseSplitting, RouteDoS, SQL, SQLCVEs, SSLVerify, SafeBufferManipulation, SanitizeMethods, SelectTag, SelectVulnerability, Send, SendFile, SessionManipulation, SessionSettings, SimpleFormat, SingleQuotes, SkipBeforeFilter, StripTags, SymbolDoSCVE, TranslateBug, UnsafeReflection, ValidationRegex, WithoutProtection, XMLDoS, YAMLParsing


+SUMMARY+

+-------------------+-------+
| Scanned/Reported  | Total |
+-------------------+-------+
| Controllers       | 12    |
| Models            | 13    |
| Templates         | 47    |
| Errors            | 0     |
| Security Warnings | 1 (1) |
+-------------------+-------+

+----------------------+-------+
| Warning Type         | Total |
+----------------------+-------+
| Cross Site Scripting | 1     |
+----------------------+-------+


View Warnings:

+------------+----------------------+----------------------+---------------------------------------+
| Confidence | Template             | Warning Type         | Message                               |
+------------+----------------------+----------------------+---------------------------------------+
| High       | activities/_activity | Cross Site Scripting | Unescaped model attribute near line 18|
+------------+----------------------+----------------------+---------------------------------------+

After you have ran Brakeman, you will get a list of potential problems; it is important to use your own judgment on those items since not every item on the is an actual problem in your application. This is because Brakeman is extremely paranoid; Use your best judgment!

Ignoring false positives

If Brakeman happens to find any problems in your app that you do not qualify as actual problems, you can easily ignore those.

To create your ignore file, you can run Brakeman with the following command: $ brakeman -I, this will prompt you for an ignore file, using the default is fine here (config/brakeman.ignore.

You then get a question about the run mode, if you run Brakeman for the first time, pick option 1. Inspect all Warnings; if you are trying to add new entries to the ignore list select 2. Hide previously ignored warnings.

Next Brakeman will run like it always does, and with every problem it asks you what you want to do with it:

Confidence: High  
Category: Cross Site Scripting  
Message: Unescaped model attribute  
Code: (Unresolved Model).new.content  
File: app/views/activities/_activity.html.erb  
Line: 18  
Action: (i, n, k, u, a, s, q, ?)  

There are a couple of actions that are worth noting (For the others press ?)

  • i - Add warning to ignore list
  • n - Add warning to ignore list and add a note
  • s - Skip this warning

In this case, we will press i, so the warning gets pushed onto the Ignore list.

When you now run Brakeman again, you will see that it will no longer show this warning.

Run Brakeman as part of your test suite

To make sure you and your team stay on top of the Brakeman errors, it is probably a good idea to run Brakeman as part of your test suite.

In your CI, you can add another pipeline/step with the following command; the -z flag is important here because this makes Brakeman fail with a non-zero code if there is a problem, and thus make your CI fail:

$ bundle exec brakeman -z

We use Codeship for our continues Integration, and setting it up is as easy as adding another bash command to our Test Commands.

alt

Whenever we now push a new commit, Brakeman will be running, and inform us if we introduced a new possible security problem.

Questions?

If you have any comments or questions, please let me know! You can find me on Twitter or by Email