Skip to content

Commit 31a02ff

Browse files
authored
Merge pull request #60 from stfndamjanovic/header-sanitizer
Add option to sanitize sensitive headers
2 parents 77bc41f + a10c750 commit 31a02ff

File tree

5 files changed

+103
-1
lines changed

5 files changed

+103
-1
lines changed

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ return [
6868
'password',
6969
'password_confirmation',
7070
],
71+
72+
/*
73+
* List of headers that will be sanitized. For example Authorization, Cookie, Set-Cookie...
74+
*/
75+
'sanitize_headers' => [],
7176
];
7277
```
7378

@@ -138,6 +143,25 @@ public function logRequest(Request $request): void
138143
}
139144
```
140145

146+
#### Hide sensitive headers
147+
148+
You can define headers that you want to sanitize before sending them to the log.
149+
The most common example would be Authorization header. If you don't want to log jwt token, you can add that header to `http-logger.php` config file:
150+
151+
```php
152+
// in config/http-logger.php
153+
154+
return [
155+
// ...
156+
157+
'sanitize_headers' => [
158+
'Authorization'
159+
],
160+
];
161+
```
162+
163+
Output would be `Authorization: "****"` instead of `Authorization: "Bearer {token}"`
164+
141165
### Testing
142166

143167
``` bash

config/http-logger.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,8 @@
3232
'password_confirmation',
3333
],
3434

35+
/*
36+
* List of headers that will be sanitized. For example Authorization, Cookie, Set-Cookie...
37+
*/
38+
'sanitize_headers' => [],
3539
];

src/DefaultLogWriter.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
class DefaultLogWriter implements LogWriter
1111
{
12+
protected $sanitizer;
13+
1214
public function logRequest(Request $request)
1315
{
1416
$message = $this->formatMessage($this->getMessage($request));
@@ -26,7 +28,7 @@ public function getMessage(Request $request)
2628
'method' => strtoupper($request->getMethod()),
2729
'uri' => $request->getPathInfo(),
2830
'body' => $request->except(config('http-logger.except')),
29-
'headers' => $request->headers->all(),
31+
'headers' => $this->getSanitizer()->clean($request->headers->all(), config('http-logger.sanitize_headers')),
3032
'files' => $files,
3133
];
3234
}
@@ -51,4 +53,13 @@ public function flatFiles($file)
5153

5254
return (string) $file;
5355
}
56+
57+
protected function getSanitizer()
58+
{
59+
if (!$this->sanitizer instanceof Sanitizer) {
60+
$this->sanitizer = new Sanitizer();
61+
}
62+
63+
return $this->sanitizer;
64+
}
5465
}

src/Sanitizer.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace Spatie\HttpLogger;
4+
5+
class Sanitizer
6+
{
7+
protected string $mask;
8+
9+
public function __construct(string $mask = "****")
10+
{
11+
$this->mask = $mask;
12+
}
13+
14+
public function clean(array $input, $keys)
15+
{
16+
$keys = (array) $keys;
17+
18+
if (count($keys) === 0) {
19+
return $input;
20+
}
21+
22+
$keys = array_map([$this, 'normalize'], $keys);
23+
24+
foreach ($input as $key => $value) {
25+
$normalizedKey = $this->normalize($key);
26+
27+
if (in_array($normalizedKey, $keys)) {
28+
$input[$key] = is_array($value) ? [$this->mask] : $this->mask;
29+
30+
continue;
31+
}
32+
33+
if (is_array($value)) {
34+
$input[$key] = $this->clean($value, $keys);
35+
}
36+
}
37+
38+
return $input;
39+
}
40+
41+
public function normalize(string $string)
42+
{
43+
return strtolower($string);
44+
}
45+
46+
public function setMask(string $mask)
47+
{
48+
$this->mask = $mask;
49+
}
50+
}

tests/DefaultLogWriterTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,16 @@
127127
assertStringContainsString('testing.DEBUG', $log);
128128
assertStringContainsString('"name":"Name', $log);
129129
});
130+
131+
it('will sanitize sensitive headers', function () {
132+
config(['http-logger.sanitize_headers' => ['Authorization']]);
133+
134+
$request = $this->makeRequest('post', $this->uri, [], [], [], ['HTTP_Authorization' => 'Bearer {token}', 'HTTP_Api-Version' => '2.4.12']);
135+
136+
$this->logger->logRequest($request);
137+
138+
$log = $this->readLogFile();
139+
140+
assertStringContainsString('"authorization":["****"]', $log);
141+
assertStringContainsString('"api-version":["2.4.12"]', $log);
142+
});

0 commit comments

Comments
 (0)