3

Looking for tips on what characters I should be escaping in my regular expressions to prevent exploits.

e.g

Regular Expression Injection

The PCRE function preg_replace() function in PHP allows for an “e” (PREG_REPLACE_EVAL) modifier which means the replacement string will be evaluated as PHP after subsitution. Untrusted input used in the replacement string could therefore inject PHP code to be executed.

or here: http://hauser-wenz.de/playground/papers/RegExInjection.pdf

In general for sql injections there are lots of guides and tips to follow but cant find much about regex injection

Hard worker
  • 3,916
  • 5
  • 44
  • 73
  • https://www.owasp.org/index.php/PHP_Security_Cheat_Sheet#Code_Injection and http://stackoverflow.com/questions/4289923/in-which-languages-is-it-a-security-hole-to-use-user-supplied-regular-expression/4292439#4292439 – Mike B Jan 14 '14 at 13:12
  • You can't. You have to sanitize the input beforehand. For more exploitable PHP functions: http://stackoverflow.com/q/3115559/838733 – nietonfir Jan 14 '14 at 13:14
  • What are the general rules for sanitising input for all regular expressions functions of php? – Hard worker Jan 14 '14 at 13:49

4 Answers4

0

Simple answer: use preg_replace_callback() instead (which doesn't rely on eval of user code). That's what PHP 5.5 recommends you do when using /e.

$str = 'CAPS';
$str = preg_replace_callback('/[A-Z]/', function($match) { return strtolower($match[0]); }, $str);
echo $str;
Machavity
  • 30,841
  • 27
  • 92
  • 100
0

Use preg_quote to quote regular expression characters:

http://php.net/manual/en/function.preg-quote.php

You usually want to add your delimiter as the second argument.

e.g.

$q = $_GET['q'];
$q = preg_quote($q, "/");
$replaced = preg_replace("/" . $q . "/", "42", "The quick brown fox jumps over the lazy dog");
Alex
  • 2,398
  • 1
  • 16
  • 30
0

You should use Prepared Patterns - sort of like prepared statements in SQL - they protect you from any kind of pattern/input

<?php
$unsafe = $_GET['value'];
$pattern = Pattern::inject("(start|begin)@(end|finish)+", [$unsafe]]);

and then just use the pattern

$pattern->match($something);
Danon
  • 2,771
  • 27
  • 37
-1

this is only read the letters, and it ignores special character:

function sanitize_letter ($var) {

        $var= preg_replace("/[-[\]{}()*+?.,\\^<>&!@#$%^&\/':\";*()_+=$|#]/","",$var);

        return $var;
     }

this is only read the numbers, and it ignores special character:

function sanitize_number ($var) {

        $var= preg_replace("/[^0-9]/","",$var);
        return $var;
     }

for example, how you can use the above functions,

$pure_id=sanitize_number($_GET['id']);

Wria Mohammed
  • 1,433
  • 18
  • 23