Automated security audits for a Rails application
Published: 2023-10-23 11:00:00

I will show you how you can automate some of the security necessities of a Rails application. If you follow this guide, you will be safe from one of the OWASP Top 10 security issues(<a href="https://owasp.org/www-project-top-ten/2017/A9_2017-Using_Components_with_Known_Vulnerabilities" target="_blank">A9-Using Components with Known Vulnerabilities</a>) and lower the chances of having other vulnerabilities in your codebase. Let's get into it.

Using Components with Known Vulnerabilities is in the OWASP Top 10, but automating a notification about gems with known vulnerabilities is very easy. The <a href="https://github.com/rubysec/bundler-audit" target="_blank">bundler-audit gem</a> covers us there with the `bundle-audit` command:

```
[~/] bundle-audit --help
Commands:
  bundler-audit check [DIR]     # Checks the Gemfile.lock for insecure dependencies
  bundler-audit download        # Downloads ruby-advisory-db
  bundler-audit help [COMMAND]  # Describe available commands or one specific command
  bundler-audit stats           # Prints ruby-advisory-db stats
  bundler-audit update          # Updates the ruby-advisory-db
  bundler-audit version         # Prints the bundler-audit version
```

If you put a check for `bundle audit --update` to your CI workflow, it will check your app for vulnerable dependencies and your pipeline will fail.
Additionally, if you use yarn to manage your javascript dependencies, you can use `yarn audit` to check your dependencies for any known vulnerability.

Here is an example GitHub Action file to do this:

```yaml
# .github/workflows/bundle-audit.yml
name: Bundle Audit
on:
  pull_request:
  schedule:
    - cron: "0 0 * * *"
jobs:
  base:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Setup Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.2
          bundler-cache: true
      - name: Install bundler-audit
        run: gem install bundler-audit
      - name: Check dependencies with known vulnerabilities
        run: bundle-audit --update
      - name: Check javascript dependencies
        run: yarn audit
```

The above action runs bundle audit and yarn audit on every pull request and at midnight every day. You might need to adjust the Ruby version above to the one you are on.

Another low-hanging fruit to improve the security posture of a Ruby on Rails application is to set up static code analyses for potential security issues. There are two gems to help with this: <a href="https://github.com/presidentbeef/brakeman" target="_blank">brakeman</a> and <a href="https://github.com/gregmolnar/spektr" target="_blank">spektr</a>(DISCLAIMER: I am the author of this gem).
These gems analyze your code for potentially vulnerable code and can help to find SQL injections, XSS, and quite a few other issues.<br/>
Using on CI brakeman is more ideal, because it supports ignoring false positives out of the box. Spektr is targeted more towards security professionals running it on a codebase during an assessment.<br/>
Here is an example GitHub Actions file to run brakeman on your codebase on every pull request and once every day:

```yaml
# .github/workflows/brakeman-scan.yml
name: Brakeman Scan
on:
 - pull_request:
 - schedule:
   - cron: "0 0 * * *"

jobs:
  base:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Setup Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.2
          bundler-cache: true
      - name: Install brakeman
        run: gem install brakeman
      - name: Static code analyses for security
        run: brakeman
```

That's it