説明
パスワード認証を使う接続で password や passphrase を空にすると、認証に失敗するか、サーバーが空のパスワードを許可する場合に弱い認証情報で接続することになります。クライアントの設定を空にしても、サーバーの認証が無効になるわけではありません。実際のアカウントの認証方式と、サーバーが空の値を受け付けるかを確認する必要があります。
想定される影響
- 空のパスワードを受け付けるアカウントと接続経路があると、不正にアクセスされるおそれがあります。
- アカウントの権限に応じて、データの取得・変更・削除、メール送信、キューの使用などを行われる可能性があります。
- サーバーが空の値を拒否すると、接続の失敗によってアプリケーションに障害が起こる場合があります。
対処方法
- パスワード認証では、空や既定のパスワードを使わず、サービスに適した強度の秘密の値を供給してください。
- パスワードをコードやリポジトリに埋め込まず、保護された環境変数やAWS Secrets Manager・Vaultなどのシークレットストアから読み込んでください。
- 起動時に必須のパスワードがない、または空の場合は、接続前に処理を失敗させてください。パスワードを使わない認証方式では、その方式に合う認証情報とポリシーを確認してください。
例
変更前
javascript
// 設定で空のパスワードを使用
const mysql = require("mysql2/promise");
const config = {
host: "db.internal",
user: "app_user",
password: "", // 空のパスワードを受け付けるかはサーバーの認証設定次第
database: "app",
};
async function connect() {
const conn = await mysql.createConnection(config);
console.log("connected");
}
connect().catch(console.error);
変更後
javascript
// 保護された設定から読み込み、必須の秘密の値が空なら拒否
const mysql = require("mysql2/promise");
function requiredEnv(name) {
const v = process.env[name];
if (!v || v.trim().length === 0) {
throw new Error(`Missing required secret: ${name}`);
}
return v;
}
const dbPassword = requiredEnv("DB_PASSWORD");
const config = {
host: process.env.DB_HOST || "db.internal",
user: process.env.DB_USER || "app_user",
password: dbPassword,
database: process.env.DB_NAME || "app",
};
async function connect() {
const conn = await mysql.createConnection(config);
console.log("connected");
}
connect().catch((err) => {
// 機密の値をログに記録しない
console.error("DB 연결 실패:", err.message);
process.exit(1);
});
解説:
- 変更前: クライアントが空のパスワードを渡します。サーバーのアカウントが許可すれば弱い認証情報で接続し、拒否すれば接続に失敗します。
- 変更後: 必須のパスワードを環境変数から読み、接続前に検証します。環境変数の供給経路とアクセス権限、実際のサーバー認証設定も保護する必要があります。