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,636
  • 5
  • 39
  • 71
  • 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
  • 29,816
  • 26
  • 86
  • 96
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,283
  • 1
  • 14
  • 28
0

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,074
  • 13
  • 21
0

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

$unsafe = $_GET['value'];
Pattern::prepare(["(start|begin)", [$unsafe], "(end|finish)+"]);
Danon
  • 2,190
  • 20
  • 34