Topher Hunt
Topher Hunt

Reputation: 4804

PHP: Does base64_encode protect from mysql injections?

I'm trying to set up a PHP page that will safely accept a file upload (a resume), store it as a mysql blob, and provide a download later. But when I download the PDFs later for viewing, they always seem corrupted and won't open properly.

Thanks to a question by Jgoettsch (php: reversing mysql_real_escape_string's effects on binary), I realized that feeding the file data through mysql_real_escape_string (to prevent injection) might corrupt the file contents, and got the idea to pass the binary through base64_encode() instead, and use base64_decode() before download.

Here's some mockup code demonstrating what I'm doing currently (which is not working):

The upload:

<? 
// Get file contents
$cv_pointer = fopen($_FILES['cv']['tmp_name'], 'r');
$cv_content = fread($cv_pointer, filesize($_FILES['cv']['tmp_name']));
fclose($cv_pointer);

// Insert SQL
$sql = sprintf("INSERT INTO documents (name, file, size, date_uploaded)
  VALUES ('%s', '%s', '%s', NOW())",
    mysql_real_escape_string($_FILES['cv']['name']),
    mysql_real_escape_string($cv_content),
    mysql_real_escape_string($_FILES['cv']['size']));
$result = mysql_query($sql);
?>

And the download:

<? 
if (isset($_GET['view_cv'])) {
  $cv = mysql_fetch_assoc($rsApplicationCv);

  header("Content-length: ".$cv['size']); 
  header("Content-type: application/pdf"); 
  header("Content-disposition: attachment; filename=".$cv['name']);
  echo $cv['file'];
  exit();
}
?>

Here are my questions:

  1. If you have a file upload field, is that field vulnerable to sql injection? Or am I worrying unnecessarily? Obviously this file upload task would be much simpler if I could just pass the binary to the blob field without any translations.
  2. If I feed the uploaded file contents through base64_encode(), is that tantamount to sanitization? or should I encode it then additionally pass the encoded string through mysql_real_escape_string?
  3. This all seems like a lot of effort just to store and fetch a PDF. Is there a simpler solution to this common need, that I haven't stumbled on yet?

Thanks in advance!

Upvotes: 0

Views: 1046

Answers (2)

spencer7593
spencer7593

Reputation: 108390

Q If you have a file upload field, is that field vulnerable to sql injection?

A yes (sort of. It's not the fields on a form that are vulnerable to SQL Injection; the vulnerability is really in the code that handles the values submitted in the request.)

Q Or am I worrying unnecessarily?

A No. You should ALWAYS be aware of the potential for bad things to happen, and write your code in a way that prevents vulnerabilities from being exposed (and exploited.)

Q If I feed the uploaded file contents through base64_encode(), is that tantamount to sanitization?

A It's nearly there, as long as your base64_encode guarantees that the returned value will contain only [A-Za-z0-9+./=]. Best practice would be to use bind parameters

Q or should I encode it then additionally pass the encoded string through mysql_real_escape_string?

A barring the use of prepared statements with bind parameters, then best practice dictates that ALL values (including base64_encoded values) be run through mysql_real_escape_string if they are being included in SQL text to be submitted to the database.

Upvotes: 1

Andrew
Andrew

Reputation: 536

Since you're talking about sanitizing, I'm assuming this is for a public website where strangers will be uploading files. Storing user submitted PDF files is a very bad idea. Firstly, how can you be certain the file you're receiving is even a PDF? It's 100% possible for users to CURL a malicious file into your database and have users uknowingly download a virus. PDFs themselves (if I recall correctly) can actually glitch their way into executing viruses in certain Windows operating systems, just like WMV and WMA files can.

If you absolutely need a PDF, then the best option is to instead create your own PDF file with sanitized data submitted by a user. You can probably find a tutorial online on how to do this. I personally wouldn't recommend using PDFs in the first place since you can use HTML & CSS to build a resume and print it out perfectly.

Upvotes: 1

Related Questions