接続設定での空のパスワード

接続設定での空のパスワード

説明

パスワード認証を使う接続で 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);
});

解説:

  • 変更前: クライアントが空のパスワードを渡します。サーバーのアカウントが許可すれば弱い認証情報で接続し、拒否すれば接続に失敗します。
  • 変更後: 必須のパスワードを環境変数から読み、接続前に検証します。環境変数の供給経路とアクセス権限、実際のサーバー認証設定も保護する必要があります。

参考資料