Skip to content

Commit

Permalink
Add a processor to sanitize the HTTP headers
Browse files Browse the repository at this point in the history
  • Loading branch information
ste93cry committed Mar 13, 2017
1 parent c2f44ee commit 384d630
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
``call_existing`` is true and no exception handler is registered (#421).
- Collect User.ip_address automatically (#419).
- Added a processor to remove web cookies and another to remove HTTP body data for POST, PUT, PATCH and DELETE requests. They will be enabled by default in ``2.0`` (#405).
- Added a processor to sanitize HTTP headers (e.g. the Authorization header) (#428).

1.6.2
-----
Expand Down
17 changes: 17 additions & 0 deletions lib/Raven/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ class Raven_Client
protected $error_handler;
protected $error_types;

/**
* @var string[] The list of HTTP headers to sanitize
*/
protected $sanitize_http_headers = [];

protected $serializer;
protected $reprSerializer;

Expand Down Expand Up @@ -172,6 +177,7 @@ public function __construct($options_or_dsn = null, $options = array())
$this->transport = Raven_Util::get($options, 'transport', null);
$this->mb_detect_order = Raven_Util::get($options, 'mb_detect_order', null);
$this->error_types = Raven_Util::get($options, 'error_types', null);
$this->sanitize_http_headers = Raven_Util::get($options, 'sanitize_http_headers', array());

// app path is used to determine if code is part of your application
$this->setAppPath(Raven_Util::get($options, 'app_path', null));
Expand Down Expand Up @@ -358,6 +364,17 @@ public static function getUserAgent()
return 'sentry-php/' . self::VERSION;
}

/**
* Gets the list of HTTP headers to sanitize. Only the Authorization header
* is removed by default.
*
* @return string[]
*/
public function getSanitizeHttpHeaders()
{
return $this->sanitize_http_headers;
}

/**
* Set a custom transport to override how Sentry events are sent upstream.
*
Expand Down
58 changes: 58 additions & 0 deletions lib/Raven/Processor/SanitizeHttpHeadersProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

/*
* This file is part of Raven.
*
* (c) Sentry Team
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

/**
* This processor sanitizes the configured HTTP headers to ensure no sensitive
* informations are sent to the server.
*
* @author Stefano Arlandini <[email protected]>
*/
final class Raven_Processor_SanitizeHttpHeadersProcessor extends Raven_Processor
{
/**
* @var string[] $httpHeadersToSanitize The list of HTTP headers to sanitize
*/
private $httpHeadersToSanitize;

/**
* {@inheritdoc}
*/
public function __construct(Raven_Client $client)
{
parent::__construct($client);

$this->httpHeadersToSanitize = array_merge($this->getDefaultHeaders(), $client->getSanitizeHttpHeaders());
}

/**
* {@inheritdoc}
*/
public function process(&$data)
{
if (isset($data['request']) && isset($data['request']['headers'])) {
foreach ($data['request']['headers'] as $header => &$value) {
if (in_array($header, $this->httpHeadersToSanitize)) {
$value = self::STRING_MASK;
}
}
}
}

/**
* Gets the list of default headers that must be sanitized.
*
* @return string[]
*/
private function getDefaultHeaders()
{
return array('Authorization', 'Proxy-Authorization', 'X-Csrf-Token', 'X-CSRFToken', 'X-XSRF-TOKEN');
}
}
10 changes: 10 additions & 0 deletions test/Raven/Tests/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1653,6 +1653,16 @@ public function testGetUserAgent()
$this->assertRegExp('|^[0-9a-z./_-]+$|i', Raven_Client::getUserAgent());
}

public function testGetSanitizeHttpHeaders()
{
$headersToSanitize = array('foo', 'bar');
$client = new Dummy_Raven_Client(null, array(
'sanitize_http_headers' => $headersToSanitize,
));

$this->assertEquals($headersToSanitize, $client->getSanitizeHttpHeaders());
}

public function testCaptureExceptionWithLogger()
{
$client = new Dummy_Raven_Client();
Expand Down
84 changes: 84 additions & 0 deletions test/Raven/Tests/Processor/SanitizeHttpHeadersProcessorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

/*
* This file is part of Raven.
*
* (c) Sentry Team
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

class Raven_SanitizeHttpHeadersProcessorTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \Raven_Processor_SanitizeHttpHeadersProcessor|\PHPUnit_Framework_MockObject_MockObject
*/
protected $processor;

protected function setUp()
{
/** @var \Raven_Client|\PHPUnit_Framework_MockObject_MockObject $client */
$client = $this->getMockBuilder('\Raven_Client')
->disableOriginalConstructor()
->getMock();

$client->expects($this->once())
->method('getSanitizeHttpHeaders')
->willReturn(array('User-Defined-Header'));

$this->processor = new Raven_Processor_SanitizeHttpHeadersProcessor($client);
}

/**
* @dataProvider processDataProvider
*/
public function testProcess($inputData, $expectedData)
{
$this->processor->process($inputData);

$this->assertArraySubset($expectedData, $inputData);
}

public function processDataProvider()
{
return array(
array(
array(
'request' => array(
'headers' => array(
'Authorization' => 'foo',
'AnotherHeader' => 'bar',
),
),
),
array(
'request' => array(
'headers' => array(
'Authorization' => Raven_Processor::STRING_MASK,
'AnotherHeader' => 'bar',
),
),
),
),
array(
array(
'request' => array(
'headers' => array(
'User-Defined-Header' => 'foo',
'AnotherHeader' => 'bar',
),
),
),
array(
'request' => array(
'headers' => array(
'User-Defined-Header' => Raven_Processor::STRING_MASK,
'AnotherHeader' => 'bar',
),
),
),
),
);
}
}

0 comments on commit 384d630

Please sign in to comment.