Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The result is stored in the <code>$result</code> array, not the PDO object <code>$one</code>. This also needs an echo if you're not going to use shorttags.</p> <pre><code>&lt;input type="text" placeholder="&lt;?php echo $result['gr_name']; ?&gt;"&gt; </code></pre> <p>I'd use shorttags, so if you PHP setup has them enabled, but they are being deprecated in PHP 5.6:</p> <pre><code>&lt;input type="text" placeholder="&lt;?= $result['gr_name']; ?&gt;"&gt; </code></pre> <p>You can use shorttags for now, and I will continue to use them to protest the removal of this incredibly useful feature. Deprecating shorttags will break a lot of WP themes and simple template engines!</p> <p>You should also consider using <a href="http://php.net/manual/en/pdo.prepared-statements.php" rel="nofollow">prepared statements</a>. Without them, this script is vulnerable to SQL injections.</p> <pre><code>&lt;?php $query = $pdo-&gt;prepare("SELECT * FROM contactgroups WHERE id=:id"); if( $query-&gt;execute(array(':id' =&gt; $_GET['id'])) ) { $result = $query-&gt;fetch(); ?&gt; &lt;input type="text" placeholder="&lt;?php echo $result['gr_name']; ?&gt;" /&gt; &lt;?php } ?&gt; </code></pre> <p><strong>How PDO Prevents SQL Injection (too long to put in a comment - scroll down to see a better explanation)</strong><br> Let's begin with a query:</p> <pre><code>mysql_query("DELETE FROM users WHERE id='".$id."'"); </code></pre> <p>If <code>$id = "' OR 1=1 --";</code> then the query would look like this when sent to MySQL (-- signifies the start of a comment):</p> <pre><code>DELETE FROM users WHERE id='' OR 1=1 --' </code></pre> <p>Obviously, the destruction that would follow could be catastrophic and possibly unreversible (unless you've got some smart DB admins). The fix here instead of using the lengthy, <code>mysql_real_escape_string()</code> (I really never understood why the function name was so wordy in the first place), we can now use PDO prepared statements. </p> <p>By <a href="http://php.net/manual/en/pdo.prepare.php" rel="nofollow"><code>PDO::preparing()</code></a> a statement you are sending a message to your DB telling it to store and optimize this query because it will be used later. Your DB stores an optimized query, taking careful note of where the data belongs.</p> <pre><code>$statement = $pdo-&gt;prepare('DELETE FROM users WHERE id=:id'); </code></pre> <p>PDO will give you an instance of <a href="http://www.php.net/manual/en/class.pdostatement.php" rel="nofollow">PDOStatement</a> that you can <a href="http://php.net/manual/en/pdostatement.bindparam.php" rel="nofollow"><code>PDO::bindParam()</code></a> values to and execute. So let's do that and execute.</p> <pre><code>$statement-&gt;bindParam(':id', $id); $statement-&gt;execute(); </code></pre> <p>Now some behind the scenes magic happens here. PDO sends the data to MySQL. MySQL examines the data and inserts into the prepared statement. By knowing where the data was supposed to be placed and how long the inserted data was, MySQL can determine the character ranges in a query that don't need execute (read: the data). So, when a hacker tries an SQL injection, MySQL doesn't even worry about evaluating anything that is bound to the prepared statement.</p> <ol> <li>PDO says to MySQL, <code>"The data for :id is ' OR 1=1 --"</code></li> <li>MySQL finds the location where :id was in the prepared statement. (In this example, character 28)</li> <li>MySQL counts the length of the data (In this case, 11 characters)</li> <li>MySQL does 1st grade math and remembers that it should treat everything from character 28 to 39 as characters.</li> <li><p>MySQL inserts the data and now the query looks like this: </p> <p><code>DELETE FROM users WHERE id=' OR 1=1 --</code></p></li> <li><p>However, because it knows the position of the data, MySQL only analyzes everything outside of the pipes (|) for commands and keywords. </p> <p><code>DELETE FROM users WHERE id=|' OR 1=1 --|</code></p></li> </ol> <p>So the text between the pipes never actually gets analyzed. When MySQL needs compare id's it still compares id's in the table with the data, but since the data was never executed, the SQL injection fails.</p> <h1>A Better Explanation of How PDO Prevents SQL Injections</h1> <p>When we prepare a statement with PDO, it notifies the database of the upcoming query and where the data will be in the query. When we bind data to that query and execute it the database does some behind the scenes work to make sure that SQL injections are thwarted.<br> Let's take this behind the scenes work to another context. You manage a PHP blog whose engine you wrote entirely by yourself. You are proud of the clever comment system you wrote until some jerk decides to post this comment:</p> <pre><code>&lt;script type="text/javascript"&gt; alert('You just been H4X0RED!!!!1 LOLS'); &lt;/script&gt; </code></pre> <p>After you yell some four letter words at the computer screen and make sure that the script kiddie's parents never let him on the internet again, you solve the XSS vulnerability in your code with <code>htmlspecialchars()</code>.</p> <pre><code>$comment_text = htmlspecialchars($_POST['comment_text']); </code></pre> <p>Now what have you done here? When the script kiddie wakes up at 3 AM and sneaks down to his computer to try the code again, <code>htmlspecialchars()</code> turns his lame attempt at humor into a jibberish mess. The function takes any character that is important in HTML (namely the <code>&lt;</code> and <code>&gt;</code>) and turns them into their literal value (<code>&amp;lt;</code> and <code>&amp;gt;</code>).</p> <pre><code>&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt; alert('You just been H4X0RED!!!!1 LOLS'); &amp;lt;/script&amp;gt; </code></pre> <p>The HTML parser in everyone's browser interprets the <code>&amp;lt</code> not as the beginning of an HTML tag, but as a sign to actually output the character <code>&lt;</code>. This is essentially what the database engine does with all data inputted into prepared statements. Except since in SQL letters make up valid commands (and also valid data), the engine interprets all characters in the data as their literal value. So instead of:</p> <pre><code>DELETE FROM users WHERE id = 0 OR 1=1 --' </code></pre> <p>It evaluates each character in the data as it's literal value. In HTML that would be:</p> <pre><code>DELETE FROM users WHERE id = &amp;#48;&amp;#32;&amp;#79;&amp;#82;&amp;#32;&amp;#49;&amp;#61;&amp;#49;&amp;#32;&amp;#45;&amp;#45;&amp;#39; </code></pre> <p>If you look at <a href="http://jsbin.com/ujulak/edit#html,live" rel="nofollow">both here</a>, they both output the same thing, except in the second, the 'data' is being interpreted as it's literal value by the parser and not it's functional value. The SQL does the same thing. By using the literal value of the data, none of the actual data can be interpreted as a command or part of one.</p>
    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. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      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