第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定

前端安全:別讓安全防護(hù)從“前端”掉隊(duì)了

作为前端开发者,我们经常觉得安全不是我们的责任。确实,大问题通常由后端解决,但作为前端开发者,我们也需要注意一些特定的安全问题。

最近我参加了一次前端开发岗位的面试,面试中涉及的安全要求比我准备的要深入得多。虽然我对安全问题和缓解方法比较熟悉,但在相关术语和方法上的准备还是不够充分。

这让我意识到,作为前端开发者,我们常常不够重视安全,以及我们在安全上的职责——因此,如果我们做得不到位,我们也脱不了干系。

但我觉得在这里讨论一下这些攻击途径可能很有用,并探讨它们在现代JavaScript为中心的网络中是如何运作的,以及如何减轻或消除这些攻击手段。

跨站脚本漏洞(XSS)

将恶意脚本注入页面并执行,导致触发了未预期的行为。

一个更具体和较长的例子可能是一个消息板或评论区,它会在页面上展示用户的评论,让其他用户看到。如果用户的评论类似以下内容,实际上会在所有用户的屏幕上弹出一个警告。

<script>alert('网站被黑了哦')</script>

这还算温和的例子。运行一些 base64 编码的无意义数据,这种行为更有可能连接到并执行恶意软件文件,后果也更严重。

解决这些问题并不难,其中贯穿以下示例的原则是:永远不要信任用户输入。这意味着永远不要信任用户填写表单的内容——要清理它,并验证它以防止明显的非法操作。另外,不要直接展示用户提交的内容。这一点听起来可能很明显,但许多公司的研讨会曾因一本“留言簿”被改成纳粹宣传或其他更糟糕的内容而受到影响。

除了不直接显示用户的输入之外,始终使用内容显示的安全版本。这始终是默认行为。例如,在React中,使用{messageContent}是安全的,但如果使用<div dangerouslySetInnerHTML={messageContent} />,那就是不安全的。如果你之前不知道这是不安全的,可能值得考虑是否另一个字段更适合你。Vue虽然不那么明确警告,但{{messageContent}}是安全的,而<div v-html="messageContent">则非常不安全。

另一个缓解方法是CSP(内容安全策略)。我们很快会详细讨论这个话题。

说实话,除非你在做一些非常奇怪的事,否则 XSS 已经是一个“已经被解决的问题”。大多数现代工作流程都会在一开始就阻止它。

跨站请求伪造攻击

让使用者不知不觉地发起一个本来没有打算发起的请求。这些攻击利用了真实用户的账号和有效的登录凭证。当你在网站上操作时,浏览器会自动发送 cookie,证明你的身份是合法的。

所以你在 SuperGoodBank.com 最终完成了一个个人贷款产品的申请,用于购买两个《星际战士》模型人偶,然后离开了网站。第二天你去 PrivateerHarbour.com 下载《Bring It On: Fight To The Finish》,却没看到页面中嵌入的图片链接实际上指向了这样一个网址:https://api.supergoodbank.com/api/transactions/transfer&amount=150&destination=666-237884-123&approved=true

你的银行的API会收到那个URL,连同你的cookie一起。所以它会根据这些信息完成相应的交易。

你可能已经注意到,这实际上并不是一个前端的风险。实际上这是一个后端的风险,解决方案包括后端的修改,前端也需要配合。最好的解决方案是使用CSRF令牌。这个令牌会在每个会话中生成,并作为任何表单负载的一部分。没有有效的令牌,就没有有效的请求。

重要的是理解,这些请求及其对应的解决方案是基于表单——application/x-form-urlencodedmultipart-form-data

基于JavaScript的表单发送application/json负载需要遵守不同的规则,但仍可能需要在请求中带上CSRF令牌。通常CORS要求会阻止JavaScript请求携带CSRF令牌。关于这一点,我们也会详细讨论。

大多数缓解措施都是在后端实现的——使用 SameSite 仅限的 cookies,对高风险请求实施 2FA 验证等。但是,作为前端开发者,我们应准备好在请求中根据需要添加必要的头部或字段。

