我遇到了一个我不理解的preg_replace()问题:
我试图从应用级别日志中删除密码,令牌和其他敏感数据。为实现这一目标,我正在使用它:
$content = preg_replace(
'/(?=\\\\"password\\\\")(.*)(?=\\\")(.*)/i', '\"password\": \"[OBFUSCATED]\",',
$content
);
使用此字符串完全正常:
“{\ n \”username \“:\”myuser@gmail.com \“,\ n
\“密码\”:\“1234password \”,\ n
\“角色\”:\“ROLE_USER \”,\ n
}“
和正则表达式的建设者喜欢这个: http://www.phpliveregex.com/
但是当我在我的应用程序中使用它时,它只输出我:
"{\n \"username\": \"myuser@gmail.com\",\n \"password\": \"[OBFUSCATED]\",
而非预期:
"{\n \"username\": \"myuser@gmail.com\",\n \"password\": \"[OBFUSCATED]\", \"role\": \"ROLE_USER\",\n }"
删除更换部件后的其余部分。我不明白为什么,我对正则表达式很可怕...... 我怎样才能保留其余部分,为什么它适用于正则表达式构建器而不是我的应用程序(PHP v7.0.15)?
编辑:正如我在@ Splash58评论中看到的那样: 我不能使用数组,因为我无法提前看到哪些是需要混淆的值。它可以在$ json ['object1'] ['object2'] ['password']或$ json ['objectX'] [0] ['password']中。我不想在我的数组中搜索要在可能的拥抱数组中删除的键,perfs太糟糕了。那更清楚吗?
感谢您的任何提示! 博尔
答案 0 :(得分:1)
不建议在此类字符串上使用正则表达式,但正则表达式有一些明确的问题:
.
匹配,这样您就有可能匹配不属于一起的引用对。它还解释了您提到的问题 - 字符串的其余部分已被删除。(?= )
以错误的方式使用:它表示一个前瞻,它实际上并不抓取这些字符,而在您的用例中,实际抓住它们是可以的(哪个有更好的表现)以下是修改后的表达式:
$content = preg_replace(
'/(\\\\"password\\\\"\s*:\s*\\\\")((\\\\[^"]|[^\\\\])*)/i',
'$1[OBFUSCATED]',
$content
);
请注意,您的输入字符串不是JSON,因为真正的JSON不允许在您拥有它们的地方发生文字反斜杠。例如,它不能有只允许空格的文字\n
。你似乎逃脱了某些字符(换行符,引号),在JSON中它们不应该像那样被转义。
答案 1 :(得分:-1)
要解决根本问题,您应该 永远不会 让敏感数据在您的应用程序中漂浮。
至少 你应该只传递一个密码哈希(即由password_hash
生成的密码哈希),但即便如此只是为了实际验证用户。不要把这些东西留在内存中,不要超过需要!
一旦解决了根问题,即在不需要的情况下拥有不安全的敏感数据,您就会发现不再需要“清理”应用程序日志了。)