説明
パスワード認証が必要なアカウントで空のパスワードを使うと、接続が拒否されるか、サーバーが受け入れる場合には本人確認が弱まるおそれがあります。空文字列を渡しただけで誰でも接続できるわけではありません。実際のアクセスは、サーバーの認証方式、許可されたクライアント、アカウント権限に依存します。証明書や外部IDによる正当なパスワードレス認証とは区別してください。
想定される影響
- データの漏えい・変更: サーバーが空のパスワードを受け入れると、そのアカウント権限でデータを取得・変更・削除される可能性があります。
- 管理機能の悪用: 管理権限のあるアカウントでは、設定変更などに影響が広がるおそれがあります。
対処方法
- パスワード認証用のアカウントには強力なパスワードを設定し、サーバーで空のパスワードを拒否してください。別の認証方式を意図している場合は、サーバーとドライバーの設定を確認してください。
- パスワードをコードに埋め込まず、HashiCorp Vaultなどのシークレット保管先やアクセスを制限した実行環境から渡してください。KMSは暗号鍵の管理サービスであり、シークレットの保存・取得を行う構成とは区別してください。
- アカウント権限とネットワークアクセスを最小限にし、リモート接続にはサーバー証明書を検証するTLSを構成してください。
例
変更前
java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class InsecureDBConnection {
public static void main(String[] args) throws SQLException {
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String password = ""; // 空のパスワード
Connection conn = DriverManager.getConnection(url, user, password);
}
}
変更後
java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class SecureDBConnection {
public static void main(String[] args) throws SQLException {
String url = "jdbc:mysql://localhost:3306/mydb";
String user = System.getenv("DB_USER"); // 環境変数から取得
String password = System.getenv("DB_PASSWORD");
if (password == null || password.isEmpty()) {
throw new SecurityException("Database password is not set");
}
Connection conn = DriverManager.getConnection(url, user, password);
}
}
説明:
- 変更前:
rootへ空のパスワードを渡します。接続が許可されるかどうかは、データベースサーバーの設定によります。 - 変更後: アカウントとパスワードを環境変数から読み、パスワードが未指定または空なら処理を止めます。環境変数だけでシークレットが保護されるわけではないため、実行環境とログへのアクセスを制限してください。接続の解放とドライバー固有のTLS設定は省略しています。