网上有各种防止 xss 和 sql 注入的方案,前端的也有,后端的也有。各种方案太多太杂,看的我头疼。
我的策略是,前端负责非法字符的过滤,转换,显示,让过滤后的安全数据入库,以及能安全的显示给用户看。而后端处理非法字符,就很简单。一旦检测到非法字符就直接返回 404,403,400 等错误码。
那么问题来了,先不考虑富文本,就那种普通的文本框,假设每个用户用浏览器操作,在输入框里输入的内容中,都可能带有 sql 注入,xss 攻击所用的代码的一段文字或文章例,前端如何负责这些带有非法字符的过滤转换?让数据能安全的入库,然后在数据显示时,又能显示用户输入时的样子,又不出问题呢。
101
u823tg 2020-04-24 17:59:19 +08:00
@Leon6868 #97
看情况么 const tag = document.createElement("script"); tag.innerText = `console.log('v2')`; document.body.appendChild(tag); 杠一下。 -_- |
103
Leon6868 2020-04-24 18:04:00 +08:00
@u823tg 我说的是 sql 注入。。innerText 确实可以避免的,#97 已经承认了。我的意思和#98 的差不多,你可以参考一下
|
104
huang7230468 2020-04-24 18:05:28 +08:00
还是从后端考虑吧,
|
105
u823tg 2020-04-24 18:11:36 +08:00
@tctc4869 #98 二次注入你怎么办, 用户的输入本来就不可信。 严格来说存到数据库的数据得经过过滤,脏数据不可否认的有危险性。
|
106
Deffi 2020-04-24 18:14:02 +08:00
前端过滤怎么行,人家直接走接口,又不一定走前端 js
|
107
zhouwei520 2020-04-24 18:14:18 +08:00
一劳永逸是不是不做程序员?
|
108
zhuisui 2020-04-24 18:16:45 +08:00
`"topic_id": 665687, "content": "<img onerror=\"alert(111)\"/>", "content_rendered": "<img onerror=\"alert(111)\"/>",`
这叫没转码?到底是谁瞎了 "content_rendered" ,顾名思义,要渲染的内容,明明是转过的。 |
109
zhw2590582 2020-04-24 18:18:34 +08:00
前端防用户手动输入都是做做样子,会 js 的人直接控制台里调接口了,前端还过滤个毛线,关键还是后端
|
110
Deffi 2020-04-24 18:19:20 +08:00
前端过滤只是用户友好,后端过滤才是安全啊
|
111
zhuisui 2020-04-24 18:21:55 +08:00
各位,我相信题主的意思是:
1. 前端是面向正常用户的,各种不合法输入都应该在检查后展示给用户原因。 2. 而后端只需要粗暴的返回数据是否合法,因为如果数据是前端来的,那么必然已经经过前端的校验了。如果不是前端来的非法请求,那我也没必要告诉你为什么你的请求出问题了。 |
112
otakustay 2020-04-24 18:24:43 +08:00
这事情的本质是:后端只管安全不管用户体验,前端完全负责用户体验,是否有可行性
至少在注入这件事上,我想说没有可行性,用 SQL 参数带来的体验前端不能完全 cover 住 当然在另外一些事上是可能有可行性的,要就事论事 |
113
taaaang 2020-04-24 18:28:51 +08:00
验证和过滤从来都不只是前端的事情,哪来一劳永逸,多关注用户体验,其他交给后端。
|
115
aguesuka 2020-04-24 19:08:37 +08:00
@fancy111 有意思,不用后端,不用过滤,来吧
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>xss me</title> <script> window.onload = function () { const url = new URL(location.href) const input = url.searchParams.get('input'); document.getElementById('output').innerText = input; document.querySelector('input').value = input; } </script> </head> <body> <form> <label> <input type="text" name="input"/> </label> <button type="submit">submit</button> </form> <pre id="output"></pre> </body> </html> |
116
sagaxu 2020-04-24 19:10:34 +08:00 via Android 1
SQL 注入,prepared statement 一劳永逸,过滤是瞎鸡巴搞。
XSS 注入,后端拼 html 的由后端转义,前后端分离的,前端负责搞定。 |
117
cumt21g 2020-04-24 19:18:39 +08:00
起作用的还是后端过滤吧
|
118
skyRival 2020-04-24 19:23:11 +08:00
|
119
tctc4869 OP @Deffi
@zhw2590582 @taaaang 前端过滤,是因为前端是面向正常的客户端,而构造请求直接调后端接口不算正常的客户端,后端主要负责安全,用户体验交给前端。 后端既然检测的非法数据,就代表请求的客户端是不正常的客户端,没有经过前端验证过滤的客户端,就没有必要从数据库拿数据了,更没有必要过滤数据。都已经是非正常用户了,没必要告诉客户端是不是请求出问题了。 |
120
tctc4869 OP @cumt21g 后端过滤是多此一举,浪费精力,后端负责通不通过就行,难道后端还要告诉非法请求的客户端,你的请求数据有问题么?正常的客户端就交给前端去负责。至于非法客户端。
|
121
zhangysh1995 2020-04-24 19:40:42 +08:00
考虑一下验证方法,把这篇论文实现,The essence of command injection attacks in web applications
|
122
zhangysh1995 2020-04-24 19:41:42 +08:00
|
123
no1xsyzy 2020-04-24 19:42:51 +08:00
严格白名单新建一套描述富文本的语言,然后写个该语言到 HTML 的编译器
那建立一个和 html 很像的语言也没什么问题,但别偷懒,整个重新 parse 分析语义然后再重新渲染,不要 passthru BBcode 和 Markdown 在一定程度上就是逼自己和后续维护者别偷懒 |
126
Xezzon 2020-04-24 20:07:04 +08:00 via Android
@aguesuka 你可真有意思,谁说了要这么写了?没事放 pre 在那干嘛?难道专门为了让别人来 xss 所以我就得不用 div 用 pre 呗?
|
127
fxxwor99LVHTing 2020-04-24 21:13:11 +08:00
前端做不了,
|
128
buffzty 2020-04-24 21:35:29 +08:00 1
没人说用 react 吗? 用 react 不会出现 xss,显示时自动过滤
render() { const txt = '</script><script>alert(11);</script>' return <div>{txt}</div> } // output </script><script>alert(11);</script> |
129
mxT52CRuqR6o5 2020-04-24 21:49:16 +08:00 via Android
@buffzty xss 注入很多时候是有富文本的需求的
|
130
mxT52CRuqR6o5 2020-04-24 21:56:44 +08:00 via Android 1
sql 注入靠前端防不了,攻击者完全可以自己手动构造请求不需要通过前端去发请求
Xss 注入可以靠把富文本转成非 html 的抽象来解决(比如 quill) 普通的文本框去设置 innerHTML 是水平不行 |
131
buffzty 2020-04-24 22:46:04 +08:00
现在 orm 都是预处理.怎么可能注入呢
|
132
binux 2020-04-24 22:58:27 +08:00 via Android
@fancy111 #6 说好的只用 innerText 的,如果 '</script><script>alert(11);</script>' 是用户输入的话,它是怎么进入 HTML 的? 你还不是拼接 HTML 了。
|
133
rsjztz 2020-04-24 23:10:29 +08:00 via Android
关于 xss,我看过前端拦截 xss 语句运行的操作,sqli 还是得后端过滤
|
134
canwushuang 2020-04-24 23:20:10 +08:00 via Android
你正则能过滤 get,还能大量过滤 post 和 put ?多次编码随你正则一样绕。超长字符击穿防线也是可以,emoji 也行。别防了。。。
|
135
canwushuang 2020-04-24 23:29:32 +08:00 via Android
@sagaxu % 直接 like
|
136
neoblackcap 2020-04-25 01:15:47 +08:00
要过滤就直接先后端解析一遍,有问题就干掉,没问题就放行
|
137
hblf 2020-04-25 01:16:41 +08:00 via iPhone 1
都 0202 年了就别想着用过滤特殊字符解决 sqli 了吧,预编译比过滤安全一万倍
xss 的过滤参考 owasp 自己出的 api 各位开发大佬平时真的不看 owasp 的文档吗? |
138
Hyduan 2020-04-25 02:47:35 +08:00
话说这个会有 xss 问题么。。各位大佬试试 https://codepen.io/Hyduan/pen/bGVqLQr
|
140
tctc4869 OP @buffzty 大多数情况下可以用 orm 或 prepared statement 实现 sql 防注入,但也有不得不必须用拼接 sql 语句的方式。这类方式多数是复杂的查询语句
|
141
anUglyDog 2020-04-25 13:02:59 +08:00
|
142
DOLLOR 2020-04-25 14:47:53 +08:00
前后端分离用 react 、vue 框架根本就不用考虑这种事情,因为这些工具本来就是作为文本显示。奈何就是有人喜欢 jQuery,拼接 HTML 字符串,到处都是漏洞。
|
143
liuser666 2020-04-25 15:00:35 +08:00
前端用一下算法对字符串加一层 hash 等等再 webpack 一下,然后后端同样,端口要求处理结果,最后后端对比,让他不得不从前端走。
|
145
fancy111 2020-04-26 09:34:37 +08:00
@aguesuka 你先搞懂什么叫只用 innertext,你这个过滤是靠 searchParams 解析后转化的,还不用过滤,你连什么叫过滤都不懂。
另外谁会这么用?你网站上显示的字符都是这样来的吗? 搞笑。 |
146
xiaomimei 2020-04-26 10:08:44 +08:00
看楼上的有些人,就知道安全给开发反馈漏洞的时候有多难受了。
|
147
stevenkang 2020-04-26 10:47:01 +08:00
楼上争来争去,一群人按照前端渲染的角度来说,一群人按照后端渲染的角度来说,这样讨论问题毫无意义。
# 前端渲染时 1 、前端负责处理 XSS,用 innerText 可以解决。 2 、后端负责处理 SQL 注入,用 prepared statement 可以解决。 # 后端渲染时 1 、前端不用处理 XSS 、SQL 注入。 2 、后端负责处理 SQL 注入,用 prepared statement 可以解决。 3 、后端还需额外处理用户提交的数据必须进行 HTML 转义后再渲染返回给前端。 |
148
viikker 2020-04-26 11:04:57 +08:00
没有
|