こんにちは。現場で泥臭いインシデント対応に追われている皆さん、お疲れ様です。今日は、少し地味だけど、やられると致命傷になりかねない「LDAPインジェクション」についてお話しします。
セキュリティと聞くと難しく感じるかもしれませんが、まずは「家の防犯」に例えて、リラックスして読んでみてください。
—
1. LDAPって何?:家の「住所録」と「鍵」の仕組み
LDAP(エルダップ)は、簡単に言うと「社内の巨大な住所録」です。誰がどの部署にいて、どんな権限を持っているか、といった情報を管理するシステムですね。
皆さんが会社やWebサービスにログインする時、「IDとパスワード」を入力しますよね。システム側は、裏で「このIDの人は、このパスワードで合っているかな?」とLDAPという住所録に問い合わせを行っています。
ここで、「LDAPインジェクション」という泥棒の手口が登場します。
2. 攻撃のメカニズム:泥棒の「合鍵作り」
LDAPインジェクションは、一言で言えば「住所録への問い合わせ文を、悪意ある言葉で書き換える」攻撃です。
例えば、システムが裏でこんな命令を作っているとします。
(&(uid=入力されたID)(password=入力されたパスワード))
これは、「IDがこれ、かつ、パスワードがこれである人を探して!」という命令です。
泥棒のやり方
もし、悪意ある人がID欄にこんな文字を入れたらどうなるでしょうか?
admin)(&)
すると、システムが作る命令はこうなります。
(&(uid=admin)(&))(password=...))
この後ろの (&) というのは、「全部OK!」という魔法の言葉のようなものです。結果として、システムは「パスワードが何であろうと、adminさんを認証しちゃえ!」と勘違いしてしまいます。まさに、泥棒が隙を突いて「合鍵」を作ってしまうような状態ですね。
3. どうやって防ぐ?:泥棒を入れないための「二重の防犯」
では、この攻撃を防ぐにはどうすればいいでしょうか。家を守るのと同じで、二つのステップが重要です。
対策①:特殊文字を「ただの文字」として扱う(エスケープ)
泥棒は「命令の切れ目」を突いてきます。だから、( や ) といった、命令を意味する記号が入力されたら、それを「命令」ではなく「ただの文字列」として処理するようにします。
これを「エスケープ」と呼びます。
// エスケープ処理のイメージ(Node.jsなどのライブラリを使う場合)
// 入力値をそのままクエリに突っ込まず、専用の関数を通すのが鉄則です!
const ldap = require(‘ldap-escape’);
const userInput = “admin)(&)”; // 攻撃者の入力
const safeInput = ldap.filter(userInput);
// これで、特殊記号が無害な文字列に変換されます
console.log(safeInput); // 出力: admin\28\26\29
対策②:穴を掘らせない(パラメータ化クエリ)
これが一番の防御策です。先ほどの例では、命令文の中にユーザーの入力を「直書き」していました。そうではなく、「ここは名前が入る場所、ここはパスワードが入る場所」とあらかじめ枠を決めておく方法が「パラメータ化」です。
最近のライブラリやフレームワークは、この仕組みが標準で備わっています。
// ダメな例:文字列を連結してクエリを作る(攻撃の隙だらけ!)
const query = “(&(uid=” + req.body.username + “))”;
// 良い例:ライブラリが用意した「枠」を使う
// これなら、入力値にどんな変な記号が入っても「ただの文字列」としてしか扱われません
client.search(‘ou=users,dc=example,dc=com’, {
filter: (uid=${escapeForLdap(req.body.username)}), // 適切に処理された値のみを入れる
scope: ‘sub’
}, (err, res) => {
// 検索処理
});
—
4. 今日からできる「守りの姿勢」
最後に、新人エンジニアの皆さんに伝えたいことがあります。
- 「入力値はすべて疑え」: ユーザーが入力するものは、すべて「攻撃の武器になり得る」と考えるのがセキュリティの第一歩です。
- 「車輪の再発明をしない」: 自分で複雑なエスケープ処理を書こうとせず、信頼できるライブラリの「パラメータ化」機能を最大限に活用してください。
- 「ログを眺める習慣を持つ」: 変な文字列(
)(&)など)がシステムに送られてきていないか、たまにログをチェックしてみてください。それが「泥棒の下見」に気づくきっかけになります。
セキュリティは、一度設定して終わりではありません。家の鍵を毎日かけるのと同じで、日々の開発の中で「これ、泥棒に入られないかな?」と一瞬立ち止まることが、何よりも強力な防御になります。
一歩ずつ、一緒に学んでいきましょう!応援しています。
コメント