xss攻击最终应对方案
Tag markdown, epiceditor, xss, 后端, 过滤, on by view 3702

今天终于解决了xss这个潜在的问题,编辑器使用的是Markdown编辑器EpicEditor,EpicEditor是一款Markdown编辑器,或者说是一款可以自己定制的编辑器。后台Markdown解析器用的是"github.com/russross/blackfriday",后台代码

func Markdown2HTML(content string) string {
	content = html.EscapeString(content)
	output := blackfriday.MarkdownCommon([]byte(content))
	return string(output)
}

直接将markdown语法的串解析为html语法的串,后台还设置了一个markdown解析api后面待用,api的controller代码如下

// parse markdown
type MarkdownController struct {
	controllers.BaseController
}

func (this *MarkdownController) Get() {
	this.Data["json"] = map[string]interface{}{
		"result": false,
		"msg":    "only post method support",
		"refer":  nil,
	}

	this.ServeJson()
}

func (this *MarkdownController) Post() {
	content := this.GetString("content")

	log.Blueln(content)
	rst := utils.Markdown2HTML(content)

	this.Data["json"] = map[string]interface{}{
		"result":  true,
		"msg":     "success",
		"preview": rst,
		"refer":   nil,
	}

	this.ServeJson()
}

前端将串传给后端,这个串期望是纯markdown的,因此如果其中夹杂着有html语法,html将会被转义,之后返回带有解析后的html串。

前端的EpicEditor默认是能够解析Markdown和兼容HTML的,甚至不过滤js(这个问题我已经向项目作者反馈过,他决定之后会给其添加选项以禁用js),由于我之前的文章提到css都会给用户机会造成页面混乱,而我所找到的过滤器只支持xss过滤,即只过滤js不过滤css,并且那个过滤器有一个依赖包在墙外,这将会是很蛋疼,所以决定使用markdown,是纯markdown。EpicEditor是兼容html的,因此不满足我的需求,于是我问EpicEditor的作者是否有禁用html的选项(传送),他告诉我EpicEditor不负责解析的,解析器可以自己定制,EpicEditor默认使用的解析器是markd解析器,然后给了我一个页面,其上有定制解析器的demo

var editor = new EpicEditor({
  parser: function (str) {
    var blacklist = ['foo', 'bar', 'baz'];
    return str.split(' ').map(function (word) {
      // If the word exists, replace with asterisks
      if (blacklist.indexOf(word) > -1) {
        return '****'
      }
      return word;
    }).join(' ');
  }
}).load();

自己重做一个解析器?看一下markd项目的代码有多少吧,重做工作量太大。仔细分析上面的代码发现parser是一个函数,它的作用是这样的,传入原串,返回解析后的串。这回我之前留的api起作用了,自己实现的parser函数如下

parser: function (str) {
	var rst = $.ajax({
		async: false,
		type: "post",
		url: "/api/markdown/preview",
		data: {"content": str},
		dataType:"json",

	}).responseText;
	var json = eval('('+rst+')')
	console.log(json);
	return json.preview;
},

是的,我将原数据传给服务器去解析,得到结果,这样还有一个好处就是保证了解析器的一致性,即最终结果与编辑器preview结果是一致的。当然这也是有一些缺点的,那就是给服务器增加了负担,不过我觉得这是值得的。最后附上编辑器工作的截图

epiceditor_back_end_anti_xss.png

问题能够得以解决应当感谢各个开源项目以及其作者的无私奉献,还有他们的热心答疑,取之于开源用之于开源,Goj也会是一个开源项目,愿早日完成。


XSS攻击应对方案
Tag XSS, 攻击, 跨站脚本攻击, on by view 6706

XSS(Cross Site Scripting),跨站脚本攻击,简单来说就是用户获取到了页面脚本执行的权限,够获取到JS脚本执行权限后能干的事情很多,比如盗取session id,从而实现登录帐号从而获取账户相关信息。

XSS攻击一般都是出现在有富文本提交的表单中,用户可以在提交的富文本中按以下各种方法插入JavaScript脚本:

<script>alert("hacked!");</script>
<img src="./" onerror="alert('hacked!');">
<a href="javascript:alert('hacked!')">foo</a>
<style>
div{
  background: url("javascript:alert('hacked!');");
}
</style>

以及其他的各种方法在页面执行Js脚本,当然黑客执行脚本的目的并不是为了弹窗装逼,而是读取当前用户的cookies,从而获取session id,达到非法登录用户账户的目的,简单来说就是不要密码盗号。

嵌入式web页面富文本编辑器很多,例如ueditor等,有人以为防范XSS攻击是这些编辑器的事情,事实上XSS攻击并不是这些编辑器能够阻止得了的,因为黑客是可以绕过编辑器提交表单的,所以防范XSS攻击的重点是后台字符串过滤,将非法的串过滤掉,当然还有另外一种办法,那就是使用第三方替代标签,如UBB标签(discuz中使用的就是这个)、Markdown等,不直接使用HTML系列的标签由其他标签转换为HTML,从而达到防止非法注入脚本的目的。

事实上富文本提交攻击防范远不止XSS这些,XSS主要是指Js脚本的攻击,可是有一种不致命却很糟糕的攻击却是被忽略了,那就是css脚本扰乱界面布局,事实上这应该算是纯粹的捣乱,可是却也能够严重的影响到页面的美观以及用户的正常使用,开源中国就曾经被大家用这种方法玩坏过。

<div style="display:block;position:fixed;width:100%;height:100%;background-color:red;"></div>

上面的代码便可以让整个网页变成红色。

因此,我个人认为html富文本的过滤不仅仅是简单的Js过滤,应当连css一起过滤掉。或者干脆使用第三方标签UBB等。