我会在本文介绍我是如何与r2c的另一位开发人员成功识别日志中的数据泄漏,从而修复了该漏洞并彻底杜绝其今后的再发生,整个过程只需几个小时就可以完成了。
东丽网站建设公司创新互联公司,东丽网站设计制作,有大型网站制作公司丰富经验。已为东丽1000+提供企业网站建设服务。企业网站搭建\成都外贸网站建设公司要多少钱,请找那个售后服务好的东丽做网站的公司定做!
作为一名开发人员和工程经理,我一直痴迷于寻找一种可以不需要安全团队完全参与,即可快速解决整个涉及组织安全漏洞的方法。
为什么要这么做呢?好处有很多:
我将以上过程称为“self-service DevSec。
接下来,我将介绍我们在日常开发工作过程中遇到的一个安全漏洞。我将讨论我们如何发现此漏洞的,以及如何在短短几个小时内修复整个安全漏洞,并使用Semgrep防止该漏洞再次发生。Semgrep是一个开源工具,用于使用熟悉的语法进行轻量级静态分析。
上个月,我正在与r2c的另一位工程师Clara McCreery一起调试Flask Web应用验证流程。就像许多工程师面临着令人困惑的调试问题一样,我们的第一步就是将Web应用程序放入调试日志记录。
具体来说,我们想知道数据库操作的情况,因此我们将ORM(在本例中,我们使用SQLAlchemy)设置为INFO级别的日志记录,方法如下:
- logging.getLogger("sqlalchemy.engine.base.Engine").setLevel(logging.INFO)
这会将SQLAlchemy配置为记录所有SQL语句以及传递的参数,让我们看一下我们看到的一些输出结果:
- INFO:werkzeug:127.0.0.1 - - [25/Sep/2020 11:50:01] "POST /api/auth/authenticate HTTP/1.1" 200 -
- INFO:sqlalchemy.engine.base.Engine:BEGIN (implicit)
- INFO:sqlalchemy.engine.base.Engine:SELECT token.id AS token_id, token.token AS token_token, token.name AS token_name
- FROM token
- WHERE token.token = %(token_1)s
- LIMIT %(param_1)sINFO:sqlalchemy.engine.base.Engine:{'token_1': $2a$10$KVsyW1jjKn.pvkVi3w9Rn.1mwnZFd7F2SFveGDG8flIhbe.MoJH4G, 'param_1': 1}
我们绝对不应该记录令牌,即使已安全地对其进行哈希处理。在此示例中,处于讲解的目的,实际令牌值已更改。
首先要制定一个计划
至此,我们已经确定了一个安全漏洞,并且希望在保留检查日志能力的同时修复此漏洞。具体步骤如下:
接下来,我将指导你完成每个步骤。需要注意的是,我们能够在几个小时内完成整个流程,而无需与安全团队合作。
缓解当前的安全漏洞
这里的缓解措施非常简单,因为我们已经知道了漏洞的根本原因,为此可以快速还原日志记录的更改过程。然后,我们可以对日志进行快速审核,以确保仅泄漏了开发测试令牌。
永久解决方案
那我们如何防止SQLAlchemy记录敏感数据?
第一步是阅读文档。快速搜索“引擎日志中的sqlalchemy隐藏参数”将我们链接到SQLAlchemy Engine文档。稍后进行详细阅读,这样我们就发现了hide_parameters标志,该标志防止日志记录框架在日志或异常中发出任何参数。
虽然这肯定可以防止发现的安全漏洞,但对我们来说信息量太小了,因为我们想知道例如数据库ID等信息,以便进行调试。
真正的解决方案
然后,我们检查了相关的SQLAlchemy源代码,相关代码在sqlalchemy / engine / base.py中:
sql_util._repr_params依次运行:
通过研究trunc,我们发现它通过将参数的repr截断为最大字符数来转换参数值,这意味着我们应该重写参数对象的repr方法以防止敏感日志记录。
此时,我们像优秀的工程师一样,使用了一条懒惰的策略,因为我发现的这个GitHub漏洞,Mike Bayer已经发布了一个很好的解决方案,所以我就进行了一些复制,关键代码如下:
这段代码的作用是什么?你可以发现它用新的ObfuscatedString.Repr参数替换了我们原来的str参数。登录时或发出异常消息时,该字符串将替换为我们的********。由于参数仍然被绑定为原始字符串(通过impl = types.String),因此仍然插入和从数据库中选择正确的值。
要使用这个新的字段类型,我们设置令牌的字段类型如下:
然后,我们重新启用INFO日志记录,并检查我们是否正确混淆了文本:
- INFO:werkzeug:127.0.0.1 - - [25/Sep/2020 13:48:55] "GET /api/agent/deployments/1/policies HTTP/1.1" 200 -
- INFO:sqlalchemy.engine.base.Engine:BEGIN (implicit)
- INFO:sqlalchemy.engine.base.Engine:SELECT token.id AS token_id, token.token AS token_token, token.name AS token_name
- FROM token
- WHERE token.token = %(token_1)s
- LIMIT %(param_1)s
- INFO:sqlalchemy.engine.base.Engine:{'token_1': ********, 'param_1': 1}
为了完整起见,我们还在开发数据库控制台中验证了是否存储和检索了正确的值。
执行过程
应该说,我们已经暂时解决了安全漏洞,以便可以重新调试原始的身份验证漏洞。但要彻底修复整个漏洞。我们将如何做?
以下有一些想法,我相信我们都曾经遇到过:
如果要从这篇博客文章中得出一个中心结论的话,那就是:这些都不是理想的解决方案,原因如下:
幸运的是,Semgrep为我们提供了一个简单的解决方案:在代码中定义一个不变量,并在每次CI运行时使用Semgrep扫描对其进行强制执行。
在r2c中,我们使用GitHub操作在每个合并请求上运行Semgrep。我们使用由Semgrep .dev管理的管理策略、规则字段表和通知设置来定义Semgrep应该运行哪些检查。
为了保证我们的代码不会再出现问题,我访问了semgrep.dev/editor并编写了一个快速规则来检测潜在的不安全日志SQLAlchemy字段。
这是Semgrep的YAML定义语言中的规则定义:
这个规则有什么作用?详细解释如下:
然后快速地按下“部署到策略”按钮,就可以保证所有的web应用程序都得到了保护。
通过我们的VS Code扩展将Semgrep集成到编程工作流中的开发人员也会开始在他们的IDE中产生效果。
请注意,此解决方案是有意迭代的:我们可能会发现更多字段名称被标识为敏感字段,或者还希望包含db.Text类型。幸运的是,这是一个快速修订,并根据需要重新部署。
总结
在这篇文章中,我演示了你作为一名开发人员或管理人员如何使用轻量级静态分析(如Semgrep)来帮助在代码中强制执行不变量。
在r2c中,我们习惯性地使用Semgrep来防止自己重复犯错误:意外地使调试器处于提交状态?有一条规则可以防止这种情况发生。当我们发现导入某个库会减慢程序的初始化速度时,我们编写了一条规则来确保它被延迟加载。
本文翻译自:https://r2c.dev/blog/2020/fixing-leaky-logs-how-to-find-a-bug-and-ensure-it-never-returns/
当前题目:成功识别日志中的数据泄漏漏洞并对其进行缓解
本文URL:http://www.mswzjz.com/qtweb/news30/204630.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联