0

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

我需要一段时间才能完全过渡到 PDO,但与此同时,我想尽我所能使应用程序尽可能安全。目前所有输入都通过,mysql_real_escape_string()并且我确保应用程序和数据库都以UTF8.

在我完全切换到 PDO 之前,我还能做些什么或应该做些什么(最佳实践)来确保应用程序的安全?

感谢您的所有帮助:)

4

2 回答 2

1

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

仔细检查并确保每个输入都经过验证并且完全符合您的期望。努力学习filter_var()不同FILTER_的 s。它本身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 hacks。这是一场永无止境的冒险。

熟悉您的(新)代码,开始并继续进行研究,在任何地方实施严格的验证,不信任来自用户空间的任何东西,并尊重增强安全性永无止境。

如果可以,请付费让供应商定期对您的站点进行安全扫描。每月。我认为 Nessus 每年收费 1200 美元。这不是万无一失的,但比任何一个像样的渗透测试人员都可以在 20 分钟内发现的糟糕的低级问题被 pWnd 更好。

对?


此外,不要将注意力集中在这段代码的想象问题上,而忽略其他关键问题。如果您继承的这段代码运行的是 PHP 4.1,那么有一个古老的 phpMyAdmin 向世界开放(psst,密码较弱),而服务器管理被忽略或实践不当,您就会遇到问题。

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

保护(通过关闭和监控)端口,维护软件包的升级,使用 SUHOSIN(尽管它不再更新?),可能会查看反向代理(Varnish)和/或其他工具(如 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/
于 2013-03-08T05:46:58.793 回答
1

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

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

它们都不是真的。
mysqli 和 PDO 都不是仅仅因为它们的存在就意味着“安全应用程序”。
这只是另一种迷信,在 PHP 人员中传播。

  • 人们必须明白,如果他们只关心数据源(即“用户输入”),他们就处于危险之中。
  • 必须明白,仅仅“切换到 PDO”本身并没有任何好处
  • 必须了解 mysql_real_escape_string() 只能保护字符串,而不能保护其他
  • 必须了解 PDO 准备好的语句可以保护字符串和 - 哦,重要的是 - 数字!让所有其他查询部分像以往一样容易受到攻击
  • 必须了解正确编写的自定义类可以比原始 mysqli 或 PDO 更安全(和有用)。无论如何,自定义类是必须的。

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

  1. 每个动态进入查询的查询部分都应该通过格式正确的placeholder。没有例外
  2. 不能通过占位符放置的所有内容都应列入白名单,即根据脚本中硬编码的变体列表进行验证。
于 2013-03-08T06:46:02.690 回答