コース目次 / 第1章
原則1 — データとコードを、混ぜない
XSS・SQLi・コマンド・SSTI・デシリアライズを貫いた「データがコードとして評価される」問題を、パラメータ化・文脈別エスケープ・JSON.parseという3つの具体策に整理します。
sec-injection と sec-serverside で扱った穴を、思い出します。
貫いていた、一つの形
XSS — 入力が HTML/JavaScript として解釈された。
SQL インジェクション — 入力が SQL 文として解釈された。
コマンドインジェクション — 入力がシェルコマンドとして解釈された。
SSTI — 入力がテンプレートの式として解釈された。
安全でないデシリアライズ — 入力(データ)が、復元の過程でコードとして評価された。
すべて、「本来はただのデータであるはずの入力が、何らかの言語のコードとして評価されてしまう」という同じ形でした。
具体的な実装手段は、3つに集約できる
1. パラメータ化(SQL・コマンド)。文字列連結で命令文を組み立てず、骨格を固定して値を別ルートで渡す。SQL ならプレースホルダ(?)、コマンドなら引数配列(execFile の第2引数)。
2. 文脈別エスケープ(XSS)。出す先(HTML本文・属性・JS・URL)ごとに、正しい変換をかけてから出力する。入力時の一括処理では対応できない。
3. データとしてのみ解釈させる(SSTI・デシリアライズ)。テンプレートのソースに入力を混ぜず、渡す変数として扱う。復元は eval ではなく JSON.parse のような、コードとしては評価しない手段で行う。
この原則の、確かめ方
コードを読むとき、こう問います。
「この入力は、どこかで文字列連結によってコマンド・クエリ・テンプレート・パスに組み込まれていないか?」
文字列連結(+ や テンプレートリテラル)で、外部由来の値を命令や構文の一部に組み込んでいたら、そこは疑うべき箇所です。逆に、専用の API(プレースホルダ、引数配列、JSON.parse)を通していれば、その心配はまず要りません。
持ち帰る一言
入力は、常にデータとして扱う。 コードとして評価される経路(文字列連結による命令の組み立て)を断ち、専用のAPI(パラメータ化・文脈別エスケープ・JSON.parse)に乗せる。この一つの原則が、注入系の穴のほとんどを説明します。次は、もう一つの大きな原則——「信じるものを明示する」です。
こうなっていればOK
卒業まであと4章です。
この章はまだ完了していません。
保存できませんでした(プライベートブラウズ中かもしれません)。この端末に進捗は残りませんが、先へは進めます。