本次分享的目的,重点在于,让大家对常见的 Web 攻击有一个直观的认知。
当你知道,黑客是通过什么样的漏洞来攻击你的时候,你就更容易理解为什么要通过这样的方式来防范黑客攻击
本次分享不会过多涉及概念、防范的细节、千奇百怪的攻击方式。
有兴趣的同学,可以去找 谷G 同学请教。
演示地址
用户端  (SourceCode)
Hack 端 (SourceCode)
高版本 Chrome 会自动识别部分 XSS 攻击,并禁止你的访问
| 12
 
 | /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --args --disable-xss-auditor
 
 | 
XSS
后端在入库前应该选择不相信任何前端数据,将所有的字段统一进行转义处理。
前端在渲染页面 DOM 的时候应该选择不相信任何后端数据,任何字段都需要做转义处理。
攻击原理
浏览器可以动态加载、渲染页面 DOM,并执行 JS 脚本。
In Practice
Demo - 公开课案例
那么在我们的项目中,是怎么来防范 XSS 攻击的呢?
因为我们已经完全实现了前后端分离,所以我们重点关注服务器端的实现。
在我们的 Web 应用中,没有直接渲染页面的部分,所以,输出过滤也没有;只针对 API 参数的输入做了 XSS 的过滤。
Show The Code
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 
 | public abstract class AskBaseController extends RootController {
 
 public boolean isAntiXssEnabled() {
 return true;
 }
 
 @InitBinder
 public void commonInitBinder(final WebDataBinder binder) {
 if (isAntiXssEnabled()) {
 binder.registerCustomEditor(String.class, new PropertyEditorSupport() {
 @Override
 public void setAsText(String text) {
 setValue(WebUtil.escapeHtml(text));
 }
 
 @Override
 public String getAsText() {
 return ObjectUtil.nullToDefault(getValue(), StringConsts.EMPTY).toString();
 }
 });
 }
 }
 
 }
 
 
 public class WebUtil {
 
 public static String escapeHtml(String source) {
 if (StringUtils.isNotEmpty(source)) {
 StringBuilder buff = new StringBuilder((int)((double)source.length() * 1.3D));
 
 for(int i = 0; i < source.length(); ++i) {
 char _char = source.charAt(i);
 switch(_char) {
 case '"':
 buff.append(""");
 break;
 case '&':
 if(url) {
 buff.append(_char);
 } else {
 buff.append("&");
 }
 break;
 case '\'':
 buff.append("'");
 break;
 case '<':
 buff.append("<");
 break;
 case '>':
 buff.append(">");
 break;
 default:
 buff.append(_char);
 }
 }
 return buff.toString();
 }
 return source;
 }
 
 
 | 
缺陷
- 以 Controller 为单位,如果设置为关闭,该 Controller 下的所有接口默认都会取消 XSS 的输入过滤
- 依赖于 Spring MVC 容器实现,如果引入其他 MVC 框架,需要重新实现。
CSRF
在服务器端接收到的请求后,去校验这个请求是可信任的
攻击原理