tags:

views:

294

answers:

4

I have been using the mysql api in PHP, and am now converting to mysqli for the increased security. The example syntax I have seen uses printf, and I would like to know if this is necessary. At the moment I use echo, like so:

echo "<h1>".$row['ARTICLE_NAME']."</h1>
<div id='leftlayer' class='leftlayer'>
<p><strong>Username: </strong>".$row['USERNAME']."
<p><strong>Article Number: </strong>".$row['ARTICLE_NO']."
<p><strong>Subtitle: </strong>".$row['SUBTITLE']."
<p><strong>Auction Start: </strong>".$row['ACCESSSTARTS']." 
</div>";

Since with mysqli you must bind variables to the result, I have done this like so:

$getRecords->bind_result($ARTICLE_NO, $ARTICLE_NAME, $SUBTITLE$, $CURRENT_BID, $START_PRICE, $BID_COUNT, $QUANT_TOTAL, $QUANT_SOLD, $ACCESSSTARTS, $ACCESSENDS, $ACCESSORIGIN_END, $USERNAME, $BEST_BIDDER_ID, $FINISHED$, $WATCH$$, $BUYITNOW_PRICE, $PIC_URL, $PRIVATE_AUCTION, $AUCTION_TYPE, $ACCESSINSERT_DATE, $ACCESSUPDATE_DATE, $CAT_DESC$, $CAT_PATH, $ARTICLE_DESC, $COUNTRYCODE, $LOCATION$, $CONDITIONS, $REVISED$, $PAYPAL_ACCEPT, $PRE_TERMINATED, $SHIPPING_TO, $FEE_INSERTION, $FEE_FINAL$, $FEE_LISTING, $PIC_XXL$, $PIC_DIASHOW, $PIC_COUNT, $ITEM_SITE_ID);

and would like to know if I could simply replace my reference to $row with the bound variable, for example:

  <p><strong>Username: </strong>".$USERNAME."

Are there any security problems with this approach, or is it fine

A: 

You should escape the output when serving XML/HTML pages. For that use htmlspecialchars or htmlentities. Anyway, you should escape output regardless of the data source and the API used to fetch that data.

Ionuț G. Stan
why? the data is not html or has special characters and I am using a bound statement which handles that for me?
Joshxtothe4
If your application takes user input, and it probably does, you should escape the output. Not escaping the output can lead to XSS attacks (http://en.wikipedia.org/wiki/Cross-site_scripting) or invalid HTML which may display data different than you'd want. Bounding does not solve this problem.
Ionuț G. Stan
If the data has been properly filtered before being stored in the database, there is no need to filter on output.
Jacco
Jacco is right, but one should not escape data before storing it in the DB. That data isn't always meant to be displayed in HTML pages. You may as well generate Excel files and at that point your data wouldn't be displayed the way you want.
Ionuț G. Stan
There are times when storing the escaped data into your DB is the best solution. It prevents you from having to escape it _every time_ you want to display the data.
Jacco
+2  A: 

I'm not sure that binding makes your application more secure when you are getting data out of the database, however it will help when you are writing into the DB as you will have no risk of SQL injection.

Whatever approach you take to reading from the DB, you still need to escape the output using htmlspecialchars() if you are not entirely certain that the data is completely clean. The bound statement will not handle this as you suggest in your comment to Ionut - you have to escape the data in a way that is applicable to where you are outputting it. PHP/MySQL doesn't know whether you are printing into an HTML document/shell command/json/etc. There isn't an magic escape method that makes any data safe for any output medium.

Tom Haigh
none of the information in the database is the result of userinput, and I call htmlentities on the one field that is. I am wondering if using something like printf("%s %s\n", $col1, $col2); is more secure than just echo $col1; ?
Joshxtothe4
That wouldn't be any more secure. If you trust the input, then don't escape it, but be aware that it most likely did get entered by a user once upon a time
Tom Haigh
actually 'most likely' probably isn't accurate, but I just wanted to make sure you didn't just assume data is safe because your users didn't enter it
Tom Haigh
A: 

I know that some buffer overflow vulnerabilities have been reported for certain PHP versions. I don't know which versions though. So based on this, and assuming the input isn't properly filtered, using printf may be less secure than using echo. Depends a lot on the context though.

Ionuț G. Stan
PHP 5.2.5 and prior : *printf() functions Integer Overflow (http://securityreason.com/achievement_securityalert/52)
Jacco
+2  A: 

I agree that mysqli is--at least in principle--better than the mysql package because you can bind parameters, which is both more secure and better for query execution. That being said, I've discovered at least two serious issues with mysqli:

  • Bug 46808 is a serious problem that has been reported in different ways for at least three years and still hasn't been fixed yet. If you want to use LONGTEXT columns you may have a problem; and
  • Sometimes I just get weird bugs where mysqli fails (with meaningless messages about errors in "canary form" or somesuch). It's at this point (combined with (1)) that I just had to give up on mysqli.

PDO is probably a better choice. Me? I just went back to mysql. It's hard to argue with the simplicity as long as you're careful with escaping strings and so on.

cletus
As for this bizar bug, it's just amazing that this (still) exists... I've been busy setting everything up, and started to rewrite everything to MySQLi since the last week, until I came across this LONGTEXT problem. Now I'm back to square one.
Alec