Brakemanを自作アプリに導入してみた
現在、フィヨルドブートキャンブ内にて、@Sakiさん主催の「パーフェクト Ruby on Rails輪読会」が行われています。 こちらの本、大変参考になりますが、なんだか難しいし、もう少し深掘りがしたい!と思いまして、このブログに予習・復習した内容を簡単に載せていきたいなと考えています。
9-3-2
Brakemanはアプリの脆弱性を静的解析してくれる便利なgem
RailsConfでの発表の動画を見る限り、読み方は「ブレーキマン」ではなく「ブレークマン」っぽい。
使い所はCIで定期実行して、脆弱性につながる疑いのコードを事前に検知するとよいとのこと。
XSSやSQLインジェクションなどの脆弱性を確認してくれ、その確認項目は30項目くらいありそう。
パRailsで作ったアプリでは警告等が出なかったので、せっかくなので自作アプリのNursePicksに導入してみる。
group :development do gem 'brakeman' end
bundle exec brakeman
で実行してみると、レポートが作成された。
== Brakeman Report == Application Path: work/nursepicks Rails Version: 6.1.6 Brakeman Version: 5.3.1 Scan Date: 2022-11-16 17:06:57 +0900 Duration: 1.213567 seconds Checks Run: BasicAuth, BasicAuthTimingAttack, CSRFTokenForgeryCVE, ContentTag, CookieSerialization, CreateWith, CrossSiteScripting, DefaultRoutes, Deserialize, DetailedExceptions, DigestDoS, DynamicFinders, EOLRails, EOLRuby, EscapeFunction, Evaluation, Execute, FileAccess, FileDisclosure, FilterSkipping, ForgerySetting, HeaderDoS, I18nXSS, JRubyXML, JSONEncoding, JSONEntityEscape, JSONParsing, LinkTo, LinkToHref, MailTo, MassAssignment, MimeTypeDoS, ModelAttrAccessible, ModelAttributes, ModelSerialize, NestedAttributes, NestedAttributesBypass, NumberToCurrency, PageCachingCVE, PermitAttributes, QuoteTableName, Redirect, RegexDoS, Render, RenderDoS, RenderInline, ResponseSplitting, RouteDoS, SQL, SQLCVEs, SSLVerify, SafeBufferManipulation, SanitizeConfigCve, SanitizeMethods, SelectTag, SelectVulnerability, Send, SendFile, SessionManipulation, SessionSettings, SimpleFormat, SingleQuotes, SkipBeforeFilter, SprocketsPathTraversal, StripTags, SymbolDoSCVE, TemplateInjection, TranslateBug, UnsafeReflection, UnsafeReflectionMethods, ValidationRegex, VerbConfusion, WithoutProtection, XMLDoS, YAMLParsing == Overview == Controllers: 11 Models: 6 Templates: 17 Errors: 0 Security Warnings: 4 == Warning Types == Cross-Site Scripting: 4 Cross-Site Scripting: 4 == Warnings == Confidence: Weak Category: Cross-Site Scripting Check: SanitizeConfigCve Message: rails-html-sanitizer 1.4.2 is vulnerable to cross-site scripting when `select` and `style` tags are allowed (CVE- 2022-32209). Upgrade to 1.4.3 or newer File: Gemfile.lock Line: 273 Confidence: Weak Category: Cross-Site Scripting Check: LinkToHref Message: Potentially unsafe model attribute in `link_to` href Code: link_to(Post.find(params[:post_id]).url, :target => :_blank, :rel => "noopener", :class => "post-image") File: app/views/posts/show.html.slim Line: 5 Confidence: Weak Category: Cross-Site Scripting Check: LinkToHref Message: Potentially unsafe model attribute in `link_to` href Code: link_to(Post.find(params[:post_id]).title, Post.find(params[:post_id]).url, :target => :_blank, :rel => "noopener") File: app/views/posts/show.html.slim Line: 9 Confidence: Weak Category: Cross-Site Scripting Check: LinkToHref Message: Potentially unsafe model attribute in `link_to` href Code: link_to(User.find(params[:id]).url, User.find(params[:id]).url) File: app/views/users/show.html.slim Line: 11
何やらCross-Site Scripting
で4件の警告あり。
内訳としては3件がLinkToHref
、1件がSanitizeConfigCve
1つ1つの警告の詳細についてはbrakeman/docs/warning_types/
link_to
メソッドの指摘に関しては
Brakemanはlink_toメソッドを使って作成されたURLにユーザー入力が含まれていると警告を発します。Railsにはこの方法で作成されたURLを安全にする方法がないため(例:プロトコルをHTTP(S)に限定する、など)、安全なメソッドを無視したい場合は次のオプションを使ってください。 Brakeman: Options
伊藤さんが翻訳してくれている。
ということで今回はurl
メソッドで怒られてるので、--url-safe-methods url
とオプションをつけておく。
あとはrails-html-sanitizer
をアップグレード。
対象コードを修正すると、
== Overview == Controllers: 11 Models: 6 Templates: 17 Errors: 0 Security Warnings: 0 == Warning Types == No warnings found
ということで修正完了。
GithubActionsにも設定、CIでも実行できるようにした。
- name: Breakeman run: bundle exec brakeman --url-safe-methods url
ちなみにbrakeman -I
コマンドで無視する警告を設定できるとのこと
参考記事:Brakemanで無視する警告の設定の仕方 - Qiita
breakman -A
でデフォルトでは検証しない、すべてのチェックも実行してみたが、Unscoped Findなど偽陽性のものも多いので、この設定をしておけばよさそう。
その他参考記事
- gem BrakemanでRails製アプリケーションの脆弱性を検知する | GMOアドパートナーズ TECH BLOG byGMO
- Rails環境でセキュリティ向上のため、Brakeman gemを導入&脆弱性対策を実施しました - Zeals TECH BLOG
セキュリティ対策ができるし、特に自作アプリでは変更のたびに誰かにレビューしてもらうことはないので、こういった静的解析ツールは便利!