Building Secure Web Applications in PHP - Paragon Initiative Enterprises Blog
无论您是计划开发全新的应用程序还是试图防止遗留代码造成代价高昂的数据泄露,如果您要编写 PHP,您应该从哪里开始?这是我们将试图详细回答的问题。
简单的解决方案:聘请安全顾问
大多数人没有空闲时间自学成为安全专家,特别是如果他们在下周二发布之前要运行业务或编写和测试一万行代码。有很多信息需要吸收,当你觉得你已经赶上时,球门柱已经移动了。
如果这听起来像您,您可能需要聘请安全顾问(或顾问团队)来管理软件的复杂性并降低业务风险。一位优秀的安全顾问不仅可以识别最危险的漏洞并为它们推荐(甚至实施)解决方案,而且他们会在您的时间和预算限制的情况下这样做。
如果我不知道该向谁求助怎么办?
Paragon Initiative Enterprises 提供应用程序安全、代码审计和Web 开发服务。给我们发一封电子邮件,告诉我们你今天在哪里,明天你想去哪里,我们将分享我们对如何到达那里的见解。
如何开发更安全的 PHP 应用程序
无论使用何种语言,无意创建不安全的 Web 应用程序都有两个主要原因:
- 缺乏安全知识
- 不良的开发习惯
不了解以某种方式编写小部件所涉及的风险的开发人员不太可能做出安全的选择。由于MITRE和OWASP的工作,最常见的漏洞(及其后果)广为人知且易于访问。然而,当团队在紧迫的期限内面临压力时,仍然可能会出现不良习惯和不安全的开发实践。
解决缺乏安全知识的方法当然是获得更多关于安全的知识。教育是唯一有效的长期安全战略。任何没有对初级开发人员进行有关 Web 应用程序安全性和常见漏洞的教育的公司都会对他们造成极大的伤害。(我们在 Github 上的应用程序安全阅读列表是一个很好的起点。)
但是不良的开发习惯怎么办?没有一个立即明显且有效的解决方案,例如如何通过获取知识来解决缺乏知识的问题。我们认为,解决不良开发习惯的唯一有效方法是设计开发人员使用的工具、库和框架,使其默认安全。如果做安全的事情比做有风险的事情更容易,那么当面临压力和严格的最后期限时,开发人员将不太可能选择增加风险。
了解和预防漏洞
如果您是应用程序安全的新手并且还没有阅读A Gentle Introduction to Application Security,我们建议您阅读。在编写可防止大多数安全漏洞的软件时,要牢记四个规则。
- 防止数据破坏对其进行操作的指令。
- 明确和全面地使用您的应用程序逻辑。
- 让您的软件保持最新状态,不要依赖废弃的组件。
- 不要编写自己的密码学。
考虑到这四点,下一步是在我们的应用程序中映射数据的可能交互。对于一个典型的业务线 CRUD 应用程序,我们可能有一个看起来像这样的图表(注意:这不消耗任何外部 API,否则图表会很快变得更加复杂):
请记住,这是一个非常简化的 Web 应用程序视图。我们不包括操作系统、网络设备或通信协议。澄清:
- 您的代码是您直接负责的代码。模型、控制器、视图、cron 作业等。
- 外部代码是您不直接负责的任何内容。这可能包括库(例如defuse/php-encryption)或实用程序(例如https://github.com/composer/composer)。
试图闯入您系统的人主要对这些途径感兴趣(以绿色突出显示):
具体来说:
- 任何可能导致数据库查询损坏的路径组合(即 SQL 注入)
- 任何诱骗您的应用程序滥用外部代码的方法(例如滥用幼稚的文件系统操作)
- 导致客户端代码执行的任何途径(例如跨站点脚本和跨站点请求伪造)
因此,这些也是您应该重点关注应用程序强化工作的地方,但需要注意几点。您通常只能控制您的代码,而深入了解并修复外部代码中的漏洞通常不是您的工作。这是一把双刃剑。
好处:如果外部代码导致泄露,例如由于零日漏洞,您无需对此直接负责。
缺点:无论如何,您可能无法协商审查它是否存在漏洞。
那么你能做些什么来保证你的应用程序安全呢?
至少,让您的所有软件保持最新状态(这涉及到我们要始终牢记的 4 件事列表中的第 3 点),并希望您永远不会受到零日漏洞的攻击。由于零日漏洞极少使用,这实际上是防止大多数攻击的有效方法,因为您不太可能成为攻击目标。
“让一切保持最新”也适用于:
- 您的操作系统
- 您的网络服务器软件
- 您的数据库软件
- PHP 本身
- 您正在使用的框架
- 任何和所有外部库
太好了,现在让我们关注一个典型的 PHP 开发人员实际控制的内容:
PHP 开发人员的焦点
无需将您的 PHP 程序员帽子换成系统管理或网络工程师角色,您的应用程序安全工作将主要集中在:
- 您的代码和数据库之间的通信。我们之前介绍过如何防止 PHP 中的 SQL 注入:尽可能使用准备好的语句,在不能使用的情况下使用非常严格的白名单。
- 您的代码和框架之间的通信,通常是 Web 浏览器的网关。您在此交互中的目标是防止跨站点脚本攻击:以上下文合理的方式正确地转义您为用户提供的任何信息。如果您使用模板引擎(例如 Twig),它应该提供一种快速便捷的方法来执行此操作。
- 您的代码与任何外部代码之间的通信。如何保护这种交互的细节完全取决于外部代码是什么、它的作用以及它的使用方式。您最有可能在这里遇到混淆的代理问题,其中输入验证和显式应用程序逻辑是您最有效的缓解策略。
最后,只有使用 HTTPS,您的服务器和最终用户之间的所有通信才能安全。我们之前在关于安全 PHP 会话的帖子和关于安全 PHP 加密的白皮书中对此进行了介绍。
图表中的其他箭头呢?
好问题。以下是其他一些很好的问题:
- 您如何保护框架与数据库交互的方式?还是外部代码?还是最终用户的网络浏览器?
- 您如何确保外部代码不会让您的应用程序完全开放?
- 如果您的 Web 服务器软件可以远程利用怎么办?
- 如果您的 Web 服务器的 PHP SAPI 不安全怎么办?
- 如果 PHP 解释器或您的应用程序使用的核心扩展之一包含漏洞怎么办?
- 你的服务器的操作系统呢?
名单还在继续。归根结底,您可以采取两条路径:
- 在有限的时间内确保您所能做的一切,让其他一切保持最新。
- 成为一名安全专家,并为其他人提供至少一个他们没有时间回答的问题的答案。
虽然我们确实预计大多数人会更喜欢第一个选项,但第二个也是一个很好的选择。
如果我尽了最大的努力,我的网站还是遭到入侵,会发生什么?
您可以主动采取一些措施来限制被“黑客攻击”造成的损害。这大部分是信息安全专家的常识。
除非您碰巧拥有大量的计算机取证和事件响应经验,否则您通常很难识别攻击者是如何入侵的。如果您询问公众,他们可能会指出一些常见问题,例如弱管理员帐户密码或易受攻击的 WordPress 插件,而不是提供任何相关见解。
要做的最重要的事情是尽快通知您的客户有关违规行为,并提供尽可能多的详细信息,并尽可能接近零无根据的猜测。
通常,如果发生安全漏洞,最难做的事情就是学会前进。对于公司及其客户。如果您认真对待安全(虽然每家公司都会在他们的违规通知新闻稿中表示这样做,我们的意思是如果您真的认真对待安全),您可能永远不必忍受数据泄露。确保您不会自满,否则您可能会忽略一些攻击者不会忽略的内容。
对于另一个更笼统的观点,Defuse Security 关于 Web 应用程序安全性的文章是必读的。