Questions about this topic? Sign up to ask in the talk tab.

Difference between revisions of "Delete after length check"

From NetSec
Jump to: navigation, search
Line 1: Line 1:
 
Delete after length-check (Empty Where Clauses)
 
Delete after length-check (Empty Where Clauses)
  Proof of concept:
+
 
+
=Proof of concept=
  ------------------------
+
While the example here is based on SQL injection, it can apply to other scenarios as well.  Suppose the following php code:
  While the example here is based on SQL injection, it can apply to other scenarios as well.  Suppose the following php code:
+
  <?php
+
  # pwreset.php
+
  if (strlen($_GET['reset']) == 16) {
+
    $pwreset_code = preg_replace_all('/([^\w]+)/','',$_GET['reset']); #alphanumeric only.
+
    $user_query  = "SELECT * FROM user WHERE pwreset_code= '" . $pwresetcode ."' LIMIT 1";
+
    $user_data    = @mysql_query($user_query);
+
    ...
+
  }
+
  -----------------------
+
  pwreset.php?reset=''''''''''''''''
+
  The generated sql statement:
+
    SELECT * FROM user WHERE pwreset_code='' LIMIT 1;
+
  As reset codes are generated on reset request (forgot password form), this will leave the first user (usually the admin) of the web app exposed to arbitrary password overwrite.
+
  
Mitigation:
+
{{code|text=<source lang="php">
  Instead of checking length before replacement, verify after deletion.
+
<?php
  * PHP:
+
  # pwreset.php
    <?php
+
  if (strlen($_GET['reset']) == 16) {
    # pwreset.php
+
    $pwreset_code = preg_replace_all('/([^\w]+)/','',$_GET['reset']); #alphanumeric only.
    $pwreset_code = preg_replace_all('/([^\w]+)/','',$_GET['reset']); #alphanumeric only.
+
    $user_query  = "SELECT * FROM user WHERE pwreset_code= '" . $pwresetcode ."' LIMIT 1";
    if (strlen($pwreset) == 16) {
+
    $user_data    = @mysql_query($user_query);
      $user_query  = "SELECT * FROM user WHERE pwreset_code= '" . $pwresetcode ."' LIMIT 1";
+
    ...
      $user_data    = @mysql_query($user_query);
+
  }
      ...
+
    }
+
  
  
In the wild:
+
  // pwreset.php?reset=''''''''''''''''
    A Joomla! framework exploit leveraged this weakness for an administrative password reset (2008).  
+
  // The generated sql statement:
    CVE 2008-3861 http://www.exploit-db.com/exploits/6234/  
+
  // SELECT * FROM user WHERE pwreset_code='' LIMIT 1;
 
+
</source>}}
 +
 +
As reset codes are generated on reset request (forgot password form),  this will leave the first user (usually the admin) of the web app  exposed to arbitrary password overwrite.
 +
 +
=Mitigation=
 +
Instead of checking length before replacement, verify after deletion.
  
Auditing:
+
==PHP==
    Follow the same auditing steps as listed for unsafe deletion, with an eye towards where clauses or other empty type comparisons that could lead to problematic outcomes.
+
  
[[Category:Secure programming]]
+
{{code|text=<source lang="php">
 +
<?php
 +
  # pwreset.php
 +
  $pwreset_code = preg_replace_all('/([^\w]+)/','',$_GET['reset']); #alphanumeric only.
 +
  if (strlen($pwreset) == 16) {
 +
    $user_query  = "SELECT * FROM user WHERE pwreset_code= '" . $pwresetcode ."' LIMIT 1";
 +
    $user_data    = @mysql_query($user_query);
 +
    ...
 +
  }
 +
</source>}}
 +
 +
=In the wild=
 +
A Joomla! framework exploit leveraged this weakness for an administrative password reset (2008). [http://www.exploit-db.com/exploits/6234/ CVE 2008-3861]
 +
 +
=Auditing=
 +
Follow the same auditing steps as listed for unsafe deletion, with an  eye towards where clauses or other empty type comparisons that could  lead to problematic outcomes.

Revision as of 02:40, 12 May 2013

Delete after length-check (Empty Where Clauses)

Proof of concept

While the example here is based on SQL injection, it can apply to other scenarios as well. Suppose the following php code:

 
<?php
  # pwreset.php
  if (strlen($_GET['reset']) == 16) {
    $pwreset_code = preg_replace_all('/([^\w]+)/','',$_GET['reset']); #alphanumeric only.
    $user_query   = "SELECT * FROM user WHERE pwreset_code= '" . $pwresetcode ."' LIMIT 1";
    $user_data    = @mysql_query($user_query);
    ...
  }
 
 
  // pwreset.php?reset=''''''''''''''''
  //  The generated sql statement:
  //  SELECT * FROM user WHERE pwreset_code='' LIMIT 1;
 

As reset codes are generated on reset request (forgot password form), this will leave the first user (usually the admin) of the web app exposed to arbitrary password overwrite.

Mitigation

Instead of checking length before replacement, verify after deletion.

PHP

 
<?php
  # pwreset.php
  $pwreset_code = preg_replace_all('/([^\w]+)/','',$_GET['reset']); #alphanumeric only.
  if (strlen($pwreset) == 16) {
    $user_query   = "SELECT * FROM user WHERE pwreset_code= '" . $pwresetcode ."' LIMIT 1";
    $user_data    = @mysql_query($user_query);
    ...
  }
 

In the wild

A Joomla! framework exploit leveraged this weakness for an administrative password reset (2008). CVE 2008-3861

Auditing

Follow the same auditing steps as listed for unsafe deletion, with an eye towards where clauses or other empty type comparisons that could lead to problematic outcomes.