タグ: PostgreSQL

JSONPathインジェクション

JSONPathはCSSのセレクタやXPathのクエリのような形でJSON形式のデータを選択/クエリする仕様です。最近のRDBMSはJSONPathクエリをサポートしているので、SQLインジェクション対策の一種として必要となる場合もあります。

JSONPathの説明はしないので仕様などはオンラインの評価環境で確認してください。

https://jsonpath.com/

JSONPathクエリは上記のような”意味を持つ文字”を使ってクエリを実行します。インジェクション攻撃は一文字でも意味がある文字があると攻撃される、と思って構わないです。JSONPathクエリもインジェクション攻撃が可能です。

もっと読む

遅すぎるサニタイズではダメな例

PostgreSQL 11がリリースされました。このリリースでto_number()、to_char()、to_date()、to_timestamp()関数の仕様が変更されました。これらは名前の通り入力を変換する関数です。その際に

  • サニタイズ – ダメな形式のデータを使える/安全なデータ形式に変換する

を行います。保存されるデータ形式は、保存可能な形に変換されます。しかし、これは十分ではないです。遅すぎるサニタイズがダメな例として紹介します。

※ エスケープやプリペアードクエリもサニタイズ(無害化)の一種です。

もっと読む

「フェイルセーフ」とは何なのか?

「フェイルセーフ」よく聞く言葉です。最近では「フェイルセキュア」1と言われることもありますが、基本概念は同じです。よく聞く言葉&簡単な概念ですが、割と広く誤解されている概念の1つに見えます。

フェイルセーフを一言で言うと

何かに失敗しても致命的な問題に至らないよう安全に失敗させる

これがフェイルセーフです。可能ならば「失敗/故障しても、失敗/故障の影響を受けないようする」場合もあります。ITシステムならRAID5や失敗時のリトライなどがこのケースです。

Wikipediaの定義では

フェイルセーフ(フェールセーフ、フェイルセイフ、英語fail safe)とは、なんらかの装置・システムにおいて、誤操作・誤動作による障害が発生した場合、常に安全側に制御すること。またはそうなるような設計手法で信頼性設計のひとつ。これは装置やシステムが『必ず故障する』ということを前提にしたものである。

となっています。

こんな単純な概念は間違いようがないでしょ?

と思うかも知れません。しかし、ソフトウェア開発では当たり前に誤解されています。

もっと読む

RDBMSから学ぶデータセキュリティ

RDBMSはデータセキュリティを学ぶには良い題材です。RDBMSはできる限り正しいデータを保存する仕組みがあるからです。RDBMSからどのようにデータのセキュリティを保証するのか紹介します。

プログラムが正しく動作する為には

  • 正しいコードであること
  • 正しい(妥当な)データであること

絶対条件です。どちらが欠けてもプログラムは正しく動作しません。

SQLiteは手軽で良いのですが、組み込み型であるためデータセキュリティを学ぶには機能的に問題があります。SQLiteにはデータ型を保証する機能もデータの内容を検証する機能もありません。1

利用するRDBMSはPostgreSQLを用い、データセキュリティに関連性の強い機能のみを対象とします。

もっと読む

SQLクエリと識別子エスケープの話

Facebookでこんなやり取りをしました。元々公開設定で投稿した物で、議論させて頂いた浅川さんにも「ブログOK」と許可も頂いたので、そのやり取りの部分だけを紹介します。

テーマは「SQLクエリと識別子エスケープ」です。

とあるブログの結論として

“「安全な静的SQLの発行方法」を開発者に啓蒙すればいいだけだ。つまり

  • プリペアドクエリでSQL発行は行うこと
    この場合変数のバインドは必ずプレースホルダを用いること。

SQL文の文字列操作は禁止であり、これほどシンプルなことも無いだろう”

と書かれていました。しかし、私はこの意見に対して

実践的なSQLクエリを書いたことが全くない開発者なのでしょう??
ソートカラム、抽出カラムを指定するSQLクエリでは「識別子(カラム名)が変数」になります。
初歩的なSQLクエリですが”自分が書いたことないから”といって一般的ではないと勘違いしています。行のソート順、抽出カラムを指定するSQLクエリは業務アプリでは”一般的”です。当たり前ですが。

こうやってベストプラクティスもどきのアンチプラクティスが使われて、喜ぶのはサイバー犯罪者とセキュリティ業者だけですよ。

とコメントしました。SQLのテーブルやジョイン結果を「表」として表示した際に、任意のカラムのソート順を指定するUIは、自分で作ったことが無かったとしても、ごく一般的だと分かると思うのですが・・・

もっと読む

PostgreSQL 10のICUコレーションとJIS X 4061

