diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index eff4339..74583e6 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -63,6 +63,11 @@ public function getConfigTreeBuilder() ->treatNullLike(array()) ->end() ->end() + ->arrayNode('filteredRequestParams') + ->prototype('scalar') + ->treatNullLike(array()) + ->end() + ->end() ->scalarNode('mailer') ->defaultValue('mailer') ->end() diff --git a/Listener/Notifier.php b/Listener/Notifier.php index 1538726..8d44205 100644 --- a/Listener/Notifier.php +++ b/Listener/Notifier.php @@ -57,6 +57,7 @@ class Notifier private $ignoredIPs; private $ignoredAgentsPattern; private $ignoredUrlsPattern; + private $filteredRequestParams; private $command; private $commandInput; @@ -72,22 +73,23 @@ class Notifier */ public function __construct(Swift_Mailer $mailer, EngineInterface $templating, $cacheDir, $config) { - $this->mailer = $mailer; - $this->templating = $templating; - $this->from = $config['from']; - $this->to = $config['to']; - $this->handle404 = $config['handle404']; - $this->handleHTTPcodes = $config['handleHTTPcodes']; - $this->reportErrors = $config['handlePHPErrors']; - $this->reportWarnings = $config['handlePHPWarnings']; - $this->reportSilent = $config['handleSilentErrors']; - $this->ignoredClasses = $config['ignoredClasses']; - $this->ignoredPhpErrors = $config['ignoredPhpErrors']; - $this->repeatTimeout = $config['repeatTimeout']; - $this->errorsDir = $cacheDir . '/errors'; - $this->ignoredIPs = $config['ignoredIPs']; - $this->ignoredAgentsPattern = $config['ignoredAgentsPattern']; - $this->ignoredUrlsPattern = $config['ignoredUrlsPattern']; + $this->mailer = $mailer; + $this->templating = $templating; + $this->from = $config['from']; + $this->to = $config['to']; + $this->handle404 = $config['handle404']; + $this->handleHTTPcodes = $config['handleHTTPcodes']; + $this->reportErrors = $config['handlePHPErrors']; + $this->reportWarnings = $config['handlePHPWarnings']; + $this->reportSilent = $config['handleSilentErrors']; + $this->ignoredClasses = $config['ignoredClasses']; + $this->ignoredPhpErrors = $config['ignoredPhpErrors']; + $this->repeatTimeout = $config['repeatTimeout']; + $this->errorsDir = $cacheDir . '/errors'; + $this->ignoredIPs = $config['ignoredIPs']; + $this->ignoredAgentsPattern = $config['ignoredAgentsPattern']; + $this->ignoredUrlsPattern = $config['ignoredUrlsPattern']; + $this->filteredRequestParams = $config['filteredRequestParams']; if (!is_dir($this->errorsDir)) { mkdir($this->errorsDir); @@ -330,7 +332,7 @@ public function createMailAndSend($exception, Request $request = null, $context $body = $this->templating->render('ElaoErrorNotifierBundle::mail.html.twig', array( 'exception' => $exception, - 'request' => $request, + 'request' => $this->filterRequest($request), 'status_code' => $exception->getCode(), 'context' => $context, 'command' => $command, @@ -361,6 +363,49 @@ public function createMailAndSend($exception, Request $request = null, $context $this->mailer->send($mail); } + /** + * Filter custom parameters, $_POST, $_GET and $_COOKIES. Replace properties + * defined in the filterList with stars. + * + * @param Request $request + * @return Request $request + */ + private function filterRequest(Request $request) + { + if (count($this->filteredRequestParams) === 0) { + return $request; + } + + $replaceWith = '*******'; + + foreach (['request', 'query', 'attributes', 'cookies'] as $type) { + foreach ($request->$type as $key => $value) { + // filter key => value parameters by key name + if (in_array($key, $this->filteredRequestParams)) { + $request->$type->set($key, $replaceWith); + continue; + } + + // filter array values in parameters by key names inside the array + if (is_array($value)) { + $found = false; + foreach ($value as $valKey => $valValue) { + if (in_array($valKey, $this->filteredRequestParams)) { + $found = true; + $value[$valKey] = $replaceWith; + } + } + + if ($found) { + $request->$type->set($key, $value); + } + } + } + } + + return $request; + } + /** * Check last send time * diff --git a/README.md b/README.md index 8d3d404..9fac9e6 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # Elao ErrorNotifier Bundle -[![Latest Stable Version](https://poser.pugx.org/elao/error-notifier-bundle/v/stable)](https://packagist.org/packages/elao/error-notifier-bundle) -[![Total Downloads](https://poser.pugx.org/elao/error-notifier-bundle/downloads)](https://packagist.org/packages/elao/error-notifier-bundle) +[![Latest Stable Version](https://poser.pugx.org/elao/error-notifier-bundle/v/stable)](https://packagist.org/packages/elao/error-notifier-bundle) +[![Total Downloads](https://poser.pugx.org/elao/error-notifier-bundle/downloads)](https://packagist.org/packages/elao/error-notifier-bundle) [![Monthly Downloads](https://poser.pugx.org/elao/error-notifier-bundle/d/monthly)](https://packagist.org/packages/elao/error-notifier-bundle) -[![Latest Unstable Version](https://poser.pugx.org/elao/error-notifier-bundle/v/unstable)](https://packagist.org/packages/elao/error-notifier-bundle) +[![Latest Unstable Version](https://poser.pugx.org/elao/error-notifier-bundle/v/unstable)](https://packagist.org/packages/elao/error-notifier-bundle) [![License](https://poser.pugx.org/elao/error-notifier-bundle/license)](https://packagist.org/packages/elao/error-notifier-bundle) ## What is it? @@ -74,6 +74,7 @@ elao_error_notifier: handlePHPErrors: true # catch fatal erros and email them handlePHPWarnings: true # catch warnings and email them handleSilentErrors: false # don't catch error on method with an @ + filteredRequestParams: [password] # replace request contents of parameter "password" with stars ignoredClasses: ~ ``` @@ -183,7 +184,7 @@ elao_error_notifier: ### How to ignore sending HTTP errors if the user agent match a given pattern? For some reasons you may need to ignore sending notifications if request comes from some user agents. -Often you will need to use this feature with annoying crawlers which uses artificial intelligence +Often you will need to use this feature with annoying crawlers which uses artificial intelligence to generate URLs which may not exist in your site. ```yml @@ -201,6 +202,18 @@ For example if you want to ignore all not exist images errors you may do somethi elao_error_notifier: ignoredUrlsPattern: "\.(jpg|png|gif)" ``` +### How to filter sensitive data in request variables? + +Sometimes you don't want to receive passwords or other sensitive data via email. With `filteredRequestParams` you can specify request variable names which should be replaced with stars. This works for named forms, too (e.g. `myFormName[password]`). + +```yml +# app/config/config_prod.yml +elao_error_notifier: + filteredRequestParams: + - "password" + - "creditCardNo" + - "_token" +``` ## Screenshot