preg_replace删除行的其余部分

时间:2018-01-13 09:54:31

标签: php regex preg-replace

我遇到了一个我不理解的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太糟糕了。那更清楚吗?

感谢您的任何提示! 博尔

2 个答案:

答案 0 :(得分:1)

不建议在此类字符串上使用正则表达式,但正则表达式有一些明确的问题:

  • 执行贪婪的.匹配,这样您就有可能匹配不属于一起的引用对。它还解释了您提到的问题 - 字符串的其余部分已被删除。
  • (?= )以错误的方式使用:它表示一个前瞻,它实际上并不抓取这些字符,而在您的用例中,实际抓住它们是可以的(哪个有更好的表现)
  • 为了避免其他不匹配,最好还是:
    • 检查是否存在冒号和空格,因为密码属性的键/值对之间不应出现任何其他内容。
    • 检查字符串文字是否只有非引号的反斜杠转义符,否则它表示字符串文字的结尾。

以下是修改后的表达式:

$content = preg_replace(
        '/(\\\\"password\\\\"\s*:\s*\\\\")((\\\\[^"]|[^\\\\])*)/i',
        '$1[OBFUSCATED]',
        $content
    );

请注意,您的输入字符串不是JSON,因为真正的JSON不允许在您拥有它们的地方发生文字反斜杠。例如,它不能有只允许空格的文字\n。你似乎逃脱了某些字符(换行符,引号),在JSON中它们不应该像那样被转义。

答案 1 :(得分:-1)

要解决根本问题,您应该 永远不会 让敏感数据在您的应用程序中漂浮。

至少 你应该只传递一个密码哈希(即由password_hash生成的密码哈希),但即便如此只是为了实际验证用户。不要把这些东西留在内存中,不要超过需要!

一旦解决了根问题,即在不需要的情况下拥有不安全的敏感数据,您就会发现不再需要“清理”应用程序日志了。)