Featured image of post SQLを文字列結合で組むと、引数が増えてインジェクションも通る。PerlとMooのBuilderで組み直す全8回【目次】

SQLを文字列結合で組むと、引数が増えてインジェクションも通る。PerlとMooのBuilderで組み直す全8回【目次】

Perl と Moo で SQL クエリビルダーを作りながら、文字列結合が招く引数の増殖と SQL インジェクションに当たり、Builder パターンとプレースホルダーで組み直す全8回の連載の目次です。困りごとからも選べます。

Perl と Moo で、SQL を組み立てるクエリビルダーを作る全8回の連載です。テーブル名を受け取って SELECT を返すだけのクラスから始め、WHERE・ORDER BY・LIMIT を足すたびにコンストラクタの引数が増えて行き詰まる様子と、値を文字列結合で埋め込んだ SQL が攻撃で全件を返す様子を確かめます。そこから、1句ずつメソッドで足す Builder パターンに組み替え、プレースホルダーで値を分け、JOIN や集計への拡張、定型クエリをまとめる Director、バリデーションとテストまで仕上げます。

各回は前の回のコードに手を足していく作りなので、通して読むなら第1回からが早道です。このページは目次を兼ねた案内板です。入口は「どこから読むか」で、困りごとが決まっているなら「困りごとから探す」で、順に追うなら「全話一覧」で選んでください。

どこから読むか

  • 第1回 — 最初から順に作るなら。SELECT を返すだけの Query クラスを作り、SQLite で動かす。前提は Moo のクラス定義の基礎
  • 第3回 — 文字列結合の SQL がどう破られるかを先に見たいなら。第2回の Query クラスを使うが、攻撃の筋は1回で追える
  • 第4回 — Builder パターンの組み立て方だけ知りたいなら。メソッドチェーンで1句ずつ足す QueryBuilder を作る。第2回の引数7個のコンストラクタと見比べる

困りごとから探す

コンストラクタの引数が増え続けて、どれが必須か分からない

  • 第2回 — WHERE・ORDER BY・LIMIT を足したら引数が7個になった
  • 第4回 — 引数を並べる代わりに、1句ずつメソッドで足す形に変える

文字列結合の SQL に、入力値がそのまま入っている

  • 第3回 — 細工した入力1つで全ユーザーの行が返る
  • 第5回 — ? と bind 値に分けて、攻撃文字列をただの値として扱う

句を足したいが、動いているコードは書き換えたくない

  • 第6回 — JOIN・GROUP BY・HAVING・OFFSET を、from や where には手を入れず足す

同じ組み立てを何か所にも書いている

  • 第7回 — ページ送り付き検索や集計の手順を Director にまとめる

間違った呼び方でも SQL ができてしまう

  • 第8回 — 不正な引数を croak で止め、Test::More でテストする

全話一覧

  1. 最小の SELECT を返す Query クラス(文字列結合)
  2. WHERE・ORDER BY・LIMIT で引数が7個に(Telescoping Constructor)
  3. 文字列結合の SQL を攻撃してみる(SQLインジェクション)
  4. メソッドチェーンで1句ずつ組み立てる(Builder)
  5. 値を ? と bind 値に分ける(プレースホルダー)
  6. JOIN・GROUP BY・HAVING・OFFSET を足す(拡張)
  7. 定型クエリの手順をまとめる(Director)
  8. バリデーションとテストで完成(Test::More)

前提知識

  • Perl v5.36 以降の基本文法(signatures、postfix dereference など)
  • Moo によるクラス定義の基礎(has)
  • DBI と DBD::SQLite(手元で実行して確かめるときに使う)
  • Moo が初めてなら、先に「Mooで覚えるオブジェクト指向プログラミング」シリーズを読むとスムーズに進みます

完成するもの

from・select・join・where・group_by・having・order_by・limit・offset をメソッドチェーンで組み立て、値はプレースホルダーで分けて返す QueryBuilder と、定型クエリをまとめた QueryDirector です。不正な呼び方は croak で止まり、t/query_builder.t のテストで振る舞いを確かめられます。

comments powered by Disqus
システム開発・AIワークフローのご相談は Meetsource へ
Hugo で構築されています。
テーマ Stack は Jimmy によって設計されています。