Railsアプリケーションにおける脆弱性対策：Brakemanが検知する主な問題

# 概要
これまでRailsアプリケーション上でセキュリティというものを特段意識していませんでした。

調べてみたところ静的解析ツールの「Brakeman」を活用することで、コードベースに潜む様々な脆弱性を早期に発見することができるとのことでした。
この記事では、Brakemanが検知する主な脆弱性とその対策について調べたのでまとめてみました！


# 1.SQLインジェクション

SQLインジェクションは、不正なSQLクエリをアプリケーションに注入する攻撃手法です。

```rb
# 脆弱なコード例
User.where("name = '#{params[:name]}'")

# 安全なコード例
User.where(name: params[:name])
```

ActiveRecordのクエリインターフェースを適切に使用することで、SQLインジェクションを防ぐことができます。
参考: [Rails セキュリティガイド - SQLインジェクション](https://railsguides.jp/security.html#sql%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%A7%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3)


# 2. クロスサイトスクリプティング (XSS)

```rb
# 脆弱なコード例
<%= params[:user_input] %>

# 安全なコード例
<%= h(params[:user_input]) %>
# または Rails 3以降では自動的にエスケープされる
<%= params[:user_input] %>
# HTMLを意図的に出力する場合
<%= raw params[:trusted_input] %>
```

Railsは標準でXSS対策を行っていますが、html_safeやrawを使用する際は注意が必要です。
参考: [Rails セキュリティガイド - XSS対策](https://railsguides.jp/security.html#%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0-xss)


# 3. クロスサイトリクエストフォージェリ (CSRF)
CSRFは、認証済みユーザーに意図しないアクションを実行させる攻撃です。

```rb
# 脆弱なコード例
skip_before_action :verify_authenticity_token

# 安全なコード例
protect_from_forgery with: :exception
```

Railsはデフォルトでprotect_from_forgeryを使用してCSRF対策を行っていますので、不用意に無効化しないようにしましょう。
参考: [Rails セキュリティガイド - CSRF対策](https://railsguides.jp/security.html#%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%AA-csrf)


# 4. パストラバーサル
パストラバーサルは、ファイルシステムの想定外のファイルにアクセスする攻撃です。

```rb
# 脆弱なコード例
File.open(params[:filename])

# 安全なコード例
filename = Rails.root.join('public', params[:filename])
File.open(filename) if File.exist?(filename) && filename.to_s.start_with?(Rails.root.join('public').to_s)
```

ユーザー入力をそのままファイルパスとして使用せず、適切な検証と制限を行いましょう。
参考: [OWASP - パストラバーサル対策](https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html)


# 5.マスアサインメント
マスアサインメントは、モデルの予期しない属性が一括で更新される脆弱性です。

```rb
# 脆弱なコード例
User.new(params[:user])

# 安全なコード例（Strong Parameters使用）
User.new(params.require(:user).permit(:name, :email))
```

Strong Parametersを使用して、更新可能な属性を明示的に指定しましょう。
参考: [Rails ガイド - Strong Parameters](https://railsguides.jp/action_controller_overview.html#strong-parameters)


# 6. リダイレクト先の安全でない指定

```rb
# 脆弱なコード例
redirect_to params[:redirect_url]

# 安全なコード例
redirect_to params[:redirect_url] if params[:redirect_url] =~ /\A\/[a-z0-9_-]+\z/
```

リダイレクト先は常に検証し、許可されたパターンのみを受け入れるようにしましょう。
参考: [OWASP - 安全でないリダイレクト対策](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html)



# 7. コマンドインジェクション
システムコマンドにユーザー入力を渡すことで発生する脆弱性です。

```rb
# 脆弱なコード例
system("ls #{params[:directory]}")

# 安全なコード例
system("ls", params[:directory])
```

コマンド実行時は、引数を別々に渡すメソッドを使用して、シェルインジェクションを防ぎましょう。
参考: [Rails セキュリティガイド - コマンドインジェクション](https://railsguides.jp/security.html#%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%A9%E3%82%A4%E3%83%B3%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%A7%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3)


# まとめ

Brakemanは上記のような脆弱性を自動的に検出し、開発者に警告してくれます！
定期的にBrakemanを実行し、検出された問題に対処することで、Railsアプリケーションのセキュリティを大幅に向上させることができるので活用していきたいですね！

参考: [Brakeman公式ドキュメント](https://brakemanscanner.org/docs/)
参考: [GitHub - Brakeman](https://github.com/presidentbeef/brakeman)