在Laravel应用中10大审计安全问题
从2022年开始, 我花时间对Laravel应用程序进行安全审计和渗透测试. 我审计过各种规模的应用程序, 从只有几个控制器的小应用程序, 到有许多模块的巨大应用程序, 以及许多不同的编码风格和应用程序结构.
在所有这些中, 有一个非常明显的趋势, 在我审核的应用程序中都是如此:
Laravel是相当安全的, 但它很容易忽略一些小事情, 额外的防御层, 并留下一个隐藏的弱点.
事实上, 可以这么说, 我在审计过程中发现的绝大多数问题都是一些简单的东西, 在单一的路线中被忽略了, 或者是一些额外的安全层, 开发者没有意识到, 或者不愿意实施.
因此,让我们深入了解一下,看看我在做安全审计时发现的十大最常见的安全问题。
10.输入验证不足
散布在控制器中的输入验证不足是很常见的。
通常会有一个验证器检查预期的输入键(尽管有时甚至没有),然后request()->all()会在紧接着使用,将数据提交到模型、事件等。
没有适当的验证,很容易注入恶意值,导致错误、注入攻击等。
例如,通常的大量分配防御被认为是模型上的$fillable,但如果$fillable包括管理门户的管理标志,
那么任何人都可以从注册页面创建一个新的管理用户......(没错,这是一个真实的例子。)
9.缺少子资源完整性(SRI)
子资源完整性(SRI)增加了一个保护层,防止第三方脚本被破坏而影响你的网站,在我看来,它被严重低估了。
其风险在于,第三方脚本和样式可以被修改为包含恶意代码,如Magecart、键盘记录器、加密器等。
如果你的网站上有被破坏的脚本,那么你的用户就会面临风险,即使你的应用程序没有被破坏。
SRI的工作原理是在每个加载第三方资源的<script>和<style>标签上定义一个完整性哈希值,浏览器在加载该资源之前会对其进行验证。
如果哈希值不匹配,该资源就会被阻止。
我审计的大多数网站都没有加载第三方的资源,因此无论如何都不需要SRI,否则我估计这个问题会在名单上排得很靠前!
8.速率限制不充分
速率限制对于限制僵尸攻击和防止滥用是至关重要的,然而,我们经常会发现一些缺乏速率限制的终端。
当涉及到像认证或查询敏感信息(如用户账户的存在)的路线时,这一点尤其值得关注。
例如,我发现一个基于SMS的多因素认证(MFA)路线缺乏速率限制--6位数的代码在5分钟内就会过期。
篡改一个有效的代码并强行进入是很容易的。
这就是说,速率限制可能很难搞清楚--你是基于IP,还是基于用户名,还是基于两者?还是别的什么?
这取决于路线,但有一些肯定比没有好。所以不要忽视它!
7.跨站脚本(XSS)
前十名中最不令人惊讶的条目之一,但它可能比你所期望的要低得多!
XSS通常是在通过单一输入的单一路线上出现的,由于像Markdown(默认情况下是不安全的)或有限的格式化,遭受了微妙的转义绕过。
这里最好的策略是注意那些讨厌的未转义的刀片标签({!!...!})和像v-html这样的原始HTML指令,
并确保所有的使用都被正确转义,Markdown的安全功能被启用,用户提供的HTML被净化。
我建议尽量避免使用这些标签,这样任何使用都会显得非常突出,并且可以很容易被识别和审查。
6.过时和脆弱的依赖关系
另一个不足为奇的条目......你上次运行 composer/npm 更新是什么时候?
延迟依赖关系的更新是很常见的,以避免破坏事物并保持系统稳定,但依赖关系中的漏洞可能会使你的应用程序暴露,而你却什么都没做。
包含大量的依赖关系也很常见,但每个依赖关系都会增加你需要注意的潜在漏洞。
我建议每周或每月保持更新,并在构建系统中使用 composer audit --locked 和 npm audit 等工具,
在发现漏洞时阻止部署。我还建议将你的依赖性缩减到最小,任何可以被简单的内部中间件或包装器轻松取代的东西都应该被取代。
5.不安全的函数使用
自从我开始从事PHP工作以来,我已经数不清有多少次看到md5(time())(和md5(microtime())!)的使用--我在早年可能还写过一些这样的函数!
而且令人失望的是,这种趋势一直持续到今天。更糟糕的是,它经常被用来生成随机标记或唯一的文件名。
除了它既不是随机的,也不是唯一的。它非常容易被猜测和破解,而且碰撞攻击也是非常微不足道的。
我敢打赌,如果你现在进入你的代码库并搜索md5(,你会发现它在某个地方被不安全地使用......说真的,我在这个问题上有创伤!
不仅仅是md5(time()),还有其他函数,如rand()和array_rand(),它们在密码学上是不安全的,不应该被信任用于任何需要安全的地方。
始终使用适当的安全随机数生成器、random_int()和Str::random(),来安全地生成随机值。
4.缺少安全头文件
现在我们进入了没有被很好理解的额外保护层。
网络浏览器包括一堆非常棒的安全功能,你只需要在你的网站上通过使用响应头来启用它们。
虽然它们的缺失并不直接导致你的网站被黑客攻击,但它们有助于防止诸如点击劫持、推荐人信息泄露、XSS和其他注入攻击、HTTPS降级攻击等情况。
启用许多这样的安全标题是微不足道的,但大多数网站甚至不启用那些简单的安全标题......
我可以给你的最好建议是到securityheaders.com去扫描你的网站。
它将列出你所缺少的所有头文件,并给你提供资源链接,以了解更多关于添加这些头文件的信息。
3.缺少内容安全策略(CSP)。
内容安全策略是如此的重要,我在前十名中给了它们自己的位置。
CSP是防止XSS和点击劫持的第二道防线,它使你能看到哪些脚本、样式、字体、表单、框架等在你的应用程序上运行。
CSP告诉浏览器哪些资源允许在网站上使用,它将阻止和/或报告任何违反政策的行为--防止XSS攻击,并为您提供网站上发生的事情的可见性。
它们常常被认为太难或 "破坏东西",然而,部署 "仅报告 "策略为你提供了充分的可见性而不破坏任何东西。
因此,当你开始工作时,这绝对是一个好办法!设置一个最简单的方法是使用Report URI中的CSP向导。
我已经发布了我的CSP中间件,作为一个开始使用CSP的简单方法:
https://gist.github.com/valorin/d4cb9daa190fdee90603efaa8cbc5886
2.缺少授权
哦,孩子,这个包含了一堆围绕授权的东西(在某种程度上也包括认证)。
我已经看到了:
不安全的直接对象引用(IDOR),缺少签名、授权和政策中间件,被遗忘的authorize()调用,没有验证的webhooks,等等......
最终,代码实际上并没有检查请求者是否被允许做它想做的事。
事实上,我很惊讶看到这个问题在名单上占了这么高的位置,但事实证明,对于大多数项目来说,有一个这样的问题隐藏在某个地方,等待被利用是很常见的。
这通常是一个简单的案例,即开发者忘记添加一行,但它可能会留下一个巨大的漏洞。
我最好的建议是在每条路由上包括认证和授权测试,与其他测试一起。
这样,你就可以作为标准测试流程的一部分来检查有效和无效的权限,而且你会注意到授权是否丢失,因为测试会通过,而它应该是失败的。
1.暴露的API密钥和密码
这句话我要讲多少次?不要把秘密提交给Git!
这是名单中不出意料的冠军:
API密钥和密码被提交到版本控制中,并散落在代码库中。这种情况非常普遍,当我在审计过程中没有遇到这种情况时,我真的很惊讶。
考虑一下你的代码在哪里......它在你所有的开发者机器上,与承包商共享,在GitHub、Bitbucket、GitLab等,在第三方服务和构建工具中。
它散布在许多不同的地方。当你的API密钥解锁账单、文件存储、个人身份识别信息、备份、基础设施等。
这么多的敏感信息和访问权限,如果落入坏人之手,你的声誉就没有了。
我知道外面有一些教程推荐犯这些事情,所以我知道为什么会发生。
但作为一个社区,我们需要努力阻止这种情况的发生。
如果你真的不小心提交了证书,请确保你在源头上撤销它。
这将防止任何人在发现它时使用它。我还建议使用Gitleaks和TruffleHog这样的工具来寻找你代码库中的秘密。
BONUS.缺少security.txt文件!
这不是一个安全问题,所以我把它作为一个奖励包括在内,但在你的应用程序中添加一个security.txt文件是你能为你的安全所做的最简单和最好的事情之一。
security.txt是一个你放在/.known/security.txt的文本文件,它提供了你的(安全)联系细节,以防有人发现你网站的安全问题。
这使得安全人员与你联系变得超级容易,减少了报告问题所需的时间和精力,这样你就可以更快地修复它们。
转:
https://laravel-news.com/top-10-laravel-audit-security-issues
相关文章