こんにちは。ペパボEC事業部でソフトウェアエンジニアをしている小野です。テックブログを書くのは約1年ぶりになります。さて、本日はネットショップ作成サービスのカラーミーショップに、JP-Secureが提供するホスト型WAFであるSiteGuard Liteを導入するにあたり作成したRubyライブラリを2つご紹介します。
SiteGuard Liteについて
SiteGuard Liteは公式ページによると以下のように説明されています。
SiteGuard Lite(サイトガードライト)は、ウェブサーバーのモジュールとして動作するホスト型WAF製品です。ウェブサーバー自体にインストールするため、専用ハードウェアが必要ありません。できるだけシンプルに導入したいお客様に最適な製品です。
SiteGuard Lite(ホスト型) | WAF製品・サービス | 国産WAFのJP-Secure
カラーミーショップではセキュリティ対策を速で強固にすべく、すでに社内のホスティング事業部で実績のあったSiteGuard Liteの導入を進めることになりました。
作成したライブラリについて
おそらくどのWAF製品でも同じだと思いますが、SiteGuard Liteを導入する際の障壁の1つとして「過剰検知をいかに減らすか」という課題がありました。一般的にWAFは検知漏れ(False Nagative)よりも過剰検知(False Positive)するように初期設定されています。過剰検知するというのはユーザーから見ると正常なはずのリクエストがブロックされてしまうことになり、不満に直結します。したがってアプリケーションの特性に応じて検知ルールのチューニングが必要になります。今回はざっくりと以下のステップでチューニングを行いました。
- 検知ログを確認して過剰検知した内容を知る
- 過剰検知しないように除外ルールをカスタマイズする
その中で、チューニング作業を少しでもプログラマブルに行うためのRubyライブラリを2つ作成したのでご紹介します。
siteguard_lite-log-parser
pepabo/siteguard_lite-log-parser: A log parser for SiteGuard Lite WAF
1つ目は「1. 検知ログを確認して過剰検知した内容を知る」で利用するログ解析用のライブラリです。SiteGuard Liteには何種類かのログファイルがありますが、現時点では検知ログのみに対応しています。
SiteGuard Liteには管理画面があり、そこで検知ログの確認やダウンロードができますし、グラフで集計結果を見ることもできます。しかしながら、より柔軟なログの確認や集計をしたい場合は、ログをパースしてプログラムから扱えると便利です。
簡単な例を示します。
#!/usr/bin/env ruby
require 'siteguard_lite/log/parser'
log_str = <<'EOD'
1531397957.965300 0 192.168.0.100 TCP_MISS/000 0 GET http://example.com/?p=<script>alert(%22hello%22)</script> - DIRECT/192.168.1.100 - DETECT-STAT:WAF:RULE_SIG/PART_PARAM_VALUE|PART_GET_PARAM/p/OFFICIAL/00102001/xss-tag-1::%3cscript%3e:%3cscript%3ealert(%22hello%22)%3c/script%3e: ACTION:BLOCK: JUDGE:BLOCK:0: SEARCH-KEY:1531397957.965300.76402:
EOD
parser = SiteguardLiteLogParser.new('detect')
pp parser.parse(log_str)
実行時の出力結果は以下の通りです。
{"time_epoch"=>"1531397957.965300",
"conn_time"=>"0",
"client_ip"=>"192.168.0.100",
"file_size"=>"0",
"http_method"=>"GET",
"url"=>"http://example.com/?p=<script>alert(%22hello%22)</script>",
"hierarchy_code"=>"DIRECT/192.168.1.100",
"content_type"=>"-",
"detect_stat"=>
"DETECT-STAT:WAF:RULE_SIG/PART_PARAM_VALUE|PART_GET_PARAM/p/OFFICIAL/00102001/xss-tag-1::%3cscript%3e:%3cscript%3ealert(%22hello%22)%3c/script%3e:",
"detect_name"=>
"RULE_SIG/PART_PARAM_VALUE|PART_GET_PARAM/p/OFFICIAL/00102001/xss-tag-1",
"detect_name_rule"=>"RULE_SIG",
"rule_sig_part"=>"PART_PARAM_VALUE|PART_GET_PARAM",
"rule_sig_name"=>"p",
"rule_sig_file"=>"OFFICIAL",
"rule_sig_id"=>"00102001",
"rule_sig_signature_name"=>"xss-tag-1",
"rule_params_num_part"=>nil,
"rule_params_num_threshold"=>nil,
"detect_str"=>"%3cscript%3e",
"detect_str_all"=>"%3cscript%3ealert(%22hello%22)%3c/script%3e",
"action"=>"ACTION:BLOCK:",
"action_str"=>"BLOCK",
"judge"=>"JUDGE:BLOCK:0:",
"judge_str"=>"BLOCK",
"monitor_url"=>"0",
"search_key"=>"SEARCH-KEY:1531397957.965300.76402:",
"search_key_time_epoch"=>"1531397957.965300",
"search_key_nginx_request_id"=>"76402"}
siteguard_lite-custom_signature
2つ目は「2. 過剰検知しないように除外ルールをカスタマイズする」で利用するライブラリです。SiteGuard Liteでは検知ルールのカスタマイズが可能であり、その設定ファイルはタブ区切り形式のファイルになっています。このライブラリを使うと、そのタブ区切り形式のファイルをYAML形式のファイルと相互変換できるようになります。
そもそも、検知ルールのカスタマイズ設定はSiteGuard Liteの管理画面から編集可能ですが、我々はこの設定ファイルもプログラムコードと同じように管理したいと考えました。それはつまり
- GitHub Enterpriseのリポジトリで管理されている
- 変更するときはPull Requestを出してレビューする
- Pull Requestをマージしたらサーバーにデプロイする
ということです。そのためにはタブ区切り形式というのは編集が困難なフォーマットだったため、YAML形式で書けるようにライブラリを作りました。
簡単な例を示します。
#!/usr/bin/env ruby
require 'siteguard_lite/custom_signature'
text = <<'EOD'
ON NONE exclude-xss-try-1 URL PCRE_CASELESS ^http://example\\.com paramパラメータでxss-try-1を除外
ON NONE exclude-xss-try-1 PARAM_NAME PCRE_CASELESS,AND,EXCLUDE_OFFICIAL(^xss-try-1$) ^param$ paramパラメータでxss-try-1を除外
EOD
rules = SiteguardLite::CustomSignature.load_text(text)
puts SiteguardLite::CustomSignature.dump_yaml(rules)
実行時の出力結果は以下の通りです。
---
rules:
- name: exclude-xss-try-1
comment: paramパラメータでxss-try-1を除外
exclusion_action: EXCLUDE_OFFICIAL
signature: "^xss-try-1$"
conditions:
- key: URL
value: "^http://example\\\\.com"
comparison_methods:
- PCRE_CASELESS
- key: PARAM_NAME
value: "^param$"
comparison_methods:
- PCRE_CASELESS
- AND
まとめ
SiteGuard Liteを導入した時に作成したRubyライブラリを2つご紹介しました。
我々は普段ソフトウェアを開発する仕事をしています。このような既製の製品を導入するという仕事であっても、コードを書いて楽をすることはできないか?自分たちがもっと扱いやすい形にできないか?ということを考えてやっていくと、仕事がもっとおもしろくできるのではないか?と考えています。またそうやって作成したソフトウェアをオープンソースとして公開することで、少しでも誰かの役に立てると嬉しいなと思っています。
最後になりますが、ライブラリの公開に際しては事前にJP-Secureの方々に内容を確認していただき、公開を快諾していただきました。ありがとうございました。