サニタイズ(入力検証) — セキュリティと整合性
サニタイズ (sanitize) とは「外部から受け取った入力を安全に整える」こと。
Webアプリや業務システムでは、ユーザー入力をそのまま使うと SQLインジェクション や XSS、不正データ混入 の原因になります。
Javaでは「入力検証」と「サニタイズ」を組み合わせて、セキュリティと整合性を守ります。
基本の考え方
- 入力検証 (validation): 「正しい形式か」をチェックする。例: メールアドレス、日付、数値範囲。
- サニタイズ (sanitize): 「危険な文字を除去・変換」する。例: HTMLタグをエスケープ、SQL特殊文字を無効化。
- 原則:
- 信頼しない: 外部入力は必ずチェック。
- 最小限許可: 必要な文字だけ許可し、それ以外は拒否または除去。
- 責務分離: 検証は「正しいか」、サニタイズは「安全にするか」。
コード例で理解する
例題1: 数値入力の検証
public static int parseAge(String input) {
if (input == null || !input.matches("\\d+")) {
throw new IllegalArgumentException("年齢は数字のみ");
}
int age = Integer.parseInt(input);
if (age < 0 || age > 150) {
throw new IllegalArgumentException("年齢範囲外");
}
return age;
}
Java👉 検証: 数字のみ/範囲チェック。
👉 効果: 「abc」や「9999」など不正値を防ぐ。
例題2: メールアドレスの検証
public static boolean isValidEmail(String email) {
if (email == null) return false;
return email.matches("^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$");
}
Java👉 検証: 最低限の形式チェック。
👉 効果: 「aaa@bbb」など不正な形式を弾く。
例題3: HTML入力のサニタイズ
import org.apache.commons.text.StringEscapeUtils;
public static String sanitizeHtml(String input) {
if (input == null) return "";
return StringEscapeUtils.escapeHtml4(input);
}
Java👉 サニタイズ: <script> を <script> に変換。
👉 効果: XSS攻撃を防止。
例題4: SQLインジェクション対策(PreparedStatement)
import java.sql.*;
public static void findUser(Connection con, String name) throws SQLException {
String sql = "SELECT * FROM users WHERE name = ?";
try (PreparedStatement ps = con.prepareStatement(sql)) {
ps.setString(1, name); // サニタイズ不要、JDBCが安全に処理
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
System.out.println(rs.getString("name"));
}
}
}
}
Java👉 サニタイズ: PreparedStatement が内部で安全に処理。
👉 効果: "abc' OR '1'='1" のような攻撃を防ぐ。
実務での応用
- Webフォーム: 入力値を必ず検証。
- ログ保存: サニタイズしてから保存(ログインジェクション防止)。
- ファイル名: 許可文字だけ残す(例: 英数字+アンダースコア)。
- 外部API: 送信前に検証・サニタイズして整合性を保つ。
テンプレート集
数値検証
if (!input.matches("\\d+")) throw new IllegalArgumentException("数字のみ");
Java文字列長チェック
if (str.length() > 100) throw new IllegalArgumentException("長すぎる入力");
JavaHTMLエスケープ
String safe = StringEscapeUtils.escapeHtml4(input);
JavaSQL安全呼び出し
PreparedStatement ps = con.prepareStatement("SELECT * FROM t WHERE id=?");
ps.setInt(1, id);
Javaよくある落とし穴
- ブラックリスト方式: 「危険文字を禁止」より「許可文字だけ許す」ホワイトリスト方式が安全。
- サニタイズ忘れ: ログや画面出力でも危険。必ずエスケープ。
- 複雑な正規表現: 過剰に厳しいと正しい入力も弾く。バランスが大事。
- 多言語対応: エンコーディングを統一(UTF-8推奨)。
まとめ
- サニタイズ=安全化、検証=正しさ確認。
- 両方組み合わせてセキュリティと整合性を守る。
- PreparedStatement やライブラリを活用して安全に。
- 原則は「信頼しない」「最小限許可」「責務分離」。
👉 練習課題として「ユーザー名入力」を作り、英数字とアンダースコアだけ許可する検証+HTMLエスケープを組み合わせると、サニタイズの重要性が体感できます。
