説明
入力検証が不十分だと、アプリケーションが制限されたディレクトリの外にあるファイルへアクセスしたり、変更したりできる場合があります。機密情報の漏えいやファイルの破損につながるおそれがあります。
想定される影響
- 制限ディレクトリ外へのアクセスによる機密データの漏えい
- 不正なファイルの書き込みや上書き
対処方法
- 入力をパス結合関数に渡す前に、正規化と検証を行ってください。
- ファイル名だけが必要な場合は、
path.basename()で最後の要素を取り出し、信頼できる基準ディレクトリと組み合わせてください。 - 許可しない文字やディレクトリのパスを除外し、正規化した結果が基準ディレクトリ内に収まることを確認してください。
- プロセスのファイルアクセス権限を必要な範囲に制限してください。
例
変更前
javascript
const path = require("path");
function unsafePathTraversal(user_input) {
return path.join("/safeDir", user_input);
}
変更後
javascript
const path = require("path");
function safePathTraversal(user_input) {
const baseDir = path.resolve("/safeDir");
// ファイル名だけを許可する場合は、ディレクトリ要素を除去し、許可した文字だけを通します。
const filename = path.basename(String(user_input || ""));
if (!/^[a-zA-Z0-9._-]+$/.test(filename)) {
return 'Access Denied';
}
const pathString = path.resolve(baseDir, filename);
if (!pathString.startsWith(baseDir + path.sep)) {
return 'Access Denied';
}
return pathString;
}
説明:
- 変更前: 入力を検証せずにパス結合に使うため、攻撃者が制限ディレクトリの外を指定できる場合があります。
- 変更後: ファイル名だけが必要な場合に
path.basename()でディレクトリ要素を取り除きます。文字の検証と基準ディレクトリ内の確認により、パス文字列の逸脱を防ぎます。サブディレクトリを許可する場合も、正規化後の包含関係の確認が必要です。この例はファイルシステムのリンクを解決しないため、実際にアクセスするときは、シンボリックリンクや検証後のパス変更も考慮する必要があります。