ウェブアプリは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);
}
}
ノート:
+
ではなく*
でマスクします。コードは単体テストされているので、正しく機能するとかなり確信しています。もちろん、それを改善する可能性を見つけたら、私に知らせてください:-)
独自の layout を記述して、すべてのアペンダー用に構成することができます。
レイアウトには、ロギングメッセージを含むloggingEventから文字列を作成するformatメソッドがあります。
クレジットカード番号マスキングのより良い実装は http://adamcaudill.com/2011/10/20/masking-credit-cards-for-pci/ にあります。発行者とチェックサムをログに記録しますが、PAN(プライマリアカウント番号)はログに記録しません。