Weitere ähnliche Inhalte Ähnlich wie 安全なプログラムの作り方 (20) Mehr von Kazuhiro Nishiyama (20) Kürzlich hochgeladen (12) 安全なプログラムの作り方1. 安全なプログラムの作り方
Secure Programming
西山和広 (@znz)
Good-Day Inc.
Powered by Rabbit 0.9.2
3. prologue (1) はじまり
まだ javascript もなかった頃の話
掲示板 (伝言板) CGI がありました
(twitter をもっと簡易にしたようなもの)
2/41
4. prologue (2) 掲示板 CGI
HTML のタグを解析して A とか B とか
HTML の構造が崩れないものを許可
それ以外のタグ HTML とか HEAD とか
BODY とかはエスケープ
エスケープするのは、ちゃんとした HTML
を出力するため
3/41
5. prologue (3) 余談
hidden で埋め込んだ文字の文字コードで他
のフィールドの文字コード推定もうまくいか
ないブラウザがあるとか
出力した HTML と同じ文字コードでフォー
ムの内容も送ってくると思ったら、そうじゃ
ないブラウザがあるとか
そういう理由で文字コードは結局自動判別しか
なかったというのはまた別のお話
4/41
6. prologue (4) 変化
javascript が普及
onclick などが指定できるようになる
javascript: というリンクも使えるようになる
問題がなかったはずの掲示板が
何も変えていないのに
脆弱性のあるものになった
5/41
8. 対策
一般に
入力はちゃんとチェックする
出力はちゃんとエスケープする
多層の対策をするなど
その他
環境の変化に注意する
7/41
10. URL 入力欄
ブラウザの高機能化で脆弱性になったものと
して URL 入力
問題点
「javascript:」で始まる URL で javascript が実
行できる
対策
外部へのリンクを意図した入力欄なら「 http: 」
または「 https: 」で始まる URL のみ許可
9/41
12. GET は冪等に (1)
昔から言われていたこと
GET で状態を変化させてはいけない
GET は冪等 (同じリクエストには同じ応答) であ
るべき
11/41
13. GET は冪等に (2)
HTTP のリクエストメソッドは GET, POST,
HEAD など
GET や HEAD は何度リクエストを送っても同じ
結果を返すべき (羃等)
書き込みや削除には POST (や REST 風なら
PUT や DELETE など) を使うべき
GET で削除できるようにしていたら検索エンジ
ンのクローラーに消されたという話も。
12/41
16. /tmp を避ける (1)
/tmp 以下を直接使うのは避けるべき
一時ファイルを作るときなど
特に固定のファイル名で作るのは危険
問題の例
symlink attack の危険
Windows で困る
15/41
17. /tmp を避ける (2)
代わりに
Rails なら Rails.root+'tmp' 以下
一般には tmpdir や tempfile などの標準添付ラ
イブラリ
16/41
19. tmpdir と tempfile
歴史的理由により
tmpdir は e なしの tmp
tempfile は e ありの temp
覚え方
tmpdir は dir が 3 文字なので tmp も 3 文字
tempfile は file が 4 文字なので temp も 4 文
字
18/41
21. パーミッションは最小限に
2006 年の JVN#27365476: the Minnu's
filer2 において、使用中のユーザの権限で別
のユーザに任意の Ruby スクリプトを実行さ
れる脆弱性 http://jvn.jp//jp/
JVN27365476/index.html
/tmp 以下に作成される外部との連携用の Unix
Socket が誰でも読み書きできるパーミッションに
なっていた
ファイルを作成するときは umask などに注意
20/41
23. hiki 0.8.6 の脆弱性
2007 年の JVN#05187780: Hiki において
任意のファイルが削除可能な脆弱性 http://
jvn.jp//jp/JVN05187780/index.html
設置する人が出来るセキュリティ向上手
段 : ファイルの所有者と実行ユーザを分離
権限一緒 : hiki 本体も削除可能
権限分離 : データしか削除できない
22/41
26. 改行と正規表現 (1)
^ $ と A z (Z) を使い分ける
^ : 行頭
$ : 行末
A : 文字列の先頭
z : 文字列の末尾
Z : 文字列の末尾か末尾の改行の直前
25/41
27. 改行と正規表現 (2)
^ $ と A z (Z) を使い分ける
Perl では /m を付けない限り ^ $ は文字列の先
頭と末尾
Ruby で同じ意味を持つものは A と Z
入力全体をチェックするに使うのは ^ $ で
はなく A z
先ほどの hiki の例で ^ $ を使うと "任意n#
{session_id}n任意" のように回避できてしまう
26/41
28. 正規表現と文字
予期しない文字を通してしまうと危険
何が何にマッチするのか知っておくのは重要
たとえば 英数字なら
w は 1.9 だと 'あ' などにはマッチしない
[A-Za-z0-9] などのように書く方が確実
用途に応じて [[:alnum:]] とか p{Alnum} と
か
27/41
32. ログ出力 (2)
RVM がプロジェクトごとの .rvmrc ファイ
ルを確認のため表示する
2011 年の JVN#30414126: Ruby Version
Manager におけるエスケープシーケンスイ
ンジェクションの脆弱性 http://jvn.jp//jp/
JVN30414126/index.html
31/41
33. ログ出力 (対策)
対策
外部入力をログ出力するときには String#dump
などを使ってバイナリのまま出力しない
コンソールへの出力でも外部入力を含んだりバイ
ナリを含む場合はエスケープすべき
32/41
35. エスケープは適切に
エスケープは出力先に合わせた適切な場所で
適切なものを
HTML の属性値なら '' ではなく "" でくくる
エスケープ結果にあった文脈を用意することも必
要
<tag attr='#{CGI.escapeHTML
(value)'/> では意味がない
javascript のエスケープをしてから HTML のエ
スケープをするなど多段のエスケープが必要なこ
とも
34/41
39. コマンドライン処理 (3)
チェックポイント
ファイル名に空白が入っていても大丈夫か?
ファイル名が - で始まっていても大丈夫か?
ファイル名に ['"*] などの記号が入っていても大
丈夫か? (そもそもそういうファイル名を許可する
のか?)
NUL 文字 (0) が入っていても大丈夫か?
38/41
40. コマンドライン処理 (4)
受け取る側
シェルやシェルスクリプトから起動するときに
ちゃんと引数を渡せているか?
「alias p='ruby -e "p ARGV" --'」のようなエイ
リアスを作る
「foo='foo bar'; p $foo; unset foo」などで確認
39/41
41. まとめ
永遠に安全なアプリはほぼ不可能
Web アプリならブラウザなど外部環境の変化
某キャリアの SSL ゲートウェイのような外部要因
入出力は特に気を付ける
入力はチェックする
出力はちゃんとエスケープする
ファイル名やパーミッションにも気を付ける
40/41