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?
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"}} -
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.
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.
You can override this value directly:
$body['userInfo']['password'] = null;
or just remove a whole key:
unset($body['userInfo']['password']);
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
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.