0

I've inherited this script where some sensitive information is stored in the database...and I'm wanting to replace it with ******** before it gets saved and presented in a log.

I'm using PHP...and the sensitive information is a randomly generated set of characters eg: yYng6Ytzh (sometimes it may also include !'s and @'s).

It always follows the specific substring Password: eg: Password: yYng6Ytzh and is surrounded by other text stored in a single string.

For example:

$EmailContent 'Dear Some Name,

here is your password
...or click the link to login... 
someurl.com?action=Log%20In&username=someuser@test.com&…
Your log in details are:
Username: your full email address (where this email was received)
Password: yYng6Ytzh
Some more bla bla

Kind Regards,
Admin

I've been trying all sorts of combinations of preg_match(), preg_replace() including str_replace () with an offset, but I'm not getting anywhere.

Can anyone point me in the right direction please?

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • 1
    Can passwords have spaces in them? If so, what is the delimiter? You could just not do a replace and just do `$strToLog .= "Password: ********";` – ʰᵈˑ Jan 26 '15 at 12:43
  • can you post an example of what you want to achieve? – Alireza Fallah Jan 26 '15 at 12:46
  • Thanks for helping me - Here is an example...basically an email is sent out to a user with the body of the mail in one $var then it get stored in the database...I'd like to strip out the password (it doesn't include spaces) but still display the full email... there are two places I'd like to use this on in the email but was hoping to adapt one to do the other...but I'll include both examples incase there is a neater solution. – m.j.higgins Jan 26 '15 at 13:07
  • $EmailContent 'Dear Some Name, here is your password...or click the link to login... http://www.someurl.com?action=Log%20In&username=someuser@test.com&pss=yYng6Ytzh Your log in details are: Username: your full email address (where this email was received) Password: yYng6Ytzh Some more bla bla Kind Regards, Admin So, I'd like to be able to keep the structure of the mail...but just before it get stored I need the password replaced with ******** As I can't do this on the mail out function...I'm looking to intercept the $EmailContent on the database save function. – m.j.higgins Jan 26 '15 at 13:13

3 Answers3

1

You can match the password and then use a look-behind to check that "Password:" is in-front of it:

/(?<=Password:)\s*[a-zA-Z0-9!@]+/

Edit: I had to move the quantifier outside the look-behind. This means that you need to left trim the match before using it.

You could also match it using a named group. It is a little cleaner, imo.

/(?<=Password:)\s*(?P<password>[a-zA-Z0-9!@]+)/
Sverri M. Olsen
  • 13,055
  • 3
  • 36
  • 52
  • This is looking like it's a winner! it's done want I want on the output...which I'm doing to test things before I move it to the save to communication log function... I'm wondering if I can adapt this to replace the password in the url also eg: http://www.someurl.com?action=Log%20In&username=someuser@test.com&pss=yYng6Ytzh OR would I pass it though twice? – m.j.higgins Jan 26 '15 at 13:19
  • just tested and this has done exactly what I needed to do so far!!!! $aDetails = preg_replace('/(?<=Password:)\s*(?P[a-zA-Z0-9!@]+)/', '*******', $string); $aDetails = preg_replace('/(?<=pss=)\s*(?P[a-zA-Z0-9!@]+)/', '*******', $aDetails); – m.j.higgins Jan 26 '15 at 13:24
0

You can try this solution:

$string = preg_replace_callback('#(?<=Password: )([^ ]+)#', function($match) {
                                                                return str_repeat('*', strlen($match[1]));
                                                            }, 'Password: yYng6Ytzh');

var_dump($string);
silkfire
  • 24,585
  • 15
  • 82
  • 105
0

It would be a good idea to not only redact the password, but also disassociate the length of the original password with the length of the replacement text. Rather than using asterisks, I'd use [redacted]. While you know there is a predictable range of characters (alphanumeric plus @ and !), I don't think there is any advantage in keeping that portion of the regex super-tight. Using the non-whitespace character \S will do just fine and keep the pattern small. Instead of using lookarounds or capture groups, just use \K to forget the matched Password: substring.

Code: (Demo)

$email = <<<TEXT
Dear Some Name,
here is your password
...or click the link to login... someurl.com?action=Log%20In&username=someuser@test.com&…
Your log in details are:
Username: your full email address (where this email was received)
Password: yYng6Ytzh Some more bla bla Kind Regards, Admin
TEXT;

echo preg_replace('~Password: \K\S+~', '[redacted]', $email);

Output:

Dear Some Name,
here is your password
...or click the link to login... someurl.com?action=Log%20In&username=someuser@test.com&…
Your log in details are:
Username: your full email address (where this email was received)
Password: [redacted] Some more bla bla Kind Regards, Admin
mickmackusa
  • 43,625
  • 12
  • 83
  • 136