忍者ブログ

ひつ(じのひよこが)プログラミングします。
お仕事や趣味で困ったこととか、何度も「あれ?どうだったかしら」と調べたりしたこととか、作ったものとか、こどものこととかを書きます
★前は週末定期更新でしたが今は不定期更新です

2024/11    10« 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  »12

ディレクトリトラバーサルと SQL インジェクション

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

コメント

ただいまコメントを受けつけておりません。

ディレクトリトラバーサルと SQL インジェクション

ディレクトリトラバーサルと SQL インジェクションってどう違うの? という話をちょっと前にもらったのでそれぞれについて書く。

共通点

ちょっと知っている人なら全然違うじゃないか、と思う気もするのだが、ゆっくり見ると似ている点もある。

  • 開発者が想定していなかった入力によって発生する
  • 本来の操作ではアクセスされない領域にアクセスされる
  • アクセスされた領域を参照されたり、改ざんされたり、削除されたりする

違う点

『本来の操作ではアクセスされない領域』が両者の間で異なる。

ディレクトリトラバーサル

Directory Traversal、日本語ではディレクトリ横断という意味になる。

例えば、サーバに設置されたアプリケーションが次のような構造だったとしよう。

┏━━━━┓
┃ユーザー┃┌───────────────┐
┗┳━━━┛│アプリケーションのあるサーバ │
 ┃    │     ┏━━━━━━━━┓│
 ┃    │ ┏━━━┫ファイルシステム┃│
 ┃    │ ┃   ┃(Root)     ┃│
 ┃    │┏┻━━┓┃├novel     ┃│
 ┗━━━━┿┫アプリ┃┃│├novel1.txt ┃│
      │┗━━━┛┃│└novel2.txt ┃│
      │     ┃└secret    ┃│
      │     ┃ └secret.txt ┃│
      │     ┗━━━━━━━━┛│
      └───────────────┘

小〇家になろうとかカク〇ムみたいな小説を公開するアプリだとしよう。ユーザはアプリに読みたい小説のファイル名を送信する。例えば novel1 が読みたかったら novel1.txt と要求を送るわけだ。するとアプリはファイルシステムの novel ディレクトリからその小説のデータを取ってきてユーザに送り返す。

ここで問題になるのはユーザの入力が ../secret/secret.txt だった時だ。こちら、ファイルタイトルの通り機密ファイルであり、ユーザには見せられない。しかし、もしもディレクトリトラバーサルに対する対策が無ければこのファイルは容易に閲覧されてしまう。

このようにして本来アクセスされるべきでないディレクトリ (ないしファイル) にアクセスされてしまうのがディレクトリトラバーサルである。

対処法として以下が考えられる。

  • そもそもファイルアクセスを可能な限りしない。小説の本文情報は DB に入れておく
  • やむを得ず行う場合(皆無では決してないだろう)、アクセスに使うパスをきっちり管理する。
    パスを DB に格納しておいてユーザにはパスに対応するキーを入力として入れてもらうとか
    ユーザの入力をバリデーションするとか
  • サーバ側のファイルアクセス権限を適切に設定し、アプリケーションを動かしているユーザの権限ではアクセスできないようにする

SQL インジェクション

SQL Injection、日本語で SQL 注入といった意味になる。その名の通り、SQL を注入するという攻撃であったり、それをできてしまう脆弱性であったりを指す。

分かりやすい例を示す。以下のような SQL を発行するとしよう。
'SELECT * FROM NOVELS WHERE TITLE = "' + userRequestNovelName + '"'
この userRequestNovelName が曲者である。これで想定されているのは先の例と同じくユーザの入力が novel1 だとかであることである。ユーザの入力が novel1 ならば、次の SQL 分が完成する。
"SELECT * FROM NOVELS WHERE TITLE = novel1"

では、ユーザの入力が "; DROP TABLE NOVELS; とかだったら? 実行される SQL 文は以下のとおりである。
'SELECT * FROM NOVELS WHERE TITLE = "";
DROP TABLE NOVELS;"'

2文が実行されることになる。しかも2文目は実行されたら相当まずい。

これへの対処にはプレースホルダーという方法が有効だが、説明が面倒なので省略する。Java の PreparedStatement クラスがおそらくは有名か。

もう一つ似たようなもの OS コマンドインジェクション

名の通り OS のコマンドを注入できる。これで rm -rf / とかされたら大参事である。

PR

コメント

ただいまコメントを受けつけておりません。

ブログ内検索

P R