PHP:base64_encode是否可以防止mysql注入?

时间:2013-07-31 18:24:00

标签: php mysql blob sanitization

我正在尝试设置一个安全接受文件上传(简历)的PHP页面,将其存储为mysql blob,并在以后提供下载。但是当我稍后下载PDF以供查看时,它们似乎总是已损坏且无法正常打开。

感谢Jgoettsch(php: reversing mysql_real_escape_string's effects on binary)提出的一个问题,我意识到通过mysql_real_escape_string提供文件数据(以防止注入)可能会破坏文件内容,并且想要通过base64_encode()来传递二进制文件,并在下载前使用base64_decode()。

这是一些模拟代码,用于演示我当前正在做什么(哪些无法正常工作):

上传:

<? 
// 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);
?>

下载:

<? 
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();
}
?>

以下是我的问题:

  1. 如果你有一个文件上传字段,该字段是否容易受到sql注入?还是我不必要地担心?显然,如果我只是将二进制文件传递给blob字段而没有任何翻译,那么这个文件上传任务就会简单得多。
  2. 如果我通过base64_encode()提供上传的文件内容,这是否相当于清理?或者我应该编码它然后另外通过mysql_real_escape_string?
  3. 传递编码的字符串
  4. 这一切似乎只是为了存储和获取PDF而付出的努力。是否有一个更简单的解决方案来解决这个共同需求,我还没有发现它?
  5. 提前致谢!

2 个答案:

答案 0 :(得分:1)

由于您正在谈论消毒,我假设这是针对陌生人将上传文件的公共网站。存储用户提交的PDF文件是一个非常糟糕的想法。首先,您如何确定您收到的文件甚至是PDF?用户可以100%将CURL恶意文件存入您的数据库并让用户在不知情的情况下下载病毒。 PDF格式本身(如果我没记错的话)实际上可能会在某些Windows操作系统中执行病毒,就像WMV和WMA文件一样。

如果您绝对需要PDF,那么最好选择创建您自己的PDF文件,并使用用户提交的清理数据。您可以在线找到有关如何执行此操作的教程。我个人不建议首先使用PDF,因为你可以使用HTML&amp; CSS构建简历并完美打印出来。

答案 1 :(得分:1)

如果您有文件上传字段,该字段是否容易受到sql注入攻击?

A 是(有点。表格上的字段不是易受SQL注入攻击的;该漏洞实际上是在处理请求中提交的值的代码中。)

或者我不必要地担心?

A 否。您应该始终了解可能发生的不良事件,并以防止漏洞暴露(并被利用)的方式编写代码。

如果我通过base64_encode()提供上传的文件内容,这是否相当于清理?

A 只要你的base64_encode保证返回的值只包含[A-Za-z0-9 +。/ =],它几乎就在那里。最佳做法是使用绑定参数

Q 或者我应该对其进行编码,然后另外通过mysql_real_escape_string传递编码的字符串?

A 除了使用带有绑定参数的预准备语句之外,最佳实践规定所有值(包括base64_encoded值)都应通过mysql_real_escape_string运行,如果它们包含在SQL文本中以提交给数据库中。