ウェブアプリはPCIに準拠する必要があります。つまり、クレジットカード番号を保存してはなりません。このアプリはメインフレームシステムのフロントエンドであり、CC番号を内部で処理します。また、今わかったように、応答画面の1つに完全なCC番号を吐き出すことがあります。デフォルトでは、これらの応答のコンテンツ全体がデバッグレベルでログに記録され、これらから解析されたコンテンツもさまざまな場所にログに記録できます。そのため、このようなデータ漏洩の原因を突き止めることはできません。CC番号がログファイルでマスクされていることを確認する必要があります。
正規表現の部分は問題ではありません。他のいくつかの場所ですでに使用している正規表現を再利用します。ただし、Log4Jを使用してログメッセージの一部を変更する方法については、適切な情報源が見つかりません。フィルタははるかに制限されているようで、特定のイベントをログに記録するかどうかを決定することしかできませんが、メッセージの内容を変更することはできません。また、Log4J用のESAPIセキュリティラッパーAPIを見つけました。これは、一見したところ、私がやりたいことを実行することを約束します。ただし、明らかに、コード内のすべてのロガーをESAPIロガークラスに置き換える必要があります。これはお尻の痛みです。私はより透明な解決策を好みます。
Log4J出力からクレジットカード番号をマスクする方法はありますか?
更新: @pgrasの元のアイデアに基づいて、ここに実用的な解決策があります:
public class CardNumberFilteringLayout extends PatternLayout {
private static final String MASK = "$1++++++++++++";
private static final Pattern PATTERN = Pattern.compile("([0-9]{4})([0-9]{9,15})");
@Override
public String format(LoggingEvent event) {
if (event.getMessage() instanceof String) {
String message = event.getRenderedMessage();
Matcher matcher = PATTERN.matcher(message);
if (matcher.find()) {
String maskedMessage = matcher.replaceAll(MASK);
@SuppressWarnings({ "ThrowableResultOfMethodCallIgnored" })
Throwable throwable = event.getThrowableInformation() != null ?
event.getThrowableInformation().getThrowable() : null;
LoggingEvent maskedEvent = new LoggingEvent(event.fqnOfCategoryClass,
Logger.getLogger(event.getLoggerName()), event.timeStamp,
event.getLevel(), maskedMessage, throwable);
return super.format(maskedEvent);
}
}
return super.format(event);
}
}
ノート:
- CIDがこのロガーによってマスクされた場合、バックエンドサーバーによってマスクされた場合、または他の人によってマスクされた場合を区別したいので、
+
ではなくでマスクします。*
- 誤検知の心配がないので、単純な正規表現を使用します
コードは単体テストされているので、正しく機能するとかなり確信しています。もちろん、それを改善する可能性を見つけたら、私に知らせてください:-)