点击劫持

点击劫持攻击与跨站请求伪造攻击类似,但涉及将目标网站嵌入iframe中,诱使用户点击他们看不见的按钮,而实际上他们认为自己是在执行其他操作。例如,我认为自己点击确认在PrivateerHarbour网站上搜索《Bring It On》电影,但实际上,我点击的按钮实际是用来“确认转账”的,我的一大笔钱。

当然,该操作被执行了……你确实有一个有效的cookie,并且你点击了“把所有钱转给骗子的按钮”。

实际的黑客手段包括强迫用户“赞”他们从未见过的 Facebook 内容,或强制确认 PayPal 支付等等。

缓解这个问题并不难。你可以设置一个名为 X-Frame-Options 的 HTTP 头,如果将其设置为 DENY,则应用程序将无法被嵌入或框架化。(如果你有内部使用的需要,可以使用 SAMEORIGIN。)同样的道理适用于 CSP 设置:frame-ancestors ‘none’;。我们稍后会更详细地讨论 CSP,因为我之前提到过。

这已经不是那么常见的向量了,但不常见了,好的解决方案通常需要访问托管或服务器的配置。有一些CSS和JavaScript技巧可以尝试让嵌入的页面至少可见,但这些并不是真正解决问题的办法。

SQL注入攻击(一种常见的安全漏洞)

这也是一个主要在后端的问题,但我们至少可以在前端尝试缓解一下这个问题。最终这涉及到插入一大段SQL代码,希望后端不要太聪明,会不假思索地执行。

当你在某个字段中询问用户的名字时,你可以直接将它插入用户的名字字段,使用这样的命令:UPDATE users SET name = <userData.name> WHERE userID = 123

如果用户把名字设为这种代码:"REKD”; DROP TABLE users;,那么最终的查询就会变成如下所示。

    更新 users 表 SET 名称 = “RKD”; 删除表 users; WHERE 用户ID = 123

最后一部分什么也不做,但第一个部分会有效查询,用来更新每个人的名字。然后,第二个部分也会有效查询,用来彻底删除用户表。

这不太好。

阻止用户这样做其实很简单。任何ORM都会阻止这种行为。甚至底层库也提供了比如说预编译语句这样的功能,这些功能也会对输入进行清理。

作为前端开发人员,你可以至少做一些基本的验证,以防止明显的垃圾信息和/或黑客攻击传入服务器。限制字段为实际会使用的字符集,例如。

CSP(这个经常提到的)也可以帮忙,通过移除那些在有效载荷中变形的向量。

前端存储

客户端本质上是不安全的。这意味着你可能用于存储的任何浏览器API都不可信。这包括localStorage和sessionStorage,这两个存储选项用户都可以看到并且可以修改。一个常见的例子就是在你使用SPA登录时,从后端发送回的JWT。

你读到的任何教程都会告诉你不要将 JWT 存储在本地存储中,但,我们在这次演示中就直接这样做了。

最大的问题在这里与上面提到的向量有关。XSS攻击会检查浏览器API(如localStorage)中是否存在正确的令牌,并将它附加到请求中,从而在后端安全中打开一个巨大的漏洞。

浏览器可以访问的任何 API,恶意脚本也可以访问。例如,这包括 localStorage、sessionStorage,甚至 IndexedDB,它们的数据可能被查看、复制或修改。

所以如何减少这种情况的影响。和其他项目一样,这主要涉及后端,然后将其与前端集成。你需要使用一个HttpOnly cookie。这意味着客户端无法查看cookie的内容,只知道cookie的存在。服务器加载这个cookie,并从中提取JWT等数据,验证它并继续执行授权流程。

中间人拦截攻击:

中间人攻击(MITM攻击)是一类广泛的攻击,在这种攻击中,数据在任何双方之间传输时被拦截或修改——比如用户和网站之间。这可能包括窃取敏感信息,例如会话cookie、JWT令牌或登录详细信息,或篡改交易详情。