PostgreSQL Advent Calendar 9日目用のエントリです。

PostgreSQL 10のICUコレーション(照合順序)サポートの概要と基本的な使い方は以下のエントリに記載しています。ICUコレーションの使い方は以下を参照してください。

PostgreSQL 10のICUコレーションを使うと日本語を普通にソートでき、更に文字順序までカスタマイズできる

今回は日本語ソート順のJIS規格である JIS X 4061-1996にどの程度対応しているのか確かめてみます。

もっと読む

PostgreSQL 10のICUコレーションを使うと日本語を普通にソートでき、更に文字順序までカスタマイズできる

PostgreSQL 10からICU(International Components for Unicode)のロケール/コレーションがサポートされました。

これまでサポートされてきた、libcのja_JPロケールの貧弱な日本語ソート機能とは比べ物にならないくらい高機能な文字比較をサポートしています。日本語や他の言語での照合順序を柔軟に変更できます。

  • マトモな日本語ソート順でソートする(かなり重要)
  • 数字を後にソートする
  • 大文字を先にソートする
  • 仮名を先にソートする
  • 自然ソートする
  • これらをまとめて特別なソート順にする

といったことがPostgreSQL 10から行えます。

もっと読む

本当にプリペアードクエリだけを使っていますか?

'SELECT '.pg_escape_idetifier($_GET['col']).' WHERE '.pg_escape_identifier('tbl').' ORDER BY '.pg_escape_idetifier($_GET['col'])

SQLクエリにはプリペアードクエリを使いましょう!と言われて久しいです。私もプリペアードクエリを積極的に使うべきだと考えています。

  • 多くの場合、速い
  • SQLパラメーターを分離して書くので「ついうっかり」が起こりにくい
    • 特に初心者は「ついうっかり」が多い

しかし、「プリペアードクエリだけを使っていれば良いので、エスケープは要らない」という意見には賛成できません。なぜ賛成できないのか?コードを見れば分かります。

何年か前に議論になった話題です。自分のエントリを検索して、たまたま見つけたのですが物がありました。

例えば、入力バリデーションなしで以下のようなクエリは絶対に安全に実行できません。

$result = pg_query_params('SELECT '.pg_escape_identifier($_GET['col]). ' FROM '.pg_escape_identifier($_GET['table']). ' WHERE id = $1', [$_GET['id']]);

こんなクエリをそのまま書く人は居ませんが、プリペアードクエリ”だけ”ではインジェクション対策にならない事はSQLを知っていれば学生でも理解ります。

特定カラムの抽出/ソート(これはエスケープでぼほOK)、テーブル指定をするクエリは当たり前に存在します。

もっと読む

SQLインジェクション対策 総”習”編 – 第五回関西DB勉強会

第五回 関西DB勉強会でお話しさせて頂いた SQLインジェクション対策 総”習”編 の公開用資料をSlideShareにアップロードしました。私のセッションを気に入って頂けた方が多かったようで何よりです。

関西DB勉強会、面白かったです。久々にお会いできた方もいました。超満員でもう少しで入りきれないほどでした。また参加できれば、と思っています。

PDFはこちらからダウンロードできます。

https://www.slideshare.net/yohgaki/sql-76168380

 

勉強会で使ったスライドは、面白おかしく柔らかい(?)スライドでした。あまり公開用には向いていません。実際に勉強会で使った資料が欲しい方はFacebookかメールで連絡してください。個別にお送りします。

コンピュータは数値さえ正確に扱えない

コンピュータで数値を正確に扱うのは「実は結構難しい」です。つまり「コンピューターは数値を正確に扱えない」という事です。「コンピューターが数値を正確に扱えない?!何を言ってるんだ?!」と思った方は是非読んでみてください。

もっと読む

SQL識別子のエスケープ

SQLの識別子(テーブル名やフィールド名)はプリペアードクエリではエスケープできません。最近の開発者はSQLの”パラメーター”には注意を払うようになったので、SQLパラメーターによるSQLインジェクションはかなり少くなってきました。

この結果、相対的にSQL識別子によるSQLインジェクション脆弱性の割合が増えています。実際、私がコード検査を行っているアプリケーションでも識別子が原因でSQLインジェクションに脆弱であるケースが半数くらいになっています。

出力対策はセキュアコーディングの基本の1つです。プリペアードクエリだけでSQLによるインジェクションは防げません。DBMSに限らず、他のシステム(ライブラリも含む。特に文字列をパースする正規表現、XML処理など)にデータを送信する場合、完全に無害化する必要があります。

参考: CERTトップ10セキュアコーディング習慣7. 他のシステムに送信するデータを無害化する

もっと読む