Upgrade to Pro — share decks privately, control downloads, hide ads and more …

MVVM Framework Security

Oritz
May 23, 2017

MVVM Framework Security

Some security issues of the MVVM framework, take AngularJS for an example.

Oritz

May 23, 2017
Tweet

More Decks by Oritz

Other Decks in Programming

Transcript

  1. “ 3 31.80% 22.30% 7.80% 4.60% 4.50% 4.20% 3.80% 3.50%

    3.00% 2.90% 11.80% 2016 年 TOP10 漏洞比例分布 XSS 信息泄露类 权限控制 后台弱密码 SSRF 逻辑设计缺陷 安全性误配置 可执行漏洞 暴力破解
  2. 4 怎么对付 XSS 保护 Cookie • HttpOnly • Secure 设置请求头

    • CSP • X-XSS-Protection 过滤 • < > • script onerror 转义 • escape() • HTMLEncode() 十八般武艺齐上阵
  3. 5 事情好像没有那么简单 编码 • URL encode • Unicode 其他 •

    window.name • ES6 feature (alert`1`) • iframe 字符集 • ISO-2022-JP • UTF-7 关键字 • scrscriptipt • String.fromCharcode() • location.hash 各种花式绕过技巧
  4. Flask 用的 Jinja2 模板引擎 什么是模板注入 8 @app.errorhandler(404) def page_not_found(e): template

    = '''{%% extends "layout.html" %%} {%% block body %%} <div class="center-content error"> <h1>Oops! That page doesn't exist.</h1> <h3>%s</h3> </div> {%% endblock %%} ''' % (request.url) return render_template_string(template), 404
  5. 用 AngularJS 举个栗子 11 <html> <head> <meta charset="utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/angular

    js/1.4.6/angular.js"></script> </head> <body> <div ng-app>{{ 7+7 }}</div> </body> </html> » 直接生成前端模板 » {{ 7 + 7 }} » AngularJS 解析和执行 » 输出 14 » 那如果换成 {{ alert(1) }} 会咋 样?
  6. 危险的模板和表达式 16 有多种方法可以控制模板和表达式 表达式在解析时包含用户提供的内容: » $compile(userContent) » $parse(userContent) » $interpolate(userContent)

    表达式中使用管道时条件包含用户提供的内容: » {{ value | orderBy : userContent }} 在生成 AngularJS 模板时包含用户提供的内容。 表达式时在调用下面的方法时包含用户提供的内容: » $watch(userContent, ...) » $watchGroup(userContent, ...) » $watchCollection(userContent, ...) » $eval(userContent) » $evalAsync(userContent) » $apply(userContent) » $applyAsync(userContent)
  7. 向 DOM 中插入 HTML 19 错误做法(一) 关闭自动转义 // Within the

    controller // Disables strict auto escaping $sce.enabled(false); $scope.html = "Hello <b>" + userInput + "</b>!"; // Within the view <div>{{html}}</div>
  8. 向 DOM 中插入 HTML 20 错误做法(二) 使用 element.html() 插入 HTML

    // Within the controller angular.element(someElement) .html("Hello <b>" + userInput + "</b>!")
  9. 向 DOM 中插入 HTML 21 错误做法(三) 使用 ngBindHtml + trustAsHtml

    // Within the controller $scope.html = $sce.trustAsHtml("Hello <b>" + userInput + "</b>!"); // Within the view <div>{{html}}</div>
  10. 向 DOM 中插入 HTML 22 错误做法(四) 使用 ngBindHtml + trustAsHtml

    然后自己写 XSS 过滤函数 // Within the controller var escapedUserInput = escapeForHtml(userinput); $scope.html = $sce.trustAsHtml("Hello <b>" + escapedUserInput + "</b>!"); // Within the view <div>{{html}}</div>
  11. 向 DOM 中插入 HTML 23 正确做法 使用 ngBindHtml + sanitizer

    <body> <script src="../1.5.7/angular.js"></script> <script src="../1.5.7/angular-sanitize.js"></script> <div ng-app="myApp" ng-controller="myCtrl"> <p ng-bind-html="html"></p> </div> <script> var userInput = 'test<svg/onload=alert(1)>'; var myApp = angular.module('myApp', ["ngSanitize"]); var controller = myApp.controller('myCtrl', function($scope) { $scope.html = "Hello <b>" + userInput + "</b>!" }); </script> </body>
  12. 混用第三方库时的风险 24 开发时往往会用到很多第三方库 单独使用时可能没有漏洞, 但与 AngularJS 混合使用时就出现 问题了。 <script> //

    A non angular-related library. // Secure without Angular. Insecure with Angular. document.write(escapeForHTML(userInput)); </script> <script src="../angularjs/1.5.7/angular.min.js"></script>
  13. 混用第三方库时的风险 25 » EscapeForHTML 常见转义函数 » userInput 用户输入 » 没有引入

    Angular 时一切正常 » 引入 Angular 后 » 输入沙箱绕过的 Payload » BOOM! <body><div ng-app> <script> function escapeForHTML(unsafe) { return unsafe .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;") .replace(/"/g, "&quot;") .replace(/'/g, "&#039;"); } var userInput = '{{x = {"y":"".constructor.prototype}; x["y"].charAt=[].join;$eval("x=alert(1)");}}'; document.write(escapeForHTML(userInput)); </script></div> <script src="../angularjs/1.5.7/angular.js"></script> </body>
  14. AngularJS 校验 URL 的方式 28 » $sceDelegateProvider.resourceUrl(White|Black)list([list]) » 默认只能访问同一域名下的资源 »

    有三种校验方式:’self’, String 和 Regxes(正则) » 其中 String 支持两种通配符: * :匹配除 : / . ? & 和 ; 之外的任意数量字符 **:匹配所有的字符
  15. AngularJS 校验 URL 的方式 29 错误做法(一) 在协议处使用通配符 // Whitelist all

    possible schemes "**://example.org/*" • Exploit 1: http://evil.com/?ignore=://example.org/a • Exploit 2: javascript:alert(1);//example.org/a // Less permissive, but still bad "*://example.org/*" • Exploit 1: javascript://example.org/a%0A%0Dalert(1) 注释 换行
  16. AngularJS 校验 URL 的方式 30 错误做法(二) 在域名里使用 ** 通配符 //

    Whitelist all possible subdomains "https://**.example.org/*" • Exploit 1: https://evil.com/?ignore=://example.org/a // Whitelist all possible top level domains "https://example.**" • Exploit 1: https://example.evil.com • Exploit 2: https://example.:[email protected]
  17. AngularJS 校验 URL 的方式 31 错误做法(三) 使用正则表达式 // Use a

    RegEx to whitelist a domain /http:\/\/www.example.org/g • Exploit 1: // (dots are not escaped) http://wwwaexample.org • Exploit X: All the wildcard-based exploits can be applied as well
  18. AngularJS 校验 URL 的方式 32 结论 » 尽量不要使用正则表达式 » 不要在协议中使用通配符

    » 不要在域名中使用 ** » 只在子域名和网站路径中使用 * » 最好的方式是仅列出特定的 URL 作为白名单
  19. 38