Web Security 101 - Part 1: Secrets

2025-06-04

网络安全 101 - 第一部分:秘密

开启我的网络安全系列,分享我的秘密——开个玩笑!我们来聊聊如何保护我们的秘密吧。

  1. 环境变量
  2. 秘密服务器
  3. 代币
  4. 曲奇饼
  5. 中间人攻击
  6. Web存储API
  7. IndexedDB API
  8. 会话劫持

环境变量

环境变量就像全局服务器变量一样,通常用于存储机密和敏感信息。虽然有方法可以将它们暴露给浏览器的前端代码,但之后它们就不再是机密了。任何人都可以找到它们。

有一些像dotenv这样的软件包允许你在文件中配置环境变量(只需记住将它们放在你的 中)。你可以在使用HerokuNetlify.gitignore等平台托管网站时配置它们

您也可以在终端环境中手动设置它们,或者在终端使用的文件中设置它们。

环境变量的另一个常见用例是用于存储随环境变化的信息。例如,你有一个表示环境的环境变量,例如NODE_ENV=testingNODE_ENV=production。那么你将得到如下代码:



if (NODE_ENV=testing) {
  URL_BASE=http://localhost:3000
} else {
  URL_BASE=http://mydomain.net
}


Enter fullscreen mode Exit fullscreen mode

根据您的部署方式,还可以为每个环境设置单独的项目,只需更改变量的值即可。

两个壮汉手拉着手。一个男人被标记为生物学家。另一个男人被标记为程序员。他们的手被标记为环境变量。

秘密服务器

您可能会被要求使用密钥服务器来存储您的密钥。有些服务器的设置类似于密码管理器——仅用于共享凭证。其他服务器允许您通过经过身份验证的 HTTP 请求检索密钥。

像Google Cloud这样的产品在您用于部署代码的系统中内置了身份验证、授权、秘密存储和秘密检索功能。

如果以这种方式存储秘密,而不是将其硬编码在环境变量中,则更容易频繁地轮换它们。

代币

令牌是一个表示已加密信息的字符串,通常使用加密哈希值。该信息用于身份验证和授权。当您是应用用户时,他们通常会使用令牌对您进行身份验证和授权。您通常会从 API 获取密钥或令牌,以便以开发者身份对您的应用进行身份验证和授权。

加密算法有很多,但在 Web 开发中,你最常遇到的是 JWT。JSON Web Token 具有 JSON 相关的加密特性。换句话说,它们设计紧凑、URL 安全,并且易于在 JavaScript 中使用。非常适合 Web 开发中的 HTTP 请求。它们的格式甚至类似于 HTTP 请求,包含标头、包含 JSON 数据的有效负载和签名。签名是另一种加密技术,即代码签名。简而言之,代码签名旨在通过验证来源来确保您可以信任信息。

与许多加密标准一样,JWT 算法并非秘密。您可以将 JWT 粘贴到Auth0 的 JWT 调试器中,查看其中的信息。因此,您应该对 JWT 以及收到的所有令牌进行保密。请经常轮换它们,并仅通过 HTTPS 发送。

令牌作为机密信息,应该保留在服务器中,但我们经常需要在浏览器中存储用户信息。我们来谈谈 Cookie。

曲奇饼

饼干怪兽被递上许多饼干,并配文

登录后,服务器收到您的身份验证/授权令牌后,会将前端所需的信息重新打包到 cookie 中并通过 HTTP 发送。

有一个特定的set-cookie标头。您可以使用多个set-cookie标头,每个标头都包含一个键值对(例如 JavaScript 对象或 Python 元组)。

最安全的 Cookie 具有设置secureSameSiteHttpOnly属性。第一个属性表示它只能通过 HTTPS 发送。第二个属性设置为 ,则阻止 CORS 请求访问该 Cookie strict。该lax属性值会在用户导航到同一来源时发送该 Cookie。该属性值none不会限制对 Cookie 的请求。

HttpOnly仅允许通过 HTTP 请求读取 Cookie。您将无法使用Cookie API访问它。换句话说,如果您未设置HttpOnlySameSite=strict,任何人都可以使用 JavaScript 在浏览器中访问您的 Cookie。

如果您需要在前端存储用户的会话信息,则无需在 Cookie 中存储任何机密信息。相反,前端会存储一个会过期的令牌或 ID,本质上是一个公钥。如果私钥存储在后端用于验证,那么即使有人知道公钥也没关系。只有当两者结合在一起时,才会泄露敏感信息。

中间人

为什么要如此严密地保护你的 token 和 cookie?中间人攻击。这种攻击有很多名字,我个人最喜欢的是“中间人怪物”。

以 HTTP 为例,这些怪物会在发送者和接收者之间截取信息。然后,它们会重新打包信息,就像从未打开过一样,并将其发送出去。有时,它们想要获取你 Cookie 中的机密信息。有时,它们更感兴趣的是你如何对信息进行代码签名或编码。

查看OWASP 文章以获取更多信息。

三位《权力的游戏》演员合影。两位身材高挑、符合传统审美的女性分别站在一位身材丰满、身材矮小的男性身旁。图片说明:中间的男性正在进攻。

Web存储API

如果您已经计划在前端存储非秘密信息,那么您也可以使用 Web 存储 API。

Web 存储 API 包含两部分:会话存储本地存储。会话存储仅存储会话内的数据,一旦关闭浏览器或标签页,数据就会消失。本地存储没有过期时间。两者都存储键值对。

由于有内置方法,因此在 Web Storage 中存储和访问信息非常简单:



localStorage.setItem(key, value)
sessionStorage.getItem(key)

Enter fullscreen mode Exit fullscreen mode




IndexedDB API

IndexedDB API类似于 Web Storage API,但功能更强大。它是一个完整的面向对象数据库,直接在浏览器中运行。这意味着您可以存储大量非机密信息。

它是持久存储,可在线和离线工作。更多信息,请参阅Mozilla 开发者网络指南

会话劫持

为什么我这么坚持你不应该在浏览器中存储机密信息?会话劫持。

中间人攻击有多种类型,包括中间人攻击。一种常见的攻击方式是获取存储在浏览器中的会话信息。其目标是要么将信息发送到服务器并获取访问权限,要么冒充您,维持您的会话。

攻击者还可以使用木马点击劫持/UI 篡改以及XSS来劫持会话。务必假设浏览器中存储的所有内容都已遭到泄露。

结论

这个建议来自我的经验。我曾经把密钥暴露给浏览器,却没有意识到这样做有多危险。我丈夫就曾遭遇过会话劫持。

我想先从概述一下机密以及它们不该存储在哪里开始。网络安全的本质在于,它耗费大量时间,不值得你付出,而且你还假设你的机密会被泄露。令牌及其编码算法和建议的频繁轮换就是一个很好的例子。

我将在本系列的其他博客中详细讨论服务器、HTTP、JavaScript 和 HTML 漏洞。

文章来源:https://dev.to/abbeyperini/web-security-101-part-1-secrets-5e39
PREV
使用 Django 和 Gmail 发送电子邮件,一种更好的方法
NEXT
Web 开发 === 可访问性