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

Server Security

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for Yibo Yibo
January 16, 2021

Server Security

Avatar for Yibo

Yibo

January 16, 2021
Tweet

More Decks by Yibo

Other Decks in Technology

Transcript

  1. 通⽤的安全加固⽅法 通道安全:HTTPS ,WSS ,MQTT+SSL 加密: DES 、3DES 、AES ,RSA 、DSA

    、ECC ,密钥管理 验签:DSA 、RSA ,MD5 、SHA1 、Bcrypt 业务防护:业务层需要对传⼊的参数进⾏验证,进⾏真正业务意义上 的判断。MVCC+CAS 2
  2. 常⻅的攻击类型 XSS (Cross Site Script ,跨站脚本攻击) ClickJacking (点击劫持) CSRF (Cross-site

    request forgery ,跨站请求伪造) ⽂件上传漏洞、⽂件下载漏洞 ( ⽬录遍历攻击) 注⼊漏洞(SQL 、Command 、Code ··· ) 框架低版本漏洞 整数溢出 其他 3
  3. XSS 攻击是指攻击者在⽹站上注⼊恶意的客户端代码,通过恶意脚本对 客户端⽹⻚进⾏篡改,从⽽在⽤户浏览⽹⻚时,对⽤户浏览器进⾏控制 或者获取⽤户隐私数据的⼀种攻击⽅式。 攻击者对客户端⽹⻚注⼊的恶意脚本⼀般包括 JavaScript ,有时也会包 含 HTML 和

    Flash 。有很多种⽅式进⾏ XSS 攻击,但它们的共同点为: 将⼀些隐私数据像 cookie 、session 发送给攻击者,将受害者重定向到 ⼀个由攻击者控制的⽹站,在受害者的机器上进⾏⼀些恶意操作。 XSS 攻击的前提: Web ⻚⾯ 且 前端使⽤ v-html (Vue ) 或产⽣ DOMXSS 。 5
  4. XSS 攻击的种类 反射型 XSS 不可信内容提交到服务器,⽴即在响应中被返回。 ⽐如:有⼀个登陆⻚⾯需要输⼊⽤户名,提交后会显示 “ 你好,XXX” ,这⾥的 XXX

    即有可能存在反 射型 XSS 攻击漏洞。 持久型 XSS 不可信内容提交到服务器,被保存到服务器数据库,下次需要时被当做可信内容被返回。 ⽐如:恶意代码写⼊个⼈资料⻚,所有访问我的资料的朋友都会遭到攻击 DOM XSS 通过恶意脚本修改⻚⾯的 DOM 结构,是纯粹发⽣在客户端的攻击。 存储型与反射型为服务器端安全漏洞;DOM 型为前端安全漏洞。 6
  5. XSS 危害 Cookie 劫持(窃取 Cookie ) 后台增删改等操作(类似于 CSRF 骗取⽤户点击,利⽤ js

    模拟浏览器 发包,借助 xmlhttprequest 类) 钓⻥,利⽤ XSS 构造出⼀个登录框,骗取⽤户账户密码 修改⽹⻚代码 利⽤⽹站重定向 获取⽤户信息(如浏览器信息、IP 、截屏、经纬度、电池状态等) XSS Worm (XSS 蠕⾍,XSS 漏洞利⽤的终极武器,2005 MySpace 、2019 Twitter ) 8
  6. 防范 XSS 攻击 XSS 攻击的本质是不安全的 HTML 注⼊,可通过在 HTML 、CSS 、JS

    或 HTTP 协议层次上进⾏防范。 预防存储型和反射型 XSS 攻击 输⼊过滤 输出检查 Cookie 中设置 HttpOnly CSP 策略 预防 DOM 型 XSS 攻击 9
  7. 预防存储型和反射型 XSS 攻击 输⼊过滤 在⽤户提交时,由前端过滤输⼊,然后提交到后端。这样做是否可⾏呢? 答案是不可⾏。⼀旦攻击者绕过前端过滤,直接构造请求,就可以提交恶意代码了。 输⼊侧过滤能够在某些情况下解决特定的 XSS 问题,但会引⼊很⼤的不确定性和乱码问题。在防范 XSS

    攻击时应避免此类⽅法。 当然,对于明确的输⼊类型,例如数字、URL 、电话号码、邮件地址等等内容,进⾏输⼊过滤还是必要 的。另外,富⽂本建议使⽤⽩名单机制进⾏过滤。 注意:转义后字串⻓度会增加,可能超出数据库字段的预期⻓度导致被截断。 10
  8. 输出检查 ⼀般来说,除了富⽂本的输出外,在变量输出到 HTML ⻚⾯时,可以使⽤编码或转义的⽅式来防御 XSS 攻击。 安全的编码函数: HTML 代码的编码⽅式是 HtmlEncode

    ,要求⾄少转换 &<>"'/ 。 JavaScript 的编码⽅式可以使⽤ JavascriptEncode 。 在 CSS 中输出在 CSS 和 style 、style attribute 中形成 XSS 使⽤ encodeForCSS() 。 在地址中输出: 在 URL 的 path (路径)或者 search (参数)中输出,使⽤ URLEncode 。 针对不同位置的输出,使⽤不同的处理⽅式。 思考:是否⽤转义就可以⾼枕⽆忧了? 11
  9. Cookie 中设置 HttpOnly HttpOnly 并⾮为了对抗 XSS——HttpOnly 解决的是 XSS 后的 Cookie

    劫持攻击。 因为设置 HttpOnly 的⽅法⽐较简单,使⽤也很灵活,并且对防御 Cookie 劫持⾮常有⽤,因此已经渐渐成为⼀种默认的标准。 response.setHeader("Set-Cookie", SESSION_ID+"="+session_id+";Path=/;HttpOnly;"); cookie.setHttpOnly(true); add_header Set-Cookie "HttpOnly"; proxy_cookie_path / "/; HTTPOnly; Secure"; 12
  10. CSP 策略 Content Security Policy ,实质就是⽩名单制度,开发者明确告诉客户 端,哪些外部资源可以加载和执⾏。在服务端使⽤ HTTP 的 Content-

    Security-Policy 头部来指定策略,或者在前端设置 meta 标签。 Content-Security-Policy: script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https: <meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:"> 脚本:只信任当前域名 <object> 标签:不信任任何 URL ,即不加载任何资源 样式表:只信任 http://cdn.example.org 和 http://third-party.org 框架(frame ):必须使⽤ HTTPS 协议加载 其他资源:没有限制 13
  11. 预防 DOM 型 XSS 攻击 DOM 型 XSS 攻击,实际上就是⽹站前端 JavaScript

    代码本身不够严谨,把不可信的数据当作代码执 ⾏了。 在使⽤ .innerHTML 、 .outerHTML 、 document.write() 时要特别⼩⼼,不要把不可信的数据作为 HTML 插到⻚⾯上,⽽应尽量使⽤ .textContent 、 .setAttribute() 等。 如果⽤ Vue/React 技术栈,并且不使⽤ v-html / dangerouslySetInnerHTML 功能,就在前端 render 阶段 避免 innerHTML 、outerHTML 的 XSS 隐患。 DOM 中的内联事件监听器,如 location 、 onclick 、 onerror 、 onload 、 onmouseover 等, 标签的 href 属性,JavaScript 的 eval() 、 setTimeout() 、 setInterval() 等,都能把字符串作为代码运⾏。 如果不可信的数据拼接到字符串中传递给这些 API ,很容易产⽣安全隐患,请务必避免。 驱散前端安全梦魇 ——DOMXSS 典型场景分析与修复指南 15
  12. 防御 XSS 总结 HTTPS Cookie 中设置 HttpOnly 富⽂本在输⼊时使⽤⽩名单机制过滤 服务端与 H5

    端配合,在输出渲染时进⾏转义 or 过滤 服务端转义、过滤⼯具:服务端- 防御 XSS 跨站脚本攻击 H5 端转义、过滤⼯具:H5-XSS 防御 H5 端⻚⾯梳理:涉及到安全问题的⻚⾯ CSP 策略 H5 端注意 DOMXSS 16
  13. XSS 检测⼯具 XSStrike xssfork XSS 攻击⼩游戏 开发者在⽹站上故意留下了⼀些常⻅的 XSS 漏洞。玩家在⽹⻚上提交相 应的输⼊,完成

    XSS 攻击即可通关。可以在玩游戏的过程中,加深对 XSS 攻击的理解。 alert(1) to win prompt(1) to win XSS game 17
  14. ClickJacking 防御⽅法 frame busting 通常可以写⼀段 JavaScript 代码,以禁⽌ iframe 的嵌套。这种⽅法叫 frame

    busting 。 但是 frame busting 也存在⼀些缺陷。由于它是⽤ JavaScript 写的,控制能⼒并不是特别强,因此有许 多⽅法可以绕过它。 HTTP 头 X-Frame-Options 它有三个可选的值: DENY : 浏览器会拒绝当前⻚⾯加载任何 frame ⻚⾯; SAMEORIGIN :frame ⻚⾯的地址只能为同源域名下的⻚⾯; ALLOW-FROM origin :可以定义允许 frame 加载的⻚⾯地址。 不过这种⽅式在 HTTP 中不可靠,⿊客可以窃听篡改 HTTP 请求来修改 HTTP 头。 20
  15. CSRF CSRF ,跨站请求伪造。也被称为 one-click attack 或者 session riding ,通常缩写为 CSRF

    或者 XSRF 。是⼀种挟制⽤户在当前已登录的 Web 应⽤程序上执⾏⾮本意的操作的攻击⽅法。 CSRF 攻击的过程,往往是在⽤户不知情的情况下构造了⽹络请求。 它在 2007 年曾被列为互联⽹ 20 ⼤安全隐患之⼀。 即便是⼤名鼎鼎的 Gmail ,在 2007 年底也存在着 CSRF 漏洞,从⽽被 ⿊客攻击⽽使 Gmail 的⽤户造成巨⼤的损失。 21
  16. CSRF 攻击原理 ⽤户登录存在漏洞的健康⽹ 站 A ; ⽹站 A 服务器验证了⽤户的 身份之后,响应该⽤户的

    Cookie 作为身份凭证; 攻击⽹站 B 检查到⽹站 A 的 漏洞或者引诱⽤户在 A ⽹站 访问 B ⽹站,这样攻击⽹站 就可以带上⽤户的身份凭证 向 ⽹站 A 发起请求 ( 攻击) ; 22
  17. ⼩明同学百⽆聊赖地刷着 Gmail 邮件。⼤部分都是没营养的通知、验证码、聊天记录之 类。但有⼀封邮件引起了⼩明的注意: 聪明的⼩明当然知道这种肯定是骗⼦,但还是抱着好奇的态度点了进去(请勿模仿)。 果然,这只是⼀个什么都没有的空⽩⻚⾯,⼩明失望的关闭了⻚⾯。⼀切似乎什么都没 有发⽣…… <form method="POST" action="https://mail.google.com/mail/h/ewt1jmuj4ddv/?v=prf"

    enctype="multipart/form-data"> <input type="hidden" name="cf2_emc" value="true"/> <input type="hidden" name="cf2_email" value="[email protected]"/> ..... <input type="hidden" name="irf" value="on"/> <input type="hidden" name="nvp_bu_cftb" value="Create Filter"/> </form> <script> document.forms[0].submit(); </script> https://www.davidairey.com/google-gmail-security-hijack/ 甩卖⽐特币,⼀个只要 998 !! “ “ 23
  18. CSRF 常⻅防御⽅法 同源策略 Origin 、 Referer ,都是⽤来表示请求源地址。在⼤多数场景中,会跟随着请求头发送到服务器,然后 服务器通过解析头部值,获取请求来源地址。⼀般来说,我们在服务器设置好允许请求地址通过的⽩名 单,然后当服务器拿到请求的来源地址,就可以进⾏过滤了。 Origin

    说到 Origin ,就不得不提 CORS 了。CORS 需要浏览器和服务器同时⽀持。⽬前,所有浏览器 都⽀持该功能,~IE 浏览器不能低于 IE10~ 。⼀旦请求发⽣ CORS ,那么请求头部信息就会携带 Origin ,但是假如发⽣ 302 重定向,那么 Origin 也不会跟随着请求头部信息⼀起发送给服务器。 Referer Referer 的值是由浏览器提供的,每⼀次的 HTTP 请求⾸部中都会有该字段,不管是 Ajax 请 求,还是图⽚。既然由浏览器提供,那么就存在被攻击者刻意隐藏,甚⾄伪造 Referer 的值。 25
  19. CSRF Token 服务器需要⽣成⼀个通过加密算法加密的 Token ; 将该 Token 保存⾄ Cookie ,更安全⾼效的是应该保存在

    Session 或 者 Redis ; 将该 Token 传给客户端,客户端在请求时要将其 Token ⼀并带上, 请求到服务器后,服务器就可以通过解密对⽐来判断该 Token 的有效 性了。 Token 虽然很有效的防御 CSRF ,但是实现复杂,不仅需要前端这边的 请求都带上 Token ,⽽且后端也需要对每个接⼝都进⾏校验,因此⼯作 量⽐较⼤。 27
  20. Set-Cookie: SameSite SameSite-cookies 是 Google 开发的⽤于防御 CSRF 和 XSSI (Cross

    Site Script Inclusion ,跨域脚本包含)的新安全机制,只需在 Set- Cookie 中加⼊⼀个新的字段属性,浏览器会根据设置的安全级别进⾏对 应的安全 cookie 发送拦截,从 Chrome 51 开始可⽤。 SameSite Cookie 在⼦域不⽀持共享,也就是说⽗域登录后在⼦域还需 要重新登录,这显然不够友好,⽽且还存在兼容性问题。 28
  21. 防御 CSRF 总结 总的来说,CSRF 危害很⼤,⽽且还跟 XSS ⼀样很难防范。 虽然说上⾯罗列的各种防御策略可以很⼤程度上防御 CSRF 攻击,但是

    并⾮⼗全⼗美。所以需要根据实际情况来选择最合适的策略,这样才能 降低受到 CSRF 攻击的概率。 我们当前的策略:使⽤“ 简化版” CSRF Token 。客户端进 H5 时会换票, 顺便⽣成⼀个 CSRF Token ,之后 H5 在 1h 内拿着这个 Token 都可以请 求。 在防御 CSRF 之前,需要先防御 XSS 。 29
  22. ⽂件上传漏洞 ⽂件上传漏洞是指由于程序在对⽤户⽂件上传部分的控制不⾜或者处理缺陷, ⽽导致的⽤户可以越过其本身权限向服务器上上传可执⾏的动态脚本⽂件。 这⾥上传的⽂件可以是⽊⻢,病毒,恶意脚本或者 WebShell 等。这种攻击⽅ 式是最为直接和有效的,“ ⽂件上传” 本身没有问题,有问题的是⽂件上传后, 服务器怎么处理、解释⽂件。如果服务器的处理逻辑做的不够安全,则会导致

    严重的后果。 ⽂件上传漏洞本身就是⼀个危害巨⼤的漏洞,WebShell 更是将这种漏洞的利 ⽤⽆限扩⼤。⼤多数的上传漏洞被利⽤后攻击者都会留下 WebShell 以⽅便后 续进⼊系统。攻击者在受影响系统放置或者插⼊ WebShell 后,可通过该 WebShell 更轻松,更隐蔽的在服务中为所欲为。 30
  23. ⽂件上传漏洞危害 上传⽂件是 Web 脚本语⾔,服务器的 Web 容器解释并执⾏了⽤户上 传的脚本,导致代码执⾏; 上传⽂件是 Flash 的策略⽂件

    crossdomain.xml ,⿊客⽤以控制 Flash 在该域下的⾏为( 其他通过类似⽅式控制策略⽂件的情况类似); 上传⽂件是病毒、⽊⻢⽂件,⿊客⽤以诱骗⽤户或者管理员下载执⾏: 上传⽂件是钓⻥图⽚或为包含了脚本的图⽚,在某些版本的浏览器中 会被作为脚本执⾏,被⽤于钓⻥和欺诈。 除此之外,还有⼀些不常⻅的利⽤⽅法,⽐如将上传⽂件作为⼀个⼊⼝,溢出服务器的 后台处理程序,如图⽚解析模块;或者上传⼀个合法的⽂本⽂件,其内容包含了 PHP 脚 本,再通过“ 本地⽂件包含漏洞(Local File Include )” 执⾏此脚本;等等。 31
  24. ⽂件下载漏洞示例 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException

    { String root = request.getServletContext().getRealPath("/upload"); String filename = request.getParameter("filename"); File file = new File(root+"/"+filename); FileInputStream fis = new FileInputStream(file); response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes())); response.addHeader("Content-Length", "" + file.length()); byte[] b = new byte[fis.available()]; fis.read(b); response.getOutputStream().write(b); } filename = ../WEB-INF/web.xml 34
  25. SQL 注⼊ HttpServletRequest request = ...; String userName = request.getParameter("name");

    Connection con = ... String query = "SELECT * FROM t_user WHERE name = '" + userName + "'"; con.execute (query); 以上代码段将⽤户输⼊的⽤户名作为 SQL 查询语句的条件 参数,在正常的⽤户名输⼊下,该查询将正确返回结果。 但当恶意⽤户能够完全控制 userName 的值,如其可设置 userName 的值为 ' OR 1 = 1; -- ,则查询语句变成 SELECT * FROM t_users WHERE name = '' OR 1=1; --' ,将 允许其访问数据库中的所有⽤户信息记录。 修复⽅案:使⽤带占位符的预编译执⾏⽅式的 SQL 语句。 37
  26. 代码注⼊ 代码注⼊通过将恶意代码注⼊到应⽤程序,在应⽤程序的上下⽂中被执 ⾏恶意代码。 在 Java 应⽤程序中主要有两种⽅式可以将 Java 代码注⼊到应⽤程序 中,脚本 API

    和动态 JSP ⽂件包含(include )。如果攻击者能够知道 哪个脚本⽂件将被载⼊(load ),则恶意代码将能够被执⾏造成任意代 码执⾏漏洞。 38
  27. 代码注⼊示例 右侧代码允许⽤户注⼊任意的代码,若其 中 args [0] 参数设置如下,则将允许恶意 ⽤户创建任意⽂件。 hallo'); var fImport

    = new JavaImporter(java.io.File); with(fImport) { var f = new File('new'); f.createNewFile(); } 修复⽅案 写死需要执⾏的命令,或通过⽩名单、预 设命令的⽅式,限制可以执⾏的命令。 39
  28. 命令注⼊示例 String btype = request.getParameter("test"); String cmds[] = {"/bin/bash ","test.sh"+btype};

    System.Runtime.getRuntime().exec(cmds); 这时候如果传 ;rm -rf /* ,等同于 /bin/bash test.sh;rm -rf /* String btype = request.getParameter("inputparam"); String cmds[] = {"/bin/bash ","-c","sh script.sh"+btype}; 此时传⼊的参数是⽤于 bash 执⾏脚本⽂件的,但因为使⽤了 -c 参 数,使后续传⼊的参数⽤于命令执⾏,如果传⼊ ;rm -rf /* , 最后等效 于 /bin/bash –c "sh script.sh;rm -rf /*" 41
  29. 命令注⼊修复⽅案 应尽量避免使⽤ Runtime 和 ProcessBuilder 来执⾏系统命令,可搜索系统是否提供 API 来完成同样的功能,如执⾏删除⽂件 rm /home/www/log.txt

    的命令,可以使⽤ File.delete() 等函数来代替 ⽆法避免执⾏命令时,应当尽可能避免创建 shell 来执⾏系统命令,优先使⽤ Runtime 和 ProcessBuilder 的 字符串数组 String[] cmdarray 的 ⽅法,可⼀定程度上降低命令注⼊ 的产⽣。 最后,可考虑使⽤⽩名单的⽅式,限制可执⾏的命令和允许的参数值,或限制⽤户输⼊ 的所允许字符,如只允许字⺟数组、下划线 private static final Pattern FILTER_PATTERN = Pattern.compile("[0-9A-Za-z_]+"); if (!FILTER_PATTERN.matcher(input).matches()) { // Handle error } 42
  30. 命令注⼊ 附 Java 程序中⽤来执⾏命令的 API 有: Runtime.public Process exec(String command)

    public Process exec(String command, String[] envp) public Process exec(String command, String[] envp, File dir) public Process exec(String[] cmdarray) public Process exec(String[] cmdarray, String[] envp) public Process exec(String[] cmdarray, String[] envp, File dir) System.exec(String str) 参考:Java OS 命令注⼊学习笔记 43
  31. 框架低版本漏洞 在使⽤低版本 struts/spring/hibernate 开发的时候,低版本漏洞通常存 在任意代码执⾏、XSS 漏洞、信息泄露等其他漏洞,可能会因为低版本 漏洞问题导致业务安全问题。 漏洞示例: CVE-2018-1270 :spring-messaging

    远程代码执⾏漏洞分析预警 Apache 服务器存在⾼危提权漏洞,请升级⾄最新版本 2.4.39 修复⽅案:使⽤稳定的⾼版本框架进⾏开发,并密切关注该版本的漏洞 问题、漏洞修复规避⽅法。避免使⽤存在已知问题的低版本。 44
  32. 整数溢出漏洞示例 public void update(byte[] b, int off, int len) {

    if (b == null) { throw new NullPointerException(); } if (off < 0 || len < 0 || off + len > b.length) { throw new ArrayIndexOutOfBoundsException(); } crc = updateBytes(crc, b, off, len); } 以上示例中,判断语句 offset + len > b.length 可能导致 offset + len 过⼤⽽溢出,从⽽不满⾜该条件,继续往下正常执⾏,可 能导致访问⾮法内存。将其改为 off > b.length – len 有效避免了整数 溢出问题。 47
  33. 其他 XXE ,构造恶意的 XML 内容,进⾏读取任意⽂件、执⾏系统命令、探测内⽹端⼝、攻 击内⽹⽹站等攻击。 SSRF (Server Side Request

    Forgery ,服务端请求伪造),通常针对外部⽹络⽆法直 接访问的内部系统。 模版注⼊,攻击者控制要呈现的模板,注⼊可暴露上下⽂数据,甚⾄在服务器上运⾏ 任意命令的表达式。 Xpath 注⼊,利⽤恶意的 XPath 查询代码,以获得某些信息的访问权并更改这些信 息。 Web Cache 欺骗攻击 URL 重定向 配置安全 逻辑漏洞 / 业务漏洞 48
  34. 安全资讯: https://www.freebuf.com/ https://www.anquanke.com/ https://www.sec-wiki.com/ https://bbs.pediy.com/ https://pivotal.io/security/ 安全学习: OWASP (Open Web

    Application Security Project ) https://websec.readthedocs.io/zh/latest/index.html Java 中常⻅的安全漏洞与规避⽅法 XSS 防御 防御 XSS 跨站脚本攻击 49