在本系列的 第 1 部分 中,我们介绍了一些可能影响 PHP 应用程序的基本安全漏洞。在第 2 部分中,让我们更深入地探讨一些可能影响您的环境的最高级安全漏洞。说实话,可能有无数种方法可以破坏软件产品并破坏其安全性。普渡大学计算机安全专家 Gene Spafford 说:“唯一真正安全的系统是断电、浇铸在一块混凝土中并密封在铅衬房间内并配备武装警卫的系统。” Spafford 有一个观点:任何向公众公开的系统都可能存在缺陷,发现缺陷并迅速(希望)修补只是时间问题。
“唯一真正安全的系统是断电、浇注在一块混凝土中并密封在有武装警卫的铅衬房间内的系统。” – 基因斯帕福德
毫无疑问,安全是一个移动的目标
定期发现新的安全漏洞,并且会立即为您在应用程序堆栈中使用的大多数主要软件应用程序发布例行补丁。无论是您的 Web 或数据库服务器、您的操作系统、您的 PHP 运行时,甚至是您那个时代采用的 MVC 框架,您的暴露点都可能存在于构成您的应用程序生态系统的各种组件中的任何地方。
虽然专业社区已经发展并且最佳实践正在成为标准实践, 但仍然有理由担心 ,您永远不应该掉以轻心。
安全最佳实践
术语“最佳实践”表示大多数开发人员和系统管理员都遵守的普遍接受的知识的广泛灰色区域。出于本文的目的,我将其用作您应该了解的通用技术的总称。当然,这些主题中的每一个都可以扩展为关于每个主题的广泛对话,但我将从高层次的角度来介绍它们。
始终打开 SSL
通过常规端口 80 访问您的应用程序时,您是通过不安全的连接向用户提供内容。如果您不收集私人用户数据并且只提供对公众友好的内容,这可能不是问题。对于一个五页的信息网站,80 端口可能不是问题。但是,如果您允许您的用户登录和存储极其敏感的财务和个人信息,该怎么办?不仅您的登录页面本身应该通过端口 443 上的 SSL 受到保护,而且您应该在与您的 Web 应用程序(私人和公共信息)的每个连接上强制执行 SSL。 SSL 似乎已成为大多数常见 Web 应用程序的事实标准,包括 Facebook 和 Google 。
如果您不确定如何访问端口号, 请查看全局 $_SERVER 函数 。如果用户试图通过 HTTP 访问您的站点,您可以在应用程序的开头创建检查以重定向到 HTTPS。
隐藏所有版本号
黑客要破坏您的系统,部分工作包括了解您的系统由什么组成。当黑客不知道您正在运行的应用程序的版本时,知道您正在运行的特定版本的应用程序的安全漏洞有什么好处?不幸的是,对于我们其他人来说,这些信息是可以公开访问的,而且黑客非常容易获得。
对您的 HTML 进行基本搜索可以揭示您从未想过会暴露的有关您的基础架构和应用程序堆栈的信息。从 Javascript 库到您使用的第三方监控工具类型,您泄露的信息远比您想象的要多。即使是您在 HTTP 标头中传递的信息也可以帮助他人了解 Web 服务器、操作系统、MVC 框架、托管服务提供商、分析工具以及制定攻击您的产品的计划所需的其他重要信息。您可以通过导航到 builtwith.com 并查询您最喜欢的网站以查看它们正在运行的技术堆栈来亲眼看看。查看您的特定应用程序堆栈以确定如何关闭发送回客户端的签名,以便您可以隐藏此敏感数据。
将您的错误记录在日志中并远离公众
一个常见的错误是让错误公开可见。一个熟练的 PHP 应用工匠明白应用程序的错误是不被公众看到的。公众需要看到什么?公众 只 需要看到 一个有趣 且 友好的 错误 即可 !这就是您的访客需要看到的全部内容。所有其他错误应立即进入您的日志和/或您的 APM 监控工具 !您公开的信息越多,您提供给黑客利用的信息就越多。您的错误消息可能包括有关您正在使用的扩展的信息、PHP 运行时、服务器信息、目录和路径,以及对您的应用程序进行攻击所需的其他重要信息。查看 display_errors 、 log_errors 和 error_log 声明。
禁用潜在有害的 PHP 函数
一种合适的做法是禁用可能被劫持和用于危害的 PHP 函数。我敢打赌您不知道 PHP 提供的这个关键特性。作为额外的安全层,如果您的应用程序遭到破坏,请完全关闭某些可能执行有害代码的功能。 disable_functions 声明包含您希望 PHP 不可用的函数列表。
更多注入攻击
在本文的 第 1 部分 中,我们介绍了 SQL 注入和 XSS 攻击。我们将介绍一些您容易受到的潜在有害注入攻击。
外壳注入
您是否听说过 shell_exec() 函数? exec() 、 passthru() 和 system() 怎么样?如果受到损害,这些功能中的每一个都有可能对您的系统造成一些难以置信的重大损害。以 shell_exec() 为例——您可以将一个字符串传递给该函数,它将执行该字符串中包含的任何 shell 命令。
我的第一个建议是,如果您不在应用程序的任何地方使用它们,则完全禁用这些功能。如果您正在使用这些函数,您绝对必须在将数据传递给您的函数执行之前对数据进行清理。
评估()
eval() 是一个函数,值得单独讨论一节。 eval() 将执行作为参数传递给它的 PHP 代码。一般来说,很少有场景需要使用此功能。 eval() 的使用被认为是不好的做法,如果您发现自己——或您的应用程序——使用这个函数,那么我强烈建议您重新审视它的必要性。与其他可能有害的功能一样,我的建议是永远不要使用并完全禁用此功能。
文件包含
include() 和 require() 是标准函数,其中 PHP 脚本将在其执行流点中包含另一个文件。虽然这些功能起着至关重要的作用,但如果受到损害,它们也可能有害。通过简单地传递一个目录路径,无论是相对路径还是绝对路径,入侵者都可以访问 PHP 可用的任何文件,如果成功,则将其包含在执行流中。这两个功能的使用如此普遍,以至于禁用它们是不可能的选择。因此,确保正确使用和安全数据清理(如果传递变量)是使用 require() 和 include() 时的最佳实践。
存储安全数据
关于安全存储数据的实践可能会写一整本书。不幸的是,这个主题超出了这篇特定博客文章的范围。但是,如果我能强调至少了解存储关键数据的敏感性的重要性,那么我可能已经部分实现了我的目标。为了您的客户和法规遵从性,应该对以下数据的存储进行安全审计:
- 社会安全号码。
- 信用卡号码。
- 出生日期
- 驾照号码
- 健康和医疗记录
- 银行账户信息
- 税务记录
- 信用报告
毫无疑问,该列表并不止于此,因为这些只是您必须视为高度敏感的信息类型的示例。最佳做法各不相同,不确保各种法律和监管机构要求的适当程序和做法的法律影响也各不相同。
将私有应用程序置于 VPN 之后
如果您有仅供内部员工使用的管理应用程序,则无需向外界公开该应用程序。您可以设计一个私人 VPN,这样即使您的员工在远程,他们也需要先连接到您的私人网络,然后才能选择访问不同的私人应用程序。
无论如何,拥有私有 VPN 将为您的公司资产引入额外的安全层,并且还可以安全访问您的私有内部应用程序。即使您为最私密的应用程序设置了 .htaccess 密码——别搞错了——您向外界提供的软件越多,您的软件也可能被黑客入侵并遭到破坏。
安全在很大程度上是一门艺术,因为它是一门科学。您在最佳实践和安全预防措施方面的投资越多,您的客户和公司就会越安全。随着 PHP 应用程序规模的扩大以满足业务扩展的需求,您和您的组织将暴露在更多的漏洞中。了解各种关键弱点将有助于提供必要的框架,以制定可靠的安全计划。