さかなソフトブログ

プログラミングやソフトウェア開発に関する情報

ツール

BrakemanでRailsセキュリティチェックを行う

更新日:

Brakeman - Rails Security Scanner というgemを使うとCSRFやXSS等Railsに施されているRailに乗れていないマナーの悪いコードを静的解析してくれるツールです。

Railsはバージョンが上がるにつれて、例えばRails4ではMass Assignment脆弱性に対応したStrong Parametersに対応するといったように近年ホットになった脆弱性に関してはかなり早いスピードで対応してくれます。

世の中には外部からアプリをブラックボックス化したところで動的解析を行って脆弱性チェックを行うサービスもある様ですが、個人的にはRailsに乗っている限りは金融取引など、よほどクリティカルな情報を扱う様なアプリ以外はBrakemanで軽くチェックしてwarningを潰す程度でリリースしても良いんじゃ無いかと思います。

スポンサーリンク

正方形336


使い方

Gemfileにbrakemanを追加します。2018/3/13現在の最新バージョンは2018/2/21にリリースされた4.2.0で比較的頻繁に更新されており安心して使えます:

group :development do
  gem 'brakeman'
end

あとはbundle installして、brakemanコマンドをRailsアプリフォルダ上で打つだけです:

$ brakeman

実際にアプリで実行してみる

web-k/tiramisu: WebSocket(Pusher)を使ったチャット&囲碁Railsアプリで実際に組み込んで実行してみました。すると4つほどwarningが出ました:

== Brakeman Report ==

Application Path: /home/toshi/tiramisu
Rails Version: 5.1.5
Brakeman Version: 4.2.0
Scan Date: 2018-03-13 10:03:35 +0900
Duration: 0.52445335 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, PermitAttributes, 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

== Overview ==

Controllers: 6
Models: 7
Templates: 8
Errors: 0
Security Warnings: 4

== Warning Types ==

Cross-Site Request Forgery: 2
Cross-Site Scripting: 1
Session Setting: 1

== Warnings ==

Confidence: High
Category: Cross-Site Request Forgery
Check: ForgerySetting
Message: 'protect_from_forgery' should be called in AuthenticationController
File: app/controllers/authentication_controller.rb
Line: 1

Confidence: High
Category: Cross-Site Scripting
Check: CrossSiteScripting
Message: Unescaped model attribute
Code: Channel.new(params.require(:channel).permit(:name)).name
File: app/views/layouts/application.html.erb
Line: 43

Confidence: High
Category: Session Setting
Check: SessionSettings
Message: Session secret should not be included in version control
File: config/initializers/secret_token.rb
Line: 12

Confidence: Medium
Category: Cross-Site Request Forgery
Check: ForgerySetting
Message: protect_from_forgery should be configured with 'with: :exception'
File: app/controllers/application_controller.rb

CSRFが2つとXSSが1つ、セッション絡みで1つある様です。ワーニングの詳しい内容についてはBrakeman - Rails Security Scanner: Warning Typesから詳しい説明が参照出来ると思います。一つづつ見ていきます。

Check: ForgerySetting

1つめのAuthenticationControllerprotect_from_forgeryが呼ばれてないというのをみてソースを見てみると、

class AuthenticationController < ActionController::Base

となっていてprotect_from_forgeryを呼んでいるApplicationControllerを継承してませんでした。特に理由も無いので継承しておきます:

class AuthenticationController < ApplicationController

Check: CrossSiteScripting

2つめはXSSの警告でソースを見ると、

 <div id="channel_name_static" style="display:inline;"><%== @channel.name %></div>
 <div id="channel_name_edit" style="display:none;"><%== f.text_field :name %></div>

で、<%== @channel.name %><%==はHTMLエスケープしてしないで出力となってました。この部分は@channel.nameをユーザー入力で変更出来るようにしていたみたいですが、<script>alert();</script>をぶち込んで見ると見事にXSS発生w・・・なんでこうしたかは過去のコード過ぎて分かりませんが、エスケープしても正常に動作するのでエスケープしておきます:

 <div id="channel_name_static" style="display:inline;"><%= @channel.name %></div>
 <div id="channel_name_edit" style="display:none;"><%= f.text_field :name %></div>

Check: SessionSettings

3つめのSessionSettings警告はBrakeman - Rails Security Scanner: Session Settingsを見る(日本語訳す)と、

config/initializers/secret_token.rbがリポジトリに含まれていると警告します。secret_token.rbは.gitignoreで除外することを推奨します。

とのこと。素直に外せば良さそうです。また、secret_token.rbは4.0以前で使っていたもので4.1以降はconfig/secrets.ymlを利用している様なのでgit rm config/initializers/secret_token.rbしてしまいます。

Check: ForgerySetting

4つめの警告はCSRFに引っかかった場合の挙動を指定しろってことなので、例外吐いて弾くようにした:

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

積極的にBrakemanを活用しよう

修正した内容はBrakemanによるセキュリティ警告の対処 · web-k/tiramisu@ff13f9aとなり、これで全ての警告が消えました。日頃ちょっとセキュリティを気にしておけばそれ程警告も出ないでしょうからコミット前、若しくはリリース前にbrakemanを走らせて対処しておくと良いでしょう。

正方形336

正方形336

-ツール
-, ,

Copyright© さかなソフトブログ , 2019 All Rights Reserved.