SQLインジェクションの対策

SQLインジェクションの対策

SQLインジェクションによるクレジットカード情報漏洩により、3131万の損害が認定された裁判が過去にある。SQLインジェクションの被害平均は、4800万 ~ 1億円にも上る。


なぜ発生するのか?

エスケープ、プレースホルダを使えと言われるが…→プレースホルダを使っていないからなのか?

:max_age プレースホルダを使っている
.$min_age ただの文字列連結 { SQLi発生

<原因>

  • 文字列連結を使ってSQLを組み立てているから(SQLを文字列で指定できてしまうから)
  • 変数の埋め込みも文字列連携と同じ
  • プレースホルダではできないことがあるから


<SQLiを防ぐには?>

  • 文字列連結ではない方法で動的SQLを組み立てればよい → SQLテンプレート or SQL構文木
  • SQL文字列ではない方法でSQLを指定できるようにすればよい


<なぜSQLiが起こりやすくなっているのか?>

  • 本質的にはライブラリやAPIインターフェースに欠陥があるから
  • 間違いを誘発するものを使う限り、SQLiがなくなることはない


SQLテンプレートとは?

  • SQLを生成するためのテンプレート
  • SQLiが発生しない 文字列連結が不可


<SQLTempl8>

  • SQLを対象としたテンプレートエンジン
  • コンセプト実装(使い方は変わる可能性があるので、ドキュメント参照)

SQL構文木

  • SQL木構造で表現したデータ
  • SQL構文木なら、悪意ある値を受け取っても、木構造は影響を受けない
  • 構文木からSQL文字列へ最終的には変換しなければならない。‘=‘と’is null’も値に応じて自動的に変換

SQL構文木の組み立て方

  • O/R Mapperを使う

演算子オーバーライドが使えると、自然な記述になる


PHP カンファレンス2015より