存在多种类型的攻击。被动窃听只是监听,主要目的是查看登录凭证。这种攻击在不安全的网络中尤其危险,例如公共Wi-Fi。主动的中间人攻击则会篡改交易内容,例如更改交易接收者。一些形式的中间人攻击会移除SSL安全措施,让用户误以为正在使用HTTPS,但实际上数据是通过明文HTTP传输的。其他版本的攻击会伪造免费Wi-Fi热点或冒充DNS提供商。

如之前所见,有几种方法可以缓解这些问题,但后端承担主要责任。但作为前端应用,也有一些最佳实践可参考。最重要的是,所有应用,包括前端,都应始终使用 https,应始终启用 SSL。

我们之前提到的 HttpOnly cookies 也可以防止中间人攻击(MitM)获取 cookies 及其内容。还有一个 HTTP Strict Transport Security 标头,可以启用它来强制使用 HTTPS,阻止 HTTP 请求。通过将域名提交到 Google HSTS 预加载列表 https://hstspreload.org/,可以对此进行优化,确保任何尝试通过 HTTP 访问您网站的用户在导航之前就会被重定向,从而使第一次访问时的中间人攻击成为不可能。

供应链攻击事件

JavaScript生态系统高度依赖于通过NPM加载的第三方模块。但是没有东西阻止攻击者甚至合法维护者出卖良心后插入恶意代码。

一个例子是2018年发生的event-stream攻击事件,一名黑客获得了npm上的event-stream包的访问权限。他们随后向特定应用程序注入了一个包,该应用程序包含比特币账户信息和私钥,从而导致了未知数量的比特币被盗取。

供应链中还存在其他漏洞。CDNs、CI/CD 管道和被重命名或伪造的依赖项都可能是潜在的风险。

对此的缓解措施都是一样的——谨慎处理依赖关系。一般应避免使用内容分发网络(CDNs)。使用并提交package-lock.jsonyarn.lock等文件可以防止依赖项被隐蔽更改,同样,明确固定依赖项也能起到作用。

前端竞态问题

有时候用户无需修改或拦截请求,甚至不需要访问localStorage,就能做到一些未被预期的操作。只需点击提交按钮两次,或者多次使用同一个50%的折扣码。

这不仅关乎安全,还关乎用户体验。我认为现在已经好很多了,但在互联网的早期,用户经常误以为需要双击按钮。这样的错误不应该导致订购两份相同的超级Sonico哥特式女仆玩偶模型。一份就已经足够了。

最关键的是,提交时要禁用按钮,防止重复提交。Uis 不能单纯依赖用户的输入。这个问题没有通用解决方案,因为它完全取决于具体的 app。不过作为开发者,这一点一定要注意。

大解决方案——

这些缓解策略和解决方案中有一条共同的线索,那就是对服务器的访问。有时这指的是后端API,而在其他情况下,则指的是为前端提供服务的任何基础设施。我们可以实施两种主要解决方案,它们确实很有帮助。内容安全策略(CSP)跨源资源共享(CORS)

CSP,即内容安全策略(CSP)

这将是一个更大范围的讨论,完全可以独立成为一篇文章。CSP 是一个名为 Content-Security-Policy 的特定头部(Header),它规定了该网站允许和不允许的内容。浏览器在加载该域名上的 JavaScript 应用程序时会读取该头部,并根据策略阻止相关活动。

这些头部数据通常都很长。

    Content-Security-Policy:   
     default-src ‘self’;   
     script-src ‘self’ ‘unsafe-inline’ https://cdnjs.cloudflare.com;   
     style-src ‘self’ ‘unsafe-inline’ https://cdnjs.cloudflare.com;   
     img-src ‘self’ data: https://cdnjs.cloudflare.com;   
     font-src ‘self’ https://cdnjs.cloudflare.com;   
     connect-src ‘self’;  
     frame-ancestors ‘none’;  
     upgrade-insecure-requests;

