Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <p><strong>Warning:</strong> This answer's sample code (like the question's sample code) uses PHP's <code>mysql</code> extension, which was deprecated in PHP 5.5.0 and removed entirely in PHP 7.0.0.</p> </blockquote> <p>If you're using a recent version of PHP, the <code>mysql_real_escape_string</code> option outlined below will no longer be available (though <code>mysqli::escape_string</code> is a modern equivalent). These days the <code>mysql_real_escape_string</code> option would only make sense for legacy code on an old version of PHP.</p> <hr> <p>You've got two options - escaping the special characters in your <code>unsafe_variable</code>, or using a parameterized query. Both would protect you from SQL injection. The parameterized query is considered the better practice but will require changing to a newer mysql extension in PHP before you can use it.</p> <p>We'll cover the lower impact string escaping one first.</p> <pre><code>//Connect $unsafe_variable = $_POST["user-input"]; $safe_variable = mysql_real_escape_string($unsafe_variable); mysql_query("INSERT INTO table (column) VALUES ('" . $safe_variable . "')"); //Disconnect </code></pre> <p>See also, the details of the <a href="http://php.net/mysql_real_escape_string" rel="noreferrer"><code>mysql_real_escape_string</code></a> function.</p> <p>To use the parameterized query, you need to use <a href="http://php.net/mysqli" rel="noreferrer">MySQLi</a> rather than the <a href="http://php.net/mysql" rel="noreferrer">MySQL</a> functions. To rewrite your example, we would need something like the following.</p> <pre><code>&lt;?php $mysqli = new mysqli("server", "username", "password", "database_name"); // TODO - Check that connection was successful. $unsafe_variable = $_POST["user-input"]; $stmt = $mysqli-&gt;prepare("INSERT INTO table (column) VALUES (?)"); // TODO check that $stmt creation succeeded // "s" means the database expects a string $stmt-&gt;bind_param("s", $unsafe_variable); $stmt-&gt;execute(); $stmt-&gt;close(); $mysqli-&gt;close(); ?&gt; </code></pre> <p>The key function you'll want to read up on there would be <a href="http://php.net/mysqli.prepare" rel="noreferrer"><code>mysqli::prepare</code></a>.</p> <p>Also, as others have suggested, you may find it useful/easier to step up a layer of abstraction with something like <a href="http://php.net/pdo" rel="noreferrer">PDO</a>.</p> <p>Please note that the case you asked about is a fairly simple one and that more complex cases may require more complex approaches. In particular:</p> <ul> <li>If you want to alter the structure of the SQL based on user input, parameterized queries are not going to help, and the escaping required is not covered by <code>mysql_real_escape_string</code>. In this kind of case, you would be better off passing the user's input through a whitelist to ensure only 'safe' values are allowed through.</li> <li>If you use integers from user input in a condition and take the <code>mysql_real_escape_string</code> approach, you will suffer from the problem described by <a href="https://stackoverflow.com/users/978756/polynomial">Polynomial</a> in the comments below. This case is trickier because integers would not be surrounded by quotes, so you could deal with by validating that the user input contains only digits.</li> <li>There are likely other cases I'm not aware of. You might find <a href="http://webappsec.org/projects/articles/091007.txt" rel="noreferrer">this</a> is a useful resource on some of the more subtle problems you can encounter.</li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload