Codeql如何分析cookie未启用httponly的问题

今天我们利用codeql分析下“cookie启用httponly“这类的安全问题,由此加深自己对codeql的使用。如果反应好的话,可以考虑把Vulnerability-goapp的其他漏洞也弄一弄。

分析go程序时必须额外下载codeql-go

说明

审计对象

Vulnerability-goapp:Vulnerable golang Web application for education。

修改

因为该项目中的所有cookie均未设置http-only,没有对比性,所以我们先要对其修改。在一些cookie设置中添加上http-only,修改记录如下。

pkgadminadmin.go修改如下。
Codeql如何分析cookie未启用httponly的问题

pkgloginlogin.go修改如下。
Codeql如何分析cookie未启用httponly的问题

pkgregisterregister.go修改如下。
Codeql如何分析cookie未启用httponly的问题

修改后记得重新生成一次database(如果需要覆盖旧的DATabase的话,则需要先删除旧的再生成新的。

目的

就是通过codeql脚本来发现其中未设置httponly和设置了httponly的但httponly的值为false(一般不会这样,但保不齐有)的这样存在漏洞的点。

确定Source和Sink

Sink定义

Sink很简单,设置Cookie时,需要用到http.SetCookie方法,而需要设置的Cookie值是这个函数的第二个参数,然后我们可以写出找到类似这样Sink的查询语句。

import gofrom DataFlow::Node sinkwhere exists(DataFlow::CallNode c |      c.getTarget().hasQualifiedName("net/http", "SetCookie") and c.getArgument(1) = sink    )select sink

运行后可获得以下结果,点击任意条目都会跳转到复合要求的代码段下。
Codeql如何分析cookie未启用httponly的问题

我们将其转换成一个Sink类,如下。

private class Sink extends DataFlow::Node {  Sink() {    exists(DataFlow::CallNode c |      c.getTarget().hasQualifiedName("net/http", "SetCookie") and c.getArgument(1) = this    )  }}

这样之后我们通过将一个变量定义成Sink的话,就是指符合条件的所有代码片段,例如:

import goprivate class Sink extends DataFlow::Node {  Sink() {    exists(DataFlow::CallNode c |      c.getTarget().hasQualifiedName("net/http", "SetCookie") and c.getArgument(1) = this    )  }}from Sink sselect s

运行后会获得同样的结果。

Source定义

然后我们再来确定Source,从http.SetCookie方法接收的参数来看,实际第二个参数是接收一个Cookie的结构体的指针。
Codeql如何分析cookie未启用httponly的问题Codeql如何分析cookie未启用httponly的问题

所以我们先要找到这样一个结构体,我们可以先把项目中所有的结构体列出来。

codeql-go中关于结构体的定义如下。
Codeql如何分析cookie未启用httponly的问题

所以我们的查询脚本例如。

import gofrom StructLit sourceselect source

也如我们预期的一样列出了所有的结构体。
Codeql如何分析cookie未启用httponly的问题

然后接下来就是剔除其他不相干的内容,对类型做限制。

关于hasQualifiedName方法,在各种Codeql-go中的各种类型都有相同的方法,定义如下,标记对象的是在属于哪个包,叫什么名。
Codeql如何分析cookie未启用httponly的问题

如果不确定的话,可以通过,getPackage和getName打印相关字段,例如。

import gofrom StructLit source// where source.getType().hasQualifiedName("net/http", "Cookie")select source.getType().getPackage(), source.getType().getName()

结果如下。
Codeql如何分析cookie未启用httponly的问题

我们可以找到source定义,例如。

import gofrom StructLit sourcewhere source.getType().hasQualifiedName("net/http", "Cookie")select source

Codeql如何分析cookie未启用httponly的问题同样转换成DataFlow::Node的子类。

private class Source extends DataFlow::Node {  Source() {    exists(StructLit s | s.getType().hasQualifiedName("net/http", "Cookie") and this.asExpr() = s)  }}

TaintConfig定义

简单的数据流

有了Source和Sink,简单定义TaintConfig,就能获得所有从Source到Sink的数据流。

import goprivate class Source extends DataFlow::Node {  Source() {    exists(StructLit s | s.getType().hasQualifiedName("net/http", "Cookie") and this.asExpr() = s)  }}private class Sink extends DataFlow::Node {  Sink() {    exists(DataFlow::CallNode c |      c.getTarget().hasQualifiedName("net/http", "SetCookie") and c.getArgument(1) = this    )  }}class Configuration extends TaintTracking::Configuration {  Configuration() { this = "HttpOnly" }  override predicate isSource(DataFlow::Node source) { source instanceof Source }  override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }}from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sinkwhere cfg.hasFlowPath(source, sink)select source, sink

结果如下:
Codeql如何分析cookie未启用httponly的问题

剔除

但是还没完,我们并没有将设置了httponly=true的部分给剔除。所以需要增加限定,就是将给HttpOnly字段设置了true的数据流,从结果中剔除。

我们可以 CodeQL 提供的 TaintTracking::isSanitizer,来过滤无害节点:

override predicate isSanitizer(DataFlow::Node node) {    exists(Write w, Field f, DataFlow::Node rhs |      f.hasQualifiedName("net/http", "Cookie", "HttpOnly") and      w.writesField(node, f, rhs) and      rhs.getBoolValue() = true    )  }

运行结果如下,但有一处地方需要注意。
Codeql如何分析cookie未启用httponly的问题红框中实际有对HttpOnly进行设置,但我们的脚本并不能识别这样的一个数据流。后面试了各种方法,最终找到一种解决方式,将isSanitizer修改成以下内容。

override predicate isSanitizer(DataFlow::Node node) {    exists(Write w, Field f, DataFlow::Node n, DataFlow::Node rhs |      f.hasQualifiedName("net/http", "Cookie", "HttpOnly") and      w.writesField(n, f, rhs) and      rhs.getBoolValue() = true and      node = n.getAPredecessor*()n    )  }

其中node=n.getAPredecessor*()是说node是n的前置数据流节点,数据可以在0个或多个步骤中从node流到n。

最终脚本

加上一些信息,模仿官方的示例,最终脚本如下。

/** * @name Cookie未设置httponly * @description Cookies包含一个HTTPOnly的设置选项,可以使此cookie不能被js读取,而只能用于HTTP请求。 * @kind path-problem * @problem.severity error * @precision low * @id go/Cookie-not-set-httponly * @tags security */import goimport DataFlow::PathGraphprivate class Source extends DataFlow::Node {  Source() {    exists(StructLit s | s.getType().hasQualifiedName("net/http", "Cookie") and this.asExpr() = s)  }}private class Sink extends DataFlow::Node {  Sink() {    exists(DataFlow::CallNode c |      c.getTarget().hasQualifiedName("net/http", "SetCookie") and c.getArgument(1) = this    )  }}class Configuration extends TaintTracking::Configuration {  Configuration() { this = "HttpOnly" }  override predicate isSource(DataFlow::Node source) { source instanceof Source }  override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }  override predicate isSanitizer(DataFlow::Node node) {    exists(Write w, Field f, DataFlow::Node n, DataFlow::Node rhs |      f.hasQualifiedName("net/http", "Cookie", "HttpOnly") and      w.writesField(n, f, rhs) and      rhs.getBoolValue() = true and      node = n.getAPredecessor*()    )  }}from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sinkwhere cfg.hasFlowPath(source, sink)select sink.getNode(), source, sink, "Cookie-not-set-httponly in $@.", source.getNode(), "here"

最终筛选出存在问题的内容。
Codeql如何分析cookie未启用httponly的问题

以上就是Codeql如何分析cookie未启用httponly的问题,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注亿速云行业资讯频道。

文章标题:Codeql如何分析cookie未启用httponly的问题,发布者:亿速云,转载请注明出处:https://worktile.com/kb/p/25451

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
亿速云亿速云认证作者
上一篇 2022年9月15日 下午11:21
下一篇 2022年9月15日 下午11:23

相关推荐

  • LDAP NULL bind导致登录绕过漏洞分析和修复方案是什么

    LDAP NULL bind匿名绑定导致登录绕过漏洞分析和修复方案 一、背景 1.1LDAP和认证过程 LDAP轻型目录访问协议是一个开放的,中立的,工业标准的应用协议,通过IP协议提供访问控制和维护分布式信息的目录信息。有优异的读性能,但写性能差。 LDAP作为开放的Internet标准,支持跨平…

    2022年9月13日
    48800
  • imazing请通过usb连接问题怎么解决

    imazing请通过usb连接解决方法 1、我们名列前茅次使用imazing连接电脑和手机是必须要使用usb线的,将usb线一头插在手机上一头插在电脑上。 2、连上之后我们需要在手机上进行确认。 3、确认信任之后就可以使用了。 到此,相信大家对“imazing请通过usb连接问题怎么解决”有了更深的…

    2022年9月16日
    24900
  • 怎么搭建配置Docker私有仓库

    ⛳️ 1.Docker容器三要素 Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之…

    2022年9月18日
    40800
  • vue包不包含jQuery

    vue中不包含jquery;vue是一个用于创建用户界面的开源JavaScript框架,虽然jquery也是一个JavaScript框架,但是jquery是使用选择器选取DOM对象,对其进行赋值、取值、事件绑定等操作,而vue对数据进行操作不再需要引用响应的DOM对象,二者并不存在包含的关系。 本文…

    2022年9月8日
    17400
  • MySQL触发器怎么创建和使用

    在实际开发中,我们经常会遇到这样的情况:有 2 个或者多个相互关联的表,如 商品信息 和 库存信息 分 别存放在 2 个不同的数据表中,我们在添加一条新商品记录的时候,为了保证数据的完整性,必须同时 在库存表中添加一条库存记录。 这样一来,我们就必须把这两个关联的操作步骤写到程序里面,而且要用 事务…

    2022年9月1日
    33700
  • 电脑0x80070035找不到网络路径怎么解决

    解决0x80070035找不到网络路径的方法 方法一: 1、我们先单击“网络”,“打开网络和Internet设置” 2、接着我们选择下“网络和共享中心” 3、接着我们选择“更改高级共享设置” 4、接着我们勾选“启用共享以便可以访问网络的用户读取公用文件夹中的文件” 5、到了“网络和共享中心”,我们直…

    2022年9月15日
    75500
  • windows如何修改一张图片的分辨率

    修改方法 1、打开图片,右击选择属性。可以从属性详细信息中查看到这个图片的分辨率。当前这个图片分辨率为687*379。 2、右击图片,选择编辑。打开图片编辑界面。也可以直接打开画图软件,在画图软件中打开需要编辑的这张图片。 3、选择工具栏中的重新调整大小选项。点击打开,会出现如图所示界面,通过这两个…

    2022年9月21日
    5.8K00
  • redis实现清空缓存的方法是什么

    正文 1.首先进到redis的安装目录,进到src目录下,找到redis-cli 2.首先用账号密码的方式进入到redis的服务端 ./redis-cli -h 127.0.0.1 -p 6379 -a 1234 进去后会出现下面的界面ip:port>,你就可以操作啦 3. flushdb —…

    2022年8月29日
    23500
  • win11更新后没声音怎么解决

    win11更新后没声音解决方法: 方法一: 1、部分设备在win10上的驱动可能无法在win11使用。 2、所以可以尝试拔出耳机或音效后,重新连接一下试试看。 方法二: 1、如果重新插拔后还是不行。 2、那么推荐下载一个Realtek音频管理器。【点击下载】 3、下载安装好之后,在其中开启声音就可以…

    2022年9月13日
    57800
  • windows浩辰cad看图王卸载不了怎么解决

    解决方法: 方法一: 1、首先我们要退出软件,然后右键任务栏空白处,打开“任务管理器” 2、在后台进程中找到所有cad相关进程。 3、选中这些进程,点击右下角的“结束任务” 4、结束完成后,我们打开系统设置中的“应用” 5、最后在其中找到浩辰cad看图王,将它卸载就可以了。 方法二: 1、另外我们也…

    2022年9月21日
    38600
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部