数据库访问最佳实践指南

时间:2013-03-08 04:53:22

标签: php javascript mysql security sql-injection

我最近在我的工作场所继承了对Web应用程序(主要是PHP,但也是一大堆JavaScript)的控制。我的首要任务之一是确保应用程序是安全的。不幸的是,应用程序中的数据库访问目前通过自定义类完成,而不是MYSQLi或PDO。

在我完全转换到PDO之前需要一段时间,但与此同时,我想尽我所能使应用程序尽可能安全。 目前所有输入都通过mysql_real_escape_string()传递,我确保应用程序和数据库都以UTF8编码。

在我可以完全切换到PDO之前,还有什么我可以做或我应该做的(最佳实践)使应用程序安全吗?

感谢您的所有帮助:)

2 个答案:

答案 0 :(得分:1)

您可以做的一件事就是将其发送到内部网(如果有的话)。您可能会惊讶于您的网站的服务器被另一端的异国情调的南美大学的神秘手指扫描的频率。也许

通过并确保每个输入都经过验证并确切地符合您的预期。使用不同的filter_var()FILTER_上努力学习。 mysql_*本身不是邪恶的,它只是陈旧的,*_real_escape_string() 关于安全性,它是关于查询完整性的。

我知道这样做:

switch ($_GET['color']) {
    case 'green':
        $color = 'green';
    break;
    case 'blue':
        $color = 'blue';
    break;
    case 'yellow':
        $color = 'yellow';
    break;
    default:
        $color = NULL;
}

这是做作的,但你得到了漂移。在没有任何疑问的情况下提供您收到的数据,并在可能的时间和地点使用您的数据。保持简单,但不简单,不要认为像PDO这样的“交钥匙”方法你的查询真的可以保护你网站的资产(或你的工作)。

如果我必须验证字段名称,你打赌我正在做类似的事情:

$field = preg_replace('/[^a-z_]/', $_POST['field']);

疯狂的疯狂正则表达式...我试着保持简单而且非常直接。否则他们会让我发痒。

PDO和MYSQLI是现代和良好的工具,但它们不是安全问题的替代品,也不是灵丹妙药。核心安全原则和对细节的细致关注是您完成工作的方式。例如,如果你无法弄清楚为什么某些东西被认为是“坏主意”,那就研究它直到你得到它为止。在错误的手中,eval()能够做坏事,就像刀子一样。但它很容易“获得”。尝试会话固定或XRSF / CSRF黑客攻击。这是一场无休止的奥德赛。

熟悉您的(新)代码,开始并继续进行研究,在所有地方实施严格的验证,不信任用户空间,并尊重增强安全性永远不会结束。

如果可以,向供应商付费以安全扫描您的网站。每月。我认为Nessus每年收费1200美元。它不是万无一失,但比一些糟糕的低悬挂问题更好,任何体面的渗透测试仪都可以在二十分钟内发现。

右?


此外,不要轻微关注此代码的想象问题,而忽略其他关键问题。如果您继承的这段代码正在运行PHP 4.1,那么有一个古老的phpMyAdmin向全世界开放( psst,弱密码),并且服务器管理被忽略或无法实施,您遇到了问题。

如果你有这样的服务器,谁需要SQL注入问题。如果你不知道ssh和隧道,你应该。

安全(通过关闭和监控)端口,维护软件包的升级,使用SUHOSIN(虽然它不再被更新?),可能会查看反向代理(清漆)和/或其他工具像Fail2ban一样管理对基础设施的威胁。不要依赖安全模式或魔术引号等“技术”,除非代码依赖于它。


如果你正和老维护者谈谈,请问他担心什么。我刚刚翻过一个我维持了八年的网站。我们进行了looong谈话......


  1. http://www.hardened-php.net/suhosin/(是否仍然保留?)
  2. http://sectools.org/
  3. http://h-online.com/security
  4. http://security.stackexchange.com
  5. http://www.schneier.com/

答案 1 :(得分:1)

你的问题中有两个假设,实际上只是严重的妄想 你假设

  • “所有输入都通过mysql_real_escape_string()传递”意味着安全性
  • “完全切换到PDO”意味着安全性

它们都不是真的 mysqli不是PDO也不是因为他们的存在而意味着“安全应用” 这只是另一种迷信,在PHP人群中传播。

  • 必须明白,如果他们的关注只是数据来源(即“用户输入”),他们就有危险。
  • 必须明白,只需“切换到PDO”就不会有任何好处
  • 必须明白mysql_real_escape_string()只能保护字符串,而不是其他
  • 必须要明白,PDO准备好的语句可以保护字符串 - 哦,一个大问题 - 数字! 让所有其他查询部分一如既往地易受攻击
  • 必须要明白,正确编写的自定义类比原始mysqli或PDO更安全(和有用)。无论如何,定制课程是必须的。

只有知识可以使您的代码安全,但不是您正在使用的某些API 因此,在开始重写代码之前,这里有两条安全SQL规则:

  1. 动态查询的每个一个查询部分都应经过格式正确的占位符。没有异常
  2. 不能通过占位符放置的所有内容都应列入白名单,即根据脚本中硬编码的变体列表进行验证。