browser-storage-com/storage-security-linter
GitHub: browser-storage-com/storage-security-linter
一个 ESLint 插件,用于在 lint 阶段检测并修复浏览器存储中的安全隐患,涵盖凭证泄露、PII 暴露、异常未处理等问题。
Stars: 0 | Forks: 0
# eslint-plugin-storage-security
一个 ESLint 插件,用于标记有风险的浏览器存储使用方式——例如将 auth token 和 PII 存入
`localStorage`,未使用 `try`/`catch` 而可能抛出异常的写入操作,以及对存储数据进行未受保护的
`JSON.parse`——并为你提供更安全的模式建议。
Web storage(`localStorage`、`sessionStorage`、`indexedDB`)虽然方便,但
很容易被误用:origin 上的任何脚本都可以读取它,在超出配额和
隐私浏览模式下会抛出异常,并且会返回任意字符串,而这些字符串可能不再是
有效的 JSON。这些规则会在 lint 阶段捕获常见的隐患。
## 为什么
- **XSS 会将存储的 token 变成被盗的会话。** Web storage 中的任何内容都可以
被注入或第三方脚本访问。
- **存储中的 PII 是未加密且持久的**,这会带来隐私和合规性
隐患。
- **`setItem` 会抛出异常**,在发生 `QuotaExceededError` 和某些隐私模式下。
- **对存储数据进行 `JSON.parse` 会在**输入损坏或被篡改时抛出异常。
## 安装
此包通过 GitHub 分发(**未**发布到 npm
registry):
```
npm install --save-dev github:browser-storage-com/storage-security-linter
```
它没有运行时依赖。ESLint 是一个 peer dependency(`eslint >=8`)。
## 用法
### Flat config (ESLint 9+)
```
// eslint.config.js
import storageSecurity from "eslint-plugin-storage-security";
export default [
storageSecurity.configs["flat/recommended"],
];
```
或者手动配置:
```
import storageSecurity from "eslint-plugin-storage-security";
export default [
{
plugins: { "storage-security": storageSecurity },
rules: {
"storage-security/no-token-in-localstorage": "error",
"storage-security/require-try-catch-storage": "error",
},
},
];
```
### Legacy config (`.eslintrc`)
```
{
"plugins": ["storage-security"],
"extends": ["plugin:storage-security/recommended"]
}
```
## 预设
| 预设 | 配置键 | 备注 |
| --- | --- | --- |
| Recommended (flat) | `configs["flat/recommended"]` | 启用除建议性的 `no-unencrypted-storage-write` 之外的所有规则。 |
| All (flat) | `configs["flat/all"]` | 启用所有规则。 |
| Recommended (legacy) | `plugin:storage-security/recommended` | 相同的规则集,`.eslintrc` 风格。 |
| All (legacy) | `plugin:storage-security/all` | 所有规则,`.eslintrc` 风格。 |
## 规则
| 规则 | 描述 | 推荐 | 可修复 |
| --- | --- | :---: | :---: |
| [no-token-in-localstorage](docs/rules/no-token-in-localstorage.md) | 禁止在 web storage 中存储 auth token / JWT / secret。 | 是 | 否 |
| [no-sensitive-data-in-storage](docs/rules/no-sensitive-data-in-storage.md) | 禁止向 web storage 中写入可能的 PII。 | 是 | 否 |
| [require-try-catch-storage](docs/rules/require-try-catch-storage.md) | 要求在 `setItem` / `indexedDB.open` 外围使用 `try`/`catch`。 | 是 | 建议 |
| [no-json-parse-storage-without-catch](docs/rules/no-json-parse-storage-without-catch.md) | 要求对存储值进行 `JSON.parse` 时进行错误处理。 | 是 | 建议 |
| [no-unencrypted-storage-write](docs/rules/no-unencrypted-storage-write.md) | 鼓励通过加密 wrapper 进行写入。 | 否 (建议性) | 否 |
### no-token-in-localstorage
标记写入到 `localStorage` / `sessionStorage` 中类似凭证的 key(`token`、`jwt`、`auth`、`secret`、`password`、
`apiKey` 等),包括通过
`setItem` 或成员赋值(`localStorage.token = …`),以及带有
`window.` 前缀的形式。建议将短期 token 保留在内存中,并将 refresh token 存放在
`HttpOnly` cookie 中。匹配是大小写不敏感的,并且模式列表
可以通过 `patterns` 选项进行配置。
### no-sensitive-data-in-storage
标记写入到 web storage 中类似 PII 的 key(`ssn`、`creditCard`、`cvv`、`dob`、`passport` 等)。使用 `patterns`(替换默认值)或
`additionalPatterns`(扩展默认值)进行配置。
### require-try-catch-storage
标记未包裹在 `try`
块中的 `setItem` 和 `indexedDB.open` 调用,因为它们可能会抛出 `QuotaExceededError` 或 `SecurityError`。提供一个
建议来包裹该语句。设置 `checkIndexedDB: false` 以将其限制于 Web
Storage。
### no-json-parse-storage-without-catch
标记位于
`try` 块之外的 `JSON.parse(localStorage.getItem(...))`(以及 `sessionStorage`),在这种情况下,损坏或被篡改的数据会导致抛出异常。提供一个建议
来包裹该语句。
### no-unencrypted-storage-write
建议性规则,**在 `recommended` 中默认关闭**。启用后,如果
有意义的写入操作未通过批准的加密 wrapper,则会发出警告。
使用 `wrappers` 选项配置接受的 wrapper 名称。
## 选项一览
```
{
"rules": {
"storage-security/no-token-in-localstorage": [
"error",
{ "patterns": ["token", "jwt", "auth", "secret", "password", "apiKey"] }
],
"storage-security/no-sensitive-data-in-storage": [
"error",
{ "additionalPatterns": ["employeeId"] }
],
"storage-security/require-try-catch-storage": [
"error",
{ "checkIndexedDB": true }
],
"storage-security/no-unencrypted-storage-write": [
"warn",
{ "wrappers": ["encrypt", "secureStore"] }
]
}
}
```
## 延伸阅读
关于这些规则所防范问题的实用背景:
- [保护浏览器存储中的 auth token](https://www.browser-storage.com/storage-security-encryption-privacy/securing-auth-tokens-in-browser-storage/)
- [为什么 localStorage 中的 JWT 容易受到 XSS 攻击](https://www.browser-storage.com/storage-security-encryption-privacy/securing-auth-tokens-in-browser-storage/why-jwt-in-localstorage-is-xss-vulnerable/)
- [使用 Web Crypto 加密浏览器存储](https://www.browser-storage.com/storage-security-encryption-privacy/encrypting-browser-storage-with-web-crypto/)
- [存储分区与隐私控制](https://www.browser-storage.com/storage-security-encryption-privacy/storage-partitioning-and-privacy-controls/)
## License
MIT © browser-storage.com
由 [浏览器存储与离线优先状态持久化](https://www.browser-storage.com/) 背后的团队维护。
标签:ESLint插件, MITM代理, ProjectDiscovery, Web存储, 代码安全, 前端安全, 数据保护, 数据可视化, 漏洞枚举, 自定义脚本, 错误基检测, 静态代码分析