原文作者:Teo Selenius(已授权)
译者 & 校正:HelloGitHub-小熊熊 & 卤蛋
对付开拓者而言,网络安全的主要性不言而喻。任何一处代码缺点、一个依赖项漏洞或是数据库的端口暴露到公网,都会有可能直接送你上热搜。

那么,哪里可以找到详细的避雷指引呢?OWASP's top 10 清单太短了,而且它更关注的是漏洞罗列,而非对预防。比较之下,ASVS 是个很好的列表,但还是知足不了实际需求。
本文这份清单将先容 72 个实操要点,让你全方位保护你的 Web 运用程序。各位看官,准备入坑啦!
众所周知,一个安全的运用须要对浏览器和 Web 做事器之间的所有连接进行加密。此外,建议禁用一些旧的密码套件和协议。利用 HTTPS 时,仅加密网站的“敏感”部分是不足的。如非这样,攻击者可以截获某个未加密的 HTTP 要求,然后假造来自做事器的相应,返回恶意内容。幸运的是,HTTPS 目前是很随意马虎做到的。我们可以通过 Let's Encrypt 免费得到证书,加上 CertBot 免费续期。
连续我们的清单,下一个是 HSTS 它与 HTTPS 密切干系。
2、利用 HSTS 和预加载来保护用户免受 SSL 剥离攻击做事器可以用 HSTS 或 Strict Transport Security header 来逼迫进行加密连接。它表示须要一贯利用 HTTPS 连接访问网站。
HSTS 可以防止 SSL 剥离攻击。所谓的 SSL 剥离攻击也便是:网络上的攻击者截获浏览器发出的第一个 HTTP 要求(常日是未加密的),并立即假造对该要求的回答,假装是做事器并将连接降级为明文 HTTP。
值得把稳的是,HSTS 仅在用户至少成功访问了一次运用程序的情形下才能生效。为了战胜这个限定,可以把我们的网站提交到 https://hstspreload.org ,这样,各浏览器便可以将我们的域名通过硬编码写入到 HSTS 列表中。
如下:
Strict-Transport-Security:max-age=63072000;includeSubDomains;preload
警告:
在履行 HSTS 时,将会逼迫进出该网站的所有网络要求均被加密,如果网站要求中仍旧有纯文本,可能无法访问。以是,先设置一个小的 max-age 参数进行调试,如果统统正常事情,再加大这个值。调试成功后再加上预加载 (preload) ,把开启预加载保留在末了一步,由于关闭它是件很麻烦和痛楚的事情。
3、设置安全 Cookie,保护用户免受网络攻击给 Cookie 加上 Secure 属性。此属性将防止 Cookie 在(意外或逼迫的)未加密的连接中泄露。
Set-Cookie:foo=bar;...otheroptions...Secure
4、安全天生 HTML 以避免 XSS 漏洞
要避免 XSS(跨站点脚本)漏洞,可以采取下面两种方法:
完备静态的网站(例如 JavaScript SPA + 后端API)。避免天生 HTML 问题的最有效方法是根本不天生HTML,如前述方法,当然,也可以试试很酷的 NexJS。模板引擎。针对传统的 Web 运用程序,个中的 HTML 大多是在后端做事器上根据供应参数动态天生的。这种情形下,不要通过字符串连接来创建 HTML 。推举的做法是利用模板引擎,比如 PHP 措辞的 Twig、Java 措辞的 Thymeleaf、Python 措辞的 Jinja2 等等。此外,务必要精确配置模板引擎,从而可以自动对参数进行编码,并且不要利用任何可以绕过这种编码的“不屈安”函数。不要把 HTML 放在回调函数、属性(不带引号)或 href/src 等诸如此类的地方。
5、安全利用 JavaScript 以避免 XSS 漏洞要避免 JavaScript 真个 XSS(跨站点脚本)漏洞,切忌将不受信赖的数据通报到可实行代码的函数或属性中。这类常见的函数或属性包括:
eval、setTimeout、setInterval 等。innerHTML,React's dangerouslySetInnerHTML 等。onClick、onMouseEnter、onError 等。href、src 等。location, location.href 等。6、沙箱处理不可信内容,避免 XSS 漏洞最好是能避免不可信的内容,但每每又不能完备避免:例如须要从远程获取 HTML 进行展示,或者须要许可用户用所见即所得的编辑器写文章,等等。
要避免这些场景中的 XSS(跨站点脚本)漏洞,请首先利用 DOMPurify 清理内容,然后在沙箱中进行内容呈现。
纵然所见即所得的编辑库声称从 HTML 中移除了恶意内容,仍旧可以通过重新净化和沙箱来处理,进一步确保安全。
还有一种常见的情形是,我们想在网页展示广告等内容。这种情形下大略采取 IFrame 是不足的,由于 same-origin 策略会许可跨域的 frame 将父级 frame (也便是我们的网站)的 URL 修正为一个钓鱼网站。因此,要记住利用 IFrame 的沙箱属性来避免此种情形的发生。
7、采取内容安全策略,避免 XSS 漏洞内容安全策略(CSP)可以很好地防御 XSS(跨站点脚本)攻击、点击挟制攻击等。以是,一定要用它!
默认情形下,CSP 会阻挡险些所有的危险操作,以是额外的配置越少越好。如下:
Content-Security-Policy:default-src'self';form-action'self';object-src'none'
它许可从 Web 运用程序的源代码加载脚本、样式、图像、字体等,但不许可加载其他内容。最值得把稳的是,它将阻挡内联脚本()的运行,从而更好地预防 XSS 漏洞。
此外,form-action:'self' 指令可防止在网站上创建恶意 HTML 表单(比如“您的会话已过期,请在此处输入密码”类似的表单),并将其提交到攻击者的做事器。
无论如何,都不要指定 script-src: unsafe inline ,一旦这样做,CSP 将形同虚设。
末了,如果你担心 CSP 会影响生产环境,可以先以 Report-Only 模式进行支配:
Content-Security-Policy-Report-Only:default-src'self';form-action'self'
8、设置 HttpOnly 的 Cookie,保护用户免受 XSS 攻击
为 Cookie 设置 HttpOnly 属性,可以防止 Cookie 被 JavaScript 代码访问。一旦跨脚本攻击发生,该设置也会让黑客更难盗取到 Cookie 信息。当然,有些须要被 JavaScript 代码访问的 Cookie,就不能做这个设置了。
Set-Cookie:foo=bar;...otheroptions...HttpOnly
9、针对下载功能,合理设置避免 XSS 漏洞
向用户供应下载功能时,在 header 中设置 Content-Disposition: attachment,从而避免 XSS 漏洞。该设置将禁止在用户浏览器直接渲染文件,从而避免 HTML 或 SVG 格式的下载文件可能引发的漏洞。如下:
Content-Disposition:attachment;filename="document.pdf"
如果我们想许可特定的文件(如 pdf)能在浏览器端打开,并且也确定这样是安全的,那么,可以针对该类型文件,将 header 省略掉或是将 attachment 换为 inline。
10、针对 API 相应,合理设置避免 XSS 漏洞反射型文件下载(RFD)攻击每每通过构建一个 URL 从 API 下载一个恶意文件来实现。针对该类漏洞,可采取在 API HTTP 相应中返回带有安全文件名的 Content-Disposition header来防御。
11、利用现有平台的反跨站要求假造(CSRF)机制,避免 CSRF 漏洞为避免反跨站要求假造漏洞,务必确保我们所采取的平台开启了反跨站要求假造功能,并确保该配置发挥了应有的浸染。
12、验证 OAuth 身份认证的 state 参数,避免 CSRF 漏洞有一类与 OAuth 身份认证干系的跨站要求假造漏洞是黑客让用户不经意间采取其账户进行登录。因此,如果有利用 OAuth 身份认证,务必确保对状态(state)参数的验证。
13、精确利用 HTTP 协议,避免 CSRF 漏洞除了 POST、PUT、PATCH、DELETE 以外,不要利用其它 HTTP 方法进行数据变动。GET 要求一样平常是不包含在反跨站要求假造机制中的。
14、为 Cookie 设置同源属性,避免 CSRF、XS-leak、XSS 漏洞为 Cookie 设置 SameSite 属性。SameSite 能防止大多数的跨站点要求假造攻击,而且还可以防止许多跨站点泄露的漏洞。
SameSite 属性有两种模式:宽松(lax)和严格(strict)。
宽松模式可以防止大多数跨站点计时和跨站点要求假造攻击,但对基于 Get 要求的跨站点要求假造漏洞无效。如下:
Set-Cookie:foo=bar;...otheroptions...SameSite=Lax
严格模式则可以防止该类基于 Get 要求的漏洞,以及反射型的跨站点脚本漏洞。然而,严格模式不适宜常规的运用程序,由于它会中断身份验证链接。如果用户已登录某个网站,现在要在新的页面打开指向该运用程序的链接,则打开的新页面将不会为该用户自动登录。由于严格模式的限定,会话 Cookie 也不会随要求一起发送。严格模式设置如下:
Set-Cookie:foo=bar;...otheroptions...SameSite=Strict
15、每次登录创建一个新的会话 ID,防止会话固定攻击
会话固定攻击一样平常是在以下环境发生:
攻击者将 Cookie(例如 JSESSIONID=ABC123)注入到用户的浏览器中。不用担心,攻击者有很多方法可以做到这一点。用户利用其凭据登录,并在登录要求中提交攻击者设置的 JSESSIONID=ABC123 。运用程序对 Cookie 和用户进行身份验证。与此同时,拥有该 Cookie 的攻击者也就可以通过该用户的身份进行登录了。为了防止涌现这种情形,程序中须要在身份验证通过后,创建一个新的会话 ID 返回给用户,而不是验证可能被动了手脚的 Cookie。
16、合理命名 Cookie,防止会话固定攻击难道 Cookie 命名也能影响到网络运用程序的安全性?确实如此!
将 Cookie 采取 __Host- 的形式来命名,浏览器将:
该项设置示例如下:
Set-Cookie:__Host-foo=bar...otheroptions...
17、设置 Cache-Control header,防止用户信息被盗取
缓存是将访问过的网站、下载过的文件全部存储在硬盘的某个位置,直到有人手动删除它们。默认情形下,浏览器会对页面的统统内容进行缓存,从而加快访问速率、节约网络带宽。
要在公共网络环境担保信息安全,我们须要将所有 HTTP 相应设置一个得当的 Cache-Control header,特殊是针对非公开的和动态的内容。
该项设置示例如下:
Cache-Control:no-store,max-age=0
18、设置 Clear-Site-Data header,防止用户信息被盗取
其余一个可以有效担保用户退出后记录即被打消的 header 是 Clear-Site-Data 。当用户退出登录时,可以在 HTTP 要求中携带该 header。浏览器会打消该域名下的缓存、Cookie、存储以及实行高下文。大部分浏览器都支持该 header。
该项设置示例如下:
Clear-Site-Data:""
19、妥当地处理“退出”,防止用户信息被盗取
用户退出登录后,务必要对访问令牌和会话识别码进行失落效处理。这样,纵然攻击者从访问历史/缓存/内存等地方获取到这些信息,它们也不再有效。
此外,如果有单点登录,牢记要调用单点登录的退出端口。否则,由于单点登录会话仍处于生动状态,此时的退出将会无效,只要用户再次点击“登录”,即可自动登录。
末了,清理掉你可能用到过的 Cookie、HTML5 存储等。上面提到的 Clear-Site-Data 还未被某些浏览器支持,以是最好还是手工打消一下。
20、针对 JavaScript 密码采取 SessionStorage,防止用户信息被后来者盗取SessionStorage 类似于 LocalStorage,但对每个标签页都是独占的,而且在浏览器/标签页关闭往后将自动打消。
把稳:如果要在系统内打开的多个标签页之间同步用户的授权信息,那就须要用事宜来同步 sessionStorage 信息。
21、不要通过 URL 传输敏感信息URL 设计的初衷就不是为了传输敏感信息。它会被显示在屏幕上,存储到浏览器历史记录,也随意马虎随 referrer header 而泄露,被记录在做事器日志等。以是,切忌在 URL 中通报敏感信息。
22、采取 Referrer 策略,防止 URL 地址透露默认情形下,当从系统中链接到一个外部网站时,浏览器会设置一个 Referrer 的 header 来见告该网站这次访问的来源。这个 header 包含了全体 URL 地址,这可能就涉及到一点隐私。
可以在 HTTP 相应中设置一个 Referrer-Policy 的 header 来禁止该默认行为:
Referrer-Policy:no-referrer
23、为运用设置独立域名,防止同源运用相互滋扰
如果我们这样设置运用域名:https://www.example.com/app1/ 和 https://www.example.com/app2/,是非常危险的。由于浏览器会认为它们是同源运用,也便是同样的做事主机、端口和模式。正由于是同源运用,它们将对彼此有完备的访问权限。任何影响个中一个的漏洞都会同样影响到其余一个。
因此,我们须要给每个运用一个独立的域名。以是,这种情形下该当设置为:https://app1.example.com/ 和 https://app2.example.com/
把稳:位于同一个域名下的子域名是可以为全体域名设置 Cookie 的。例如 app1.example.com 可以为 example.com 设置 Cookie,而这个 Cookie 也将适用于 app2.example.com。许可为一个站点设置 Cookie 有时会给会话固定等类型的漏洞以可乘之机。公共后缀列表可以用来应对该问题。此外,也可以通过将 Cookie 命名为 __Host- 来防止其被子域名所覆盖。
24、谨慎采取 CORS(跨域资源共享)浏览器的安全模型大部分是依赖于同源策略,它可以防止运用的跨域读取。而 CORS(跨域资源共享)则是一种许可网站进行跨域资源访问的手段。以是,决定利用它之前,最好先搞清楚自己是否真的须要。
25、限定要求来源如果你在 api.example.com 的做事须要被来自 www.example.com 的 GET 要求访问,那么可以在 api.example.com 做事上指定如下header:
Access-Control-Allow-Origin:https://www.example.com
如果你有个公开的做事接口(比如说一个供应给互联网上 JavaScript 客户端利用的打算器做事),那么你可以指定一个随机的来源:
Access-Control-Allow-Origin:
如果你只想让有限的几个域名访问它,那么可以在程序中读取要求的 Origin header,进行比对后处理。不过,建议利用现成的库来操作,不要徒手撸,很随意马虎出错。
26、谨慎利用 allow credentials 选项默认情形下,跨域资源共享是不带用户凭据的。但如果在 Web 做事器端指定如下 header,则将许可携带:
Access-Control-Allow-Origin:https://www.example.comAccess-Control-Allow-Credentials:true
这对 header 组合相称危险。由于它会使跨域访问具备已登任命户的权限,并利用该权限来访问网站资源。以是,如果你不得不该用它,务必小心为上。
27、对 HTTP method 进行验证仅许可所须要的 HTTP 方法,从而最小化攻击面。
Access-Control-Allow-Methods:GET
28、合理利用 WebSockets, 避免反跨站要求假造等漏洞
WebSockets 迄今还是比较新的技能,技能文档较少利用它难免会有些风险。以是,采取时务必要做到以下几点:
对连接进行加密就像我们该当用 https:// 而非 http:// 采取 WebSockets 时也要利用 wss:// 而非 ws://HSTS 也会影响 WebSockets ,它会自动将非加密的 WebSocket 连接升级到 wss://
对连接进行鉴权如果利用的是基于 Cookie 的鉴权机制,且 WebSocket 做事器与运用做事器在同一个域名下,那就可以在 WebSocket 中连续利用已有的会话。不过牢记要对要求源进行验证!如果不是基于 Cookie ,可以在系统中创建一个单次利用、有韶光限定并与用户 IP 绑定的授权令牌,用该令牌对 WebSocket 进行授权。对连接源进行确认理解 WebSockets 的一个关键点在于要知道同源策略对其是无效的。任何一个能与你的系统建立 WebSocket 连接的网站,在利用 Cookie 鉴权的时候,都是可以直接得到用户信息的。因此,在 WebSocket 握手时,必须要确认连接源。可以通过验证要求头中的 Origin 参数来确认。
如果想要做到双重保险,可以采取反跨站要求假造令牌作为 URL 参数。但针对每个任务则须要创建一次性的独立令牌,而不要直策应用反跨站要求假造令牌,由于后者紧张是用来为运用的其它部分供应安全保障的。
29、采取 U2F 令牌或客户端证书,保护系统关键用户免受钓鱼攻击如果系统可能会面临钓鱼攻击的威胁,说人话也便是,“如果存在这样的可能性:攻击者创建一个假的网站,骗取管理员/CEO 或其它用户的信赖,从而盗取其用户名、密码和验证码”,那么就该当利用 U2F 令牌或客户端证书来防止这种攻击,这样的话纵然攻击者有了用户名、密码和验证码也无法得逞。
备注:强调钓鱼防护对付一样平常用户而言每每会带来不必要的麻烦。然而,供应多一种可选项对终端用户而言也非坏事。此外,向用户提前奉告钓鱼攻击的危险也是非常必要的。
30、针对跨站点透露进行保护跨站点透露是一系列浏览器边信道攻击。这种攻击使恶意网站可以从其它 Web 运用程序的用户中推测出信息。
这种攻击存在已有时日,但是浏览器端却是最近才开始添加针对性的预防机制。可以在 这篇文章 中理解关于该类攻击的更多细节以及该当采纳的安全掌握方法。
二、做事器真个威胁防御其次,是做事器真个威胁防御,这里从运用系统、根本举动步伐、运用架构、运用监控、事宜相应平分歧侧面,归纳了如下建议:
2.1 运用系统31、对用户输入进行合法性验证该类别的方法中最关键的一点便是尽可能严格地对所有用户输入进行合法性验证。适当的验证会使系统漏洞更难被创造和利用。对不合法的用户输入直接谢绝,而不要考试测验去洗濯。验证方面包括如下:
采取严格的数据类型。针对日期采取 DataTime 类型,数字采取 Integer 类型等等。针对有固定可选项的情形采取列举类型。只管即便避免采取字符串类型。如果必须采取字符串,至少给一个长度限定。如果必须采取字符串,将可输入的字符集尽可能地减少。如果要处理 JSON,利用 JSON 模式进行验证。如果要处理 XML,利用 XML 模式进行验证。32、非常处理优雅化,避免技能细节透露对终端用户不要显示堆栈记录或类似的调试信息。采取全局的非常处理器对非常进行处理,展现给浏览器端大略的缺点信息。这样会使攻击者更难创造和利用系统中的漏洞。
33、不要自己做鉴权对用户进行鉴权时可能会涌现各种各样的问题:要抵御密码猜想攻击、用户列举攻击,要管理密码重置、存储用户凭据,样样都不随意马虎。就像密码处理一样繁芜,我们普通人还是不要考试测验了。
直策应用 auth0 等类似的工具来进行身份验证,采取一些广泛利用的、安全的软件模块来实现通信协议(常见的为 OpenID connect)。如果不想用 auth0 这类第三方的身份供应商,也可以自己搭建一个类似 KeyCloak 的做事来代替。
34、对统统都进行鉴权,减少攻击面运用系统要默认对统统都进行鉴权,除非是一些静态资源、非常页面或登出页面。
35、采取多重身份认证万一有人破解了身份认证做事呢?如果存在这种担忧,直接上多重身份认证(说人话也便是:除了密码以外,还须要手机验证码)。这样就算身份认证做事被黑、攻击者可以伪装到任何人,还是无法知道手机收到的验证码。
36、通过严格的权限掌握,避免对数据或功能的未授权访问权限掌握虽不是件随意马虎事,但也有妥善处理的方法:只要时候记住不要在掌握器方法中忘了对用户权限进行验证,从而带来用户越权的漏洞,包括:
不要默认对所有掌握器方法开通访问权限。根据用户角色划分每个掌握器的访问权限。采取方法级别的安全掌握,限定对做事方法的访问权限。采取集中化的权限管理工具,防止对每条记录的非授权访问。采取前端 Web 运用和后台 API 结合的架构,对每个 App 和 API 均采纳权限掌握,而不仅是对与互联网连接的部分进行掌握。为了进一步澄清权限管理工具,这里总结了一些要点:
数据记录要有可以进行权限掌握的字段,比如 int ownerId。被授权的用户要有一个 ID。要有一个类可用来进行权限评估,在数据记录的 ownerId 与 用户的 ID 相匹配时,能判断出用户具有对应的访问权限。在以上根本上,可以将权限评估类集成到运用平台的权限掌握系统中,比如 Spring Security 产品的 PreAuthorize、PostAuthorize 等等。如果须要更繁芜的权限掌握,也可以搭建一个完善的 ACL 系统。37、采取得当的工具和技能,避免注入漏洞注入类的漏洞有很多,而且都很相似,包括 SQL 注入、HTML 注入、XML 注入、XPath 注入、命令注入、SMTP 注入、相应 header 注入等等。名称不同但实质相同,相应地办理方法也类似:
问题缘故原由:利用字符串拼接,来构建特定协议下的参数化。办理方案:采取得当的、安全的、现成的工具来实现这项任务。这里不会深入太多细节,只要记住:不管你是什么协议,都服膺上面这点。后面会列举一些常见的注入类漏洞。
38、创建安全的数据库查询语句,避免 SQL 注入漏洞如果要避免 SQL 注入漏洞,那就记住绝不要自己用字符串拼接 SQL 查询语句。采取一个工具关系映射框架(ORM)来实现,可以让开发更高效、运用更安全。
如果想要构建更细粒度的查询,可以利用更底层一点的 ORM。
如果不能利用 ORM,那就考试测验预处理语句,但也要小心这类语句会比 ORM 更随意马虎涌现缺点。
警告:
ORM 框架也不是万能的,表示在两方面:一是,它对原生的 SQL 查询还是支持的,最好不要利用这类查询;二是,像其它任何软件一样,ORM 框架也会时时时被曝出漏洞。以是,还是遵照我们一而再再而三强调的策略:对所有输入进行验证,采取网络运用程序防火墙(WAF),并保持软件包的更新,这样基本就可以放心了。
39、谨慎利用操作系统的命令行,防止命令注入的干系漏洞如果可以避免,最好不要实行操作系统命令。如果不能避免,那最好遵照以下准则:
采取得当的库/方法来构建命令及其参数。参数必须是 list 类型。不要用单独字符串来创建命令。不用利用 shell 来调用命令。预定义好命令参数。比如 curl,如果许可用户通过 -o 来指定参数,那么攻击者就有机会写入到本地文件系统。理解程序如何实行,并相应地对参数进行验证。再比如 curl,你可能只是想让用户可以拉取某个网站的内容,但如果他拉取了 file:///etc/passwd,那就危险了。想清楚再行动。在上面的例子中,就算验证了访问地址因此 http:// 或 https:// 开头,攻击者也可以发起以这两类协议开头的攻击,如:http://192.168.0.1/internal_sensitive_service/admin。再强调一遍:真得要想清楚了再行动。就算你对 DNS 进行验证,确保命令中不含敏感内网地址,你有去禁止将特定 DNS 记录映射到 192.168.0.1 吗?如果答案是否,那就危险了。40、合理配置 XML 解析器,避免 XML 漏洞作为一种标记措辞,XML 的危险性表示在它可以访问系统资源。XSLT 的一些实现乃至支持嵌入代码。因此,在处理时必须非常谨慎。
如果可以,避免接管来自不受信赖源的 XML/XSLT。如果要向 XML、XSLT 或 XPath 传参,记住要利用安全的软件组件,而不要利用字符串连接/格式化的办法。利用主流、安全的软件组件来解析 XML/XSLT。不要利用缺点的库或代码来处理 XML。此外,在任何情形下,都不要试图去徒手撸一个解析器(比如 SAML),非常随意马虎出错。精确配置解析器:禁用 XSLT 文档、禁用 xinclude、禁用文档类型定义、禁用外部实体,启用 DOS 保护。详细配置在实现时会有所不同,但务必对所选择的解析器进行深入的研究。41、采取得当的类构建URL,避免 URL 注入漏洞URL 注入常常会在以下情形发生:
flavour=request.getParam("flavour");url="https:/api.local/pizzas/"+flavour+"/";returnget(url).json();
如果 flavour 被设置为:
../admin/all-the-sensitive-things/
那么这个 API 要求将会变为 https://api.local/admin/all-the-sensitive-things/,是不是很凶险?
办理方案依然是采取得当的 URL 构建库来为 URL 传参,从而能精确地对参数进行编码。
42、采取得当的类构建路径,避免路径遍历漏洞就像 URL 地址一样,如果攻击者设法在路径中的某个地方偷偷地插入 ../../../ ,文件路径可能终极指向猜想之外的位置。要避免这种情形,请创建一个类,采取这个类安全地布局路径,并验证终极路径是否在预期目录中。避免在文件路径中利用不受信赖的数据,或者更好的是,完备避免利用文件系统,直接采取云存储。
43、谨慎采取文件系统,吸收不受信赖的内容如果许可用户写入做事器的文件系统,可能会涌现各种各样的问题。改用云存储,或者在数据库中利用二进制 blob。
如果您必须访问磁盘,则应遵照以下辅导原则:
不要让不受信赖的数据影响内部文件路径。将文件保存在阔别 webroot 的隔离目录中。在写入磁盘之前,请验证文件内容是否与预期格式匹配。精确设置文件系统权限以防止写入不须要的位置。不要提取压缩包(例如 ZIP),由于它们可以包含任何文件,包括指向系统任意地方的链接和路径。44、不要动态实行代码,避免远程代码实行漏洞不要利用 eval 或等效函数。找到一种其它的方法来实当代码实行。否则,不受信赖的数据将有可能进行函数调用,从而在有机会在做事器上实行恶意代码。
45、合理采取序列化,避免反序列化漏洞对不受信赖的数据进行反序列化是很危险的,很随意马虎导致远程代码实行。
如果可以避免,不要利用序列化。如果可以在做事器端序列化工具,则对其进行数字署名。当须要再次反序列化它们时,请在连续反序列化之前验证署名。利用一些主流的软件组件,并保持更新。许多反序列化库会一贯被创造漏洞。GSon 是个不错的选择。利用大略的文本格式,如 JSON,而不是二进制格式。此外,该当避免像XML这样有问题的格式,由于这样除了反序列化之外,还须要担心 XML 漏洞。在处理序列化工具之前验证它。例如:对付 JSON,在连续反序列化之前,根据严格的 JSON 模式验证 JSON 文档。2.2 根本举动步伐46、采取网络运用程序防火墙(WAF)安装防火墙,会减少很多风险。ModSecurity 便是一个很好的开源选择。
47、配置 Web 做事器,避免 HTTP desync 攻击HTTP desync,也称 HTTP 要求走私攻击,是指攻击者挟制随机用户向系统发出的 HTTP 要求。这类攻击一样平常在以下情形下发生:
前端做事器,比如负载均衡器或反向代理做事器,接管携带有 Content-length、Transfer-Encoding 等头部参数的要求时,将要求未经处理随即通报到后台;后台接管该要求的做事器(常日是运用做事器),采取(或被欺骗采取)一个不同于前端做事器的机制来确定 HTTP 要求从何处开始、何处结束,比如前端做事器利用 Content-Length,而运用做事器采取 Transfer-Encoding;前端做事看重复利用与后端做事器的连接;前端做事器在与后台做事器连接时采取 HTTP/1(而非 HTTP/2)。那么该如何进行戒备呢?一样平常是根据所采取的产品:
咨询所采取的反向代理产品供应商,确保该产品具备主动戒备攻击的能力;配置前端做事器,在与后台连接时采取 HTTP/2;配置前端做事器,防止利用同一个连接发送多个客户真个 HTTP 要求;采取网络运用程序防火墙(WAF),并确保其具备防止要求走私的模块。48、采取容器让目标运用隔离其他运用来运行。这样,纵然发生了攻击事宜,攻击者也不会有权限去访问未经容许的文件、系统或网络资源。因此,最好利用 Kubernetes 或一个云端环境来支配你的运用。如果由于某种缘故原由必须利用一台做事器,那么可以手动采取 Docker 来约束运用。
49、利用 SELinux/AppArmor纵然通过容器来运行运用,也还是须要进一步采取 SELinux 或 AppArmor 策略来进一步地对运用做出约束,从而减少容器漏洞引发的威胁。
50、采取最少权限的做事账户这种方法带来的好处是纵然发生了被攻击事宜,也能减少被攻击造成的丢失。再次重申,列出所有的环境是不可能的,这里仅列举一些例子帮助大家理解:
纵然利用了 Docker,乃至是利用了 SELinux/AppArmor,不要用 root 账户来运行你的运用。为你的运用单独创建一个具备尽可能少的权限的账户,从而降落攻击者利用容器或内核漏洞等进行攻击的可能性;如果有利用数据库,确保运用程序中的数据库用户在访问数据库时具备尽可能少的权限;如果运用中集成了 API,确保运用访问 API 时具备尽可能少的权限。51、限定外部网络连接攻击者常日须要建立一定的反向通信渠道来建立操控渠道或盗取数据。此外,一些漏洞也是须要外部网络连接才会被创造、被利用。
因此,不能让运用随便访问外部网络,包括 DNS。试下在做事器运行命令 nslookup www.example.com,如果运行成功,则解释你没有对外部网络连接做出适当的限定。如何处理此类问题,一样平常则取决于根本举动步伐。
针对外部的 TCP/UDP/ICMP 连接,一样平常可以通过以下办法禁用:
网关防火墙,如果有的话;如果是老式做事器,可以采取本地的防火墙(例如 iptables 或 Windows 防火墙);如果做事器端采取 Docker,可以利用 iptables;如果利用了 Kubernetes,可采取网络策略定义。DNS 处理起来轻微麻烦一点,我们常日须要许可对一些 hosts 的访问。
如果有本地的 hosts 文件,那就很大略,可以采纳上面的任何一种办法来将 DNS 彻底禁用;如果没有,那么你须要在你上游的 DNS 中配置一个私有的区域,在网络层限定仅能访问该指定的 DNS 做事器。这个私有区域内只许可对一些预先指定的 hosts 的访问。52、跟踪 DNS 记录,防止子域名挟制子域名挟制发生场景举例如下:
如果我们拥有一个域名 example.com;针对一次匆匆销活动,我们买了另一个域名 www.my-cool-campaign.com ,然后创建了一个别名从 campaign.example.com 映射到 www.my-cool-campaign.com;这次匆匆销活动结束后,www.my-cool-campaign.com 域名也到期了;但是,从 campaign.example.com 到 www.my-cool-campaign.com 的别名映射仍存在;如果有人购买了这个到期的域名,那么 campaign.example.com 便可以直接指向该域名;如果攻击者在 www.my-cool-campaign.com 域名下供应一些恶意内容,那么便可以通过 https://campaign.example.com 域名直接访问到;因此,须要随时留神你的 DNS 记录。如果须要处理的类似情形较多,强烈建议你做一个自动监控方案。
2.3 架构53、创建内部 API 用来访问数据源对连接互联网的网络运用程序不应该太过于信赖。例如,不应许可它进行数据库直连。否则,当有人攻破运用程序时,全体数据库都将面临威胁。
相反,我们该当搭建多组件组成的架构,例如:
我们域名为 www.example.com 的运用程序利用 auth0 进行鉴权。该运用程序访问内部 API 做事 api.example.local 时,携带被授权用户的 token,放在要求头部的 Authorization 中。位于 api.example.local 的 API 做事根据用户的 token 进行访问限定,进而根据被付与的权限读写数据库。如果现在有黑客想要攻破我们的运用程序,纵然成功,他也没有权限访问全体数据库,而只是利用某个用户的 token,进而访问该 token 所许可访问的那部分数据。
54、内部连接也需加密和验证不要盲目相信内网的安全性,有很多方法可以攻破它。对付系统间的访问,全部采取 TLS(也便是 HTTPS)进行加密,最好在网络和系统两个层次对连接进行鉴权。
55、对敏感信息集中管理如果没有采取得当的敏感信息管理方案,就很难保持授权的短期性化、可审计性和秘密性。因此,建议采取 HashiCorp Vault 一类的工具来集中管理密码、加密 key 等类似信息。
2.4 监控56、网络,剖析,报警集中网络日志到一个独立系统,比如 SIEM(安全信息和事宜监控系统)。在这个别系中,可以在一些表征薄弱性、攻击的事宜发生时进行报警。当严重威胁发生时,可以立即关照干系职员。
57、网络系统安全事宜最主要的日志来源可能便是系统自身了。当有可疑行为发生时,系统应能引发非常,记录事宜,可能的话,乃至可以自动封锁可能带来问题的用户或IP地址。常见可疑行为包括:
输入值的合法性验证缺点(例如,试图输入 UI 中不可能供应的值)访问掌握缺点 (例如,考试测验访问一条在 UI 中不可能涌现的记录)数据库语法缺点表示某个人创造了一处 SQL 注入的薄弱性,这时候可要动作快点采纳行动了XML 缺点表示某个人创造了一处 XML 注入的薄弱性,或者正考试测验利用 XXE(XML 外部实体)薄弱性进行攻击缺点要求表示用户可能发送了被运用谢绝的要求。Spring 框架的 RequstRejectedException 便是一个例子反跨站要求假造令牌验证缺点一样平常表示有人正考试测验探求系统中存在的薄弱性58、网络运行时安全日志利用运行时安全监控工具如 Falco 来对非常系统访问进行检测。如果采取了 Kubernetes,那么 Falco 就特殊有用。远程也可以对日志进行网络和监控。
59、网络 SELinux/AppArmor 日志如果我们制订了 SELinux 策略防止向外部的连接,但系统忽然向外部某个网站(例如 burpcollaborator.net)发起 HTTP 要求,那就须要急速引起关注。又或者你的系统考试测验访问 /etc/passwd。这两种情形都表示有人已经创造了我们系统中的漏洞。
60、网络 Web 做事器事宜对 Web 做事器软件,至少要对访问日志和缺点日志进行网络,网络后发送到集中式的日志做事器。在突发事宜相应时,这将赞助我们快速理清韶光线。
61、网络网络运用程序防火墙(WAF)日志如果你像上文推举利用了网络运用程序防火墙(WAF),那么也对这个日志进行网络。但不用针对这个日志设置报警,由于它基本上会收到来自互联网各种各样的问题,而且不部分是你不用担心的。
2.5 事宜相应62、制订应对操持一旦对我们的系统进行了监控和加固,攻击者将难以快速定位系统漏洞,纵然终极创造,我们也能快速理解情形。
但仅理解情形是不足的,还须要做出如下准备:
快速剖析系统日志,理解当前状况和需采纳的对应方法在运用防火墙等产品中,快速对个别 url 地址和参数做出限定如有须要,快速关停系统2.6 开拓管理
63、威胁模型系统地考虑一下“可能会涌现哪些问题”并据此做出调度。设计一个新的系统时,越早开始这一步越好。当对系统发生改变时,再重新梳理一遍这个过程。
例如:
小王:如果攻击者攻破了我们连接了互联网的做事器,怎么办?
小陈:那可就塌台了!
小王:好吧!
这就解释我们在这里存在着一个信赖关系,我们认为连接了互联网的做事器是不会被攻破的。我们可以信赖这一点吗?
小陈:未必吧!
有一百种可能导致我们的做事器被黑掉,例如我们代码中存在的薄弱性,或者依赖中存在的薄弱性,或者是我们 Web 做事器所安装软件的薄弱性。
小王:好吧!
那就让我们冲破这层信赖关系。接下来该做些什么呢?
小陈:我们这样来分解一下系统:创建一些内部的接口用来实际访问数据库,由此以来,前真个 Web 做事器就不能直接访问后台的所有东西。
小王:这是个好办法!
除此以外,还有其它什么可能出问题呢?
小陈:嗯,如果黑客攻破了我们的内网呢?
小王:那所有东西都要丢失了,由于内网里做事器之间的连接都是未加密的。
小陈:……
这便是威胁模型,它不须要多么繁芜。利用这种办法,来找出系统中可能存在的威胁。
64、源代码逼迫审查通过技能掌握手段,防止代码未经他人审核便提交入库。这是构建安全开拓环境的根本,由于它可以做到:
如果攻击者攻陷了一个开拓职员的电脑,或者是开拓职员自身企图发起攻击,将不能直接将恶意代码迁入代码库;如果开拓职员的缺点导致引入了有漏洞的代码,很可能在被其他人检讨时及时创造。65、自动化持续集成管道,仅许可大略访问开拓职员该当有权限触发 Jenkins 构建,且 Jenkins 权限配置也仅该如此,不要再许可其它权限。单个开拓职员该当不能在构建阶段引入任意代码。当然,如果像上文推举的逼迫性地采取了代码审查,Jenkinsfile 也可以保存在版本管理工具中。
66、对 artifacts 进行署名如果是构建容器镜像,可以把对镜像署名作为构建的一步。将署名密钥存储在安全的地方。构建阶段须要访问密钥,但是杜绝将密钥与 Jenkinsfile 一起存储在版本管理工具中。更好的办法是将密钥存储在 HashiCorp Vault 之类的地方,然后在构建时再进行拉取。
67、持续集成管道中加入静态运用程序扫描器在持续集成管道中利用 SpotBugs 和 Find-Sec-Bugs(或者根据你所采取的技能栈进行选择)之类的工具。它们可以帮你在支配代码之前创造已知的漏洞。
此外,也可以作为 IDE 的插件安装在开拓职员的电脑上,在代码迁入之前就运行这些工具进行检讨。
68、构建时对依赖进行检讨,担保最小的依赖集运用程序中依赖的每个软件包都是一个风险来源。通过依赖,我们拉取了第三人的代码并在我们的运用做事器上实行,以是,必须要搞清楚我们依赖的这个软件包是什么,为什么会依赖它?
保持最小的依赖集;仅利用我们所信赖的依赖。它们必须是广泛利用和广为人知的;采取构建框架,对依赖进行确认。此外,严格掌握运用做事器的对外连接,从而避免后门的存在。
69、对依赖进行安全扫描利用 OWASP 依赖检讨工具对依赖中常见的安全问题进行扫描。除了在持续集成管道中,也可以在开拓职员的开拓环境运行这些工具。
70、持续集成管道对镜像进行安全扫描如果采取了容器化技能,可以利用 Trivy 等工具对容器镜像进行一些常规漏洞的扫描。
71、自动化支配和署名验证开拓职员可以有权限莅临盆环境中支配,但是权限范围该当掌握在前阶段已经构建和署名过的特定镜像,而不是直接访问生产做事器。如果是利用 Kubernetes,可以通过 Notary 或开放策略代理来验证待支配镜像的署名。
72、设置一个安全职员一个人的精力是有限的。我们不能期望每个开拓职员都精通渗透测试或是安全工程师。正如你不能期望所有的安全专家都是精良的开拓职员一样。因此,可以在团队中设置一个专门关注安全的职员,紧张与开拓职员、架构师进行互换,帮助保护我们的运用程序并在团队中传播安全意识。
三、结论担保运用程序的安全性,光靠避免漏洞时不足的,必须全面通盘考虑,主动进行防御。这里对一些紧张方法进行了总结:
利用最新版本的的软件组件来实行危险的操作,如身份验证、访问掌握、加密、访问数据库或解析 XML,并确保精确配置了这些组件,例如 XML 解析时禁用外部实体。利用平台供应的安全掌握,例如反跨站要求假造保护。利用 Web 浏览器供应的安全控件,如 HSTS、SameSite Cookie 和内容安全策略。对安全掌握进行集中化处理,特殊是身份验证和访问掌握,从而避免一些遗漏,如在某些掌握器方法上忘却对安全进行掌握。利用 Web 运用程序防火墙,防止运用程序漏洞被创造和被利用。通过限定对文件、网络和系统资源的访问来对运用程序进行限定。利用威胁模型创造架构中的威胁,并相应进行处理。既包括在源代码层面对每个开拓职员的源代码进行安全掌握,也包括在架构层面对前端 Web 做事器的安全掌握。对系统进行监控,制订非常处理预案。在开拓环境和持续集成环境中利用漏洞扫描程序对代码、镜像、依赖进行扫描。对开拓职员、架构师等开展安全培训,并在团队中配备一名安全职员。感谢原作者的翻译授权:
如果你看到末了一定是收成颇丰,这里还有一个收成更多知识的方法,但比读完这篇文章要难得多,加入我们一起变强!
变强之路充满荆棘,以是强者才受人尊敬
HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。