这个示例是一个中等安全设置,做了所有通常的事情,但允许内嵌脚本,并允许来自 Cloudflare CDN 的数据通过,以使我们的 FontAwesome 图标正常工作。其他示例可能包括针对 Google 字体、Google 标签管理器或 Google 分析的例外情况。营销工具通常需要很多这样的例外情况,同样,一些广泛的第三方集成(例如)也是如此。

以上部分内容并不理想或并不完全必要。default-src 是其他策略的后备选项,因此当有 connect-src 时,它实际上可能并不必需。想象一下,如果没有 Cloudflare 的部分,我们可以省略掉大部分规则。

值得注意的是最后两条。frame-ancestors 指令阻止了点击劫持攻击和其他相关的框架利用攻击。upgrade-insecure-requests 指令强制始终使用 https,确保所有连接都是安全和加密的。将 script-src 指令设置为 'self' 可以阻止任何 XSS 错误。我们还可以设置一些更小的指令,例如 object-src 'none' 用于阻止可能包含漏洞的老旧的小程序,以及 base-uri 'self' 用于阻止任何人通过更改基础 URL 来劫持表单提交。还有,这些指令可以增强网站的安全性。

一般来说,作为一条坚实的规则,你可能希望从一个最小化的约束满足问题(约束满足问题,CSP)开始,然后尽可能少地修改它,以满足你的功能需求。

Content-Security-Policy:  
default-src 'self';  
object-src 'none';  
base-uri 'self';  
frame-ancestors 'none';  
upgrade-insecure-requests;

一个常见的变更是 style-src ‘self’ ‘unsafe-inline;,这将允许内联样式存在,这可能对于你的样式设置是必要的——例如使用 Styled Components,等等。

CSP其实有点像一门黑魔法。在复杂的真实世界应用中,正确地配置CSP可能需要一些尝试和错误。有一个玩笑是CSP实际上应该代表“完全停止页面”(Completely Stops Pages),因为过度激进的CSP策略经常会以意想不到的方式破坏页面的功能或外观。

理解这一点很重要,这些指令并不是键和值,而是Content-Security-Policy是键,其余的部分就是策略。所以应该这么写:

    Content-Security-Policy: default-src 'self'; object-src 'none'; …

CSP 并不是像 React 这样的应用中的设置。如之前所说,它必须是服务器端。这可能涉及 NextJS 或 Remix(我们稍后再详谈),也可能是 SvelteKit,或者可能是通过类似 Digital Ocean 的托管服务中的反代配置。

像 Netlify 和 Vercel 这样的平台没有提供专门的 UI 来处理这种情况,但它们确实提供了内置支持。Netlify 支持一个 _headers 文件,你可以把相关内容放到这个文件中。对于 Vercel 来说,情况相似,它允许使用一个 vercel.json 文件来定义这些头部。

说到头部信息,CSP并不是这里唯一的有用头部信息。

Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, Cross-Origin-Resource-Policy, Cross-Origin-Opener-Policy,和 Cross-Origin-Embedder-Policy 都是可以用来阻止上述大多数或所有问题的头部。我强烈建议你花点时间了解一下并正确设置这些头部。

这里有一个简单的 _headers 文件,包含了一些常见的安全设置。顺便提一句,/* 有其意义——它表示这些设置将应用到所有路由。

/*
内容安全策略:默认源、对象源等配置
Content-Security-Policy: default-src 'self'; object-src 'none';
        base-uri 'self'; frame-ancestors 'none'; upgrade-insecure-requests;

传输安全策略:最大有效期为31536000秒,即一年,包括子域名,并预加载
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

X-Frame-Options: DENY

内容类型选项:禁止嗅探
X-Content-Type-Options: nosniff

引用策略:严格源当跨源
Referrer-Policy: strict-origin-when-cross-origin

权限策略:禁止地理位置、麦克风、摄像头的使用
Permissions-Policy: geolocation=(), microphone=(), camera=()

跨源资源策略:同源策略
Cross-Origin-Resource-Policy: same-origin

跨源打开者策略:同源策略
Cross-Origin-Opener-Policy: same-origin

跨源嵌入者策略:要求企业级策略
Cross-Origin-Embedder-Policy: require-corp
跨源资源共享 (CORS 策略)

你会注意到,在我们的设置中,我们花了很多时间说“自身”,而在我们的跨源资源共享策略 (CORS) 中提到的是同源。浏览器希望仅限制对本地站点的访问——同源策略 (Same-Origin Policy, 简称 SOP)。显然,这样的限制确实带来了安全上的好处,但在实际操作中,这就变成了一个小问题:什么都无法正常运行。

实践中,尤其是在单页面应用中,我们经常会请求外部资源,比如 API 数据这样的请求。请注意,像 fetch 这样的库也包括在其中。从外部 API 获取数据?真是有点大胆!

CORS的目的是让服务器(注意——这里指的是服务器,而不是客户端)来指定哪些客户端可以访问它。

看来和往常一样,这是通过一个头信息来处理的。

    Access-Control-Allow-Origin: https://frontend.com
    # 此标头表示允许的源为 https://frontend.com

这意味着只有https://frontend.com能访问该资源。任何其他来源的请求都会被浏览器拒绝。实际上,人们通常不太注重安全性,因此这个头部信息是完全开放的。事实上,大多数时候我们这样设置CORS只是为了默认情况下避免一些麻烦。

访问控制允许来源: * (允许所有来源访问)

从浏览器和现代应用的角度来看,你对服务器的任何请求都必须返回一个浏览器能够接受的 CORS 头。这通过发送一个预检请求来检查,通常是一个 OPTIONS 请求。也就是说,它使用 OPTIONS HTTP 方法,而不是像 POST 或 GET 这样的方法。虽然这种类型的请求不常见,但它确实是有效的。

前置检查会发送一系列头部信息,检查请求的各项属性,包括其认证头和请求方法是否会得到服务器的认可。服务器会以如下形式回复,回复内容大致如下:

HTTP/1.1 204 没有内容  
Access-Control-Allow-Origin: *  
Access-Control-Allow-Methods: GET, POST, OPTIONS  
Access-Control-Allow-Headers: Authorization  
Access-Control-Max-Age: 3600

基本上,这些方法允许任何URL和Authorization头。最后一个意思是,一小时内无需重发预检,直接采用当前设置即可。

理解CORS确实挺重要的,不过前端开发者不必太深入地去研究它。只要服务器配置好了,一切自然就能顺畅运作了。

掌握后端:理解并控制技术后端

这里有一个反复出现的话题。你可以也应该做一些事情来保证前端安全。但是,如果你对服务器几乎没有或根本没有控制权,那么这些努力的效果就会递减。你对服务器的访问越多,无论是作为基础架构还是应用程序,你就可以更好地配置安全设置。

我之前稍微提过一点,但有一个很好的解决办法。我写过关于像 NextJS 这样的后端服务前端的安全性优点,这样的深入安全讨论正是一个好例子。

你可以有 nginx 配置来存储这类设置,但这种情况不太可能存在于你的代码仓库里,这使得转移或重新实现更加困难。对于一个复杂的 CSP,这可能比你想象的更棘手。我也有这样的经验。

_headers 文件是 Netlify 提供的一个不错解决方案,而 vercel.json 也提供了相同的功能。但是这些是基于供应商的解决方案,依赖于特定的托管服务。NextJS 及其 next.config.js 可以让你以直观且安全的方式设置很多功能。它允许你在其服务器上下文中存储一个 HttpOnly 标头,从而使 JWT 更加安全。或者由于服务器本身就是同源的,所以可以省略 CORS 的设置。你也可以直接在服务器上设置 CORS。你可以使用内置的速率限制来保护 API 免于过多请求。

點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學(xué)習(xí),寫下你的評論
感謝您的支持,我會繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊有機(jī)會得

100積分直接送

付費(fèi)專欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號

舉報

0/150
提交
取消