aidan           Wed Aug 11 06:03:20 2004 EDT

  Modified files:              
    /phpdoc/en/reference/mysql/functions        mysql-real-escape-string.xml 
  Log:
  Removed initial example
  Added a massive example with information about sql injection attacks
  Added more information to the % and _ note
  Added a variablelist
  
http://cvs.php.net/diff.php/phpdoc/en/reference/mysql/functions/mysql-real-escape-string.xml?r1=1.10&r2=1.11&ty=u
Index: phpdoc/en/reference/mysql/functions/mysql-real-escape-string.xml
diff -u phpdoc/en/reference/mysql/functions/mysql-real-escape-string.xml:1.10 
phpdoc/en/reference/mysql/functions/mysql-real-escape-string.xml:1.11
--- phpdoc/en/reference/mysql/functions/mysql-real-escape-string.xml:1.10       Wed 
Aug 11 06:01:42 2004
+++ phpdoc/en/reference/mysql/functions/mysql-real-escape-string.xml    Wed Aug 11 
06:03:20 2004
@@ -1,11 +1,12 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
-<!-- $Revision: 1.10 $ -->
+<!-- $Revision: 1.11 $ -->
 <!-- splitted from ./en/functions/mysql.xml, last change in rev 1.100 -->
   <refentry id="function.mysql-real-escape-string">
    <refnamediv>
     <refname>mysql_real_escape_string</refname>
     <refpurpose>
-     Escapes special characters in a string for use in a SQL statement, taking into 
account the current charset of the connection.
+     Escapes special characters in a string for use in a SQL statement,
+     taking into account the current charset of the connection.
     </refpurpose>
    </refnamediv>
    <refsect1>
@@ -16,46 +17,131 @@
      <methodparam 
choice="opt"><type>resource</type><parameter>link_identifier</parameter></methodparam>
     </methodsynopsis>
     <para>
+     <variablelist>
+      <varlistentry>
+       <term><parameter>unescaped_string</parameter></term>
+       <listitem><simpara>The string to escape</simpara>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><parameter>link_identifier</parameter> (optional)</term>
+       <listitem><simpara>The mysql connection resource</simpara></listitem>
+      </varlistentry>
+     </variablelist>
+    </para>
+    <para>
      This function will escape special characters in the
      <parameter>unescaped_string</parameter>, taking into account the current
      charset of the connection so that it is safe to place it in a
-     <function>mysql_query</function>. 
+     <function>mysql_query</function>. If you wish to insert binary data
+     you must use this function.
+    </para>
+    <para>
+     mysql_real_escape_string calls MySQL's library function of the
+     same name, which prepends slashes to the following characters:
+     <literal>NULL</literal>, <literal>\x00</literal>, <literal>\n</literal>,
+     <literal>\r</literal>, <literal>\</literal>, <literal>'</literal>,
+     <literal>"</literal> and <literal>\x1a</literal>.
+    </para>
+    <para>
+     You must always (with few exceptions) use this function
+     to make your data safe before inserting. If you have
+     <link linkend="ini.magic-quotes-gpc">magic_quotes_gpc</link> enabled,
+     you must first <function>stripslashes</function> your data. If you don't use
+     this, you'll leave yourself open to SQL Injection Attacks. Here's an example:
     </para>
-    <note>
-     <simpara>
-      <function>mysql_real_escape_string</function> does not escape
-      <literal>%</literal> and <literal>_</literal>.
-     </simpara>
-    </note>
     <para>
      <example>
-      <title><function>mysql_real_escape_string</function> example</title>
+      <title>An example SQL Injection Attack</title>
       <programlisting role="php">
 <![CDATA[
 <?php
-$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
-if (!$link) {
-    die('Could not connect: ' . mysql_error());
-}
-$item = "Zak's and Derick's Laptop";
-$escaped_item = mysql_real_escape_string($item, $link);
-printf("Escaped string: %s\n", $escaped_item);
+// Query database to check if there are any matching users
+$query = "SELECT * FROM users WHERE user='{$_POST['username']}' AND 
password='{$_POST['password']}'";
+mysql_query($query);
+
+// We didn't check $_POST['password'], it could be anything the user wanted! For 
example:
+$_POST['username'] = 'aidan';
+$_POST['password'] = "' OR 1=1";
+
+// This means the query sent to MySQL would be:
+echo $query;
 ?>
 ]]>
       </programlisting>
-      <para>
-       The above example would produce the following output:
-      </para>
+       <para>
+        The query sent to MySQL:
+       </para>
       <screen>
 <![CDATA[
-Escaped string: Zak\'s and Derick\'s Laptop
+SELECT * FROM users WHERE name='fred' AND password='' OR 1=1
 ]]>
       </screen>
+      <para>
+       This would allow anyone to log in without a valid password! Using
+       <function>mysql_real_escape_string</function> around each variable
+       prevents this.
+      </para>
+      <programlisting role="php">
+<![CDATA[
+<?php
+/**
+ * Apply stripslashes recursively
+ */
+function stripslashes_deep($value)
+{
+    $value = is_array($value) ?
+                array_map('stripslashes_deep', $value) :
+                stripslashes($value);
+
+    return $value;
+}
+
+/**
+ * Quote a variable to make it safe for insertion
+ */
+function quote_smart($value)
+{
+    // Stripslashes if we need to
+    if (get_magic_quotes_gpc()) {
+        $value = stripslashes_deep($value);
+    }
+
+    // Quote it if it's not an interger
+    if (!is_int($value)) {
+        $value = "'" . mysql_real_escape_string($value) . "'";
+    }
+
+    return $value;
+}
+
+// Connect
+$link = mysql_connect('localhost', 'mysql_user', 'mysql_password')
+    OR die('Could not connect: ' . mysql_error());
+
+// Make a safe query
+$query = sprintf("SELECT * FROM users WHERE user=%s AND password=%s",
+            quote_smart($_POST['username']),
+            quote_smart($_POST['password']));
+
+mysql_query($query);
+?>
+]]>
+      </programlisting>
+      <para>
+       Our query is now safe no matter what the user submits!
+      </para>
      </example>
     </para>
+    <note>
+     <simpara>
+      <function>mysql_real_escape_string</function> does not escape
+      <literal>%</literal> and <literal>_</literal>. These are wildcards in MySQL
+      if not bounded by quotes.
+     </simpara>
+    </note>
     <para>
      See also
-     <function>mysql_escape_string</function>,
      <function>mysql_client_encoding</function>,
      <function>addslashes</function>, and the 
      <link linkend="ini.magic-quotes-gpc">magic_quotes_gpc</link>

Reply via email to