2

I'm not experienced with PHP and have to redact the password in the following code:

    $body=array(
        'userInfo' => array(
            'userName' => $username,
            'password' => $password,
            'applicationKey' => $appKey,
        ),
    );

The variable $body is used both in application logic, and in logging the array:

$this->logger->debug("REQUEST: URL[{$this->config->endpoint}] BODY: " . json_encode($body));

But I should not be logging the password. I'd like to redact it.

I know I could just copy and paste the array to a new variable $body_with_password_hidden but I'd like to learn some PHP idioms, not to mention keep the code base as compact as realistically possible.

What would be an elegant way to do this? In a language I am more comfortable, I would clone the dictionary, and overwrite the sensitive value. How would I do this in PHP?

More info

Current log statement:

[2018-04-10T18:23:11+00:00] [DEBUG] REQUEST: URL[http://myservice.com/myendpoint/login] BODY: {"userInfo":{"userName":"Administrator","password":"Administrator","applicationKey":"abc123"}} -

Desired log statement:

[2018-04-10T18:23:11+00:00] [DEBUG] REQUEST: URL[http://myservice.com/myendpoint/login] BODY: {"userInfo":{"userName":"Administrator","password":"********","applicationKey":"abc123"}} -
Sridhar Sarnobat
  • 25,183
  • 12
  • 93
  • 106
  • 2
    Same as you said - clone value and remove key. – u_mulder Apr 10 '18 at 18:31
  • 2
    $body['userInfo']['password'] = ''; should do the trick. – Adam Apr 10 '18 at 18:31
  • Possible duplicate of [PHP: How to remove specific element from an array?](https://stackoverflow.com/questions/2448964/php-how-to-remove-specific-element-from-an-array) – William Perron Apr 10 '18 at 18:34
  • Read about [PHP arrays](http://php.net/manual/en/language.types.array.php). The answer to your question can be found on the ["accessing with square brackets syntax" section](http://php.net/manual/en/language.types.array.php#language.types.array.syntax.accessing). – axiac Apr 10 '18 at 18:34

5 Answers5

4

You can override this value directly:

$body['userInfo']['password'] = null;

or just remove a whole key:

unset($body['userInfo']['password']);
Michał Szczech
  • 466
  • 4
  • 17
  • You’d need to make a copy of the array, or do logging only after using the password in the business logic, hence my preference for the other solution. But thank you still. – Sridhar Sarnobat May 03 '18 at 01:55
3

You can create a template that matches the structure of your data, with your desired redaction symbol as a value for the appropriate key.

$redacted = ['userInfo' => ['password' => '********']];

Then use array_replace_recursive to overwrite the value in the original data when you log it.

$this->logger->debug(
    "REQUEST: URL[{$this->config->endpoint}] BODY: "
    . json_encode(array_replace_recursive($body, $redacted))
);

This may be kind of overkill for overwriting a single value, but could be a neater way of doing it if you ever have a more complex structure with more values that need to be replaced.

Don't Panic
  • 41,125
  • 10
  • 61
  • 80
1

You can just pop a value into the array, based on the key's name. So you have the following:

$body=array(
        'userInfo' => array(
            'userName' => $username,
            'password' => $password,
            'applicationKey' => $appKey,
        ),
    );

You could then do:

$body['userInfo']['password'] = null;

And that would set the key within userInfo to a null value.

Adam
  • 1,149
  • 2
  • 14
  • 21
1

I think the shortest way would be the make a copy of the array, and log it with the modified password value.

$body_with_password_hidden = $body;
$body_with_password_hidden['userInfo']['password'] = "********";

Then log the $body_with_password_hidden

Ice76
  • 1,143
  • 8
  • 16
0

I built a package to do this very thing. It's pretty easy to use. https://github.com/mtownsend5512/array-redactor

$body = (new \Mtownsend\ArrayRedactor\ArrayRedactor(array(
    'userInfo' => array(
        'userName' => $username,
        'password' => $password,
        'applicationKey' => $appKey,
    ),
), ['password']))->redact();

$this->logger->debug("REQUEST: URL[{$this->config->endpoint}] BODY: " . json_encode($body));

You can redact any array key you wish by providing it in the second constructor argument. In the above example we're only redacting password. The package also supports deep-nested keys.

Mark
  • 1,255
  • 1
  • 13
  • 25