JamesToohey/csprefabricate
GitHub: JamesToohey/csprefabricate
TypeScript 库,用于以类型安全的方式生成和验证内容安全策略(CSP)字符串,并提供安全警告检测。
Stars: 1 | Forks: 0
# csprefabricate
**使用 TypeScript 生成有效的 CSP。**
内容安全策略 (CSP) 是处理起来令人沮丧的繁琐字符串:
- 棘手的语法
- 当需要多个 TLD 时会出现重复
- 容易允许不安全的配置
本项目旨在让创建有用且安全的 CSP 变成一种更愉快的体验。
目前 `csprefabricate` 能够:
- 验证指令名称
- 验证 nonce 和 hash 格式
- 通过清理输入来防止 CSP 注入
- 对指令和规则进行确定性排序,以确保输出一致
- 支持 CSP Level 3 指令(`script-src-elem`、`script-src-attr`、`style-src-elem`、`style-src-attr`、`webrtc`)
- 支持 CSP Level 3 关键字源(`'wasm-unsafe-eval'`、`'inline-speculation-rules'`、`'unsafe-allow-redirects'`、`'trusted-types-eval'`、`'report-sample'`、`'report-sha256'`、`'report-sha384'`、`'report-sha512'`、`'unsafe-webtransport-hashes'`)
- 支持为给定域名提供 TLD 列表
- 针对不安全或不完整的 CSP 配置提供警告,并提供禁用特定警告的选项
- 警告已弃用的指令(`plugin-types`、`report-uri`、`block-all-mixed-content`)
- 警告冲突的指令(例如 `'none'` 与其他源一起使用)
## 常见 CSP 问题
默认情况下,`csprefabricate` 会针对常见的 CSP 问题向您发出警告,例如:
- 过于宽松的源(例如使用 `*`)
- 缺少推荐的指令(即 `object-src`、`base-uri`、`form-action`)
- 在 `script-src` 中使用 `'unsafe-inline'`,即使存在 nonce 或 hash
- 在 `script-src` 中使用 `'unsafe-inline'` 时缺少 nonce 或 hash
- 无效的 nonce 或 hash 格式
- 在 `img-src` 或 `media-src` 中允许 `data:`
- 使用已弃用的指令(`plugin-types`、`report-uri`、`block-all-mixed-content`)
- 冲突的指令(例如 `'none'` 与其他源一起使用)
您可以通过向 `create` 函数传递一个可选的 `WarningOptions` 对象来控制显示哪些警告:
```
import {
create,
Directive,
ContentSecurityPolicy,
WarningOptions,
} from "csprefabricate";
const csp: ContentSecurityPolicy = {
[Directive.SCRIPT_SRC]: ["*"],
[Directive.IMG_SRC]: ["data:"],
};
// Disable all warnings
const warningOptions: WarningOptions = {
overlyPermissive: false,
missingDirectives: false,
unsafeInline: false,
missingNonceOrHash: false,
dataUri: false,
deprecatedDirectives: false,
conflictingDirectives: false,
};
create(csp, warningOptions);
```
您可以根据需要有选择地启用或禁用特定警告。
## 真实示例
### 示例 1:基本严格策略
```
import {create, Directive, ContentSecurityPolicy} from "csprefabricate";
const csp: ContentSecurityPolicy = {
[Directive.DEFAULT_SRC]: ["'self'"],
[Directive.SCRIPT_SRC]: ["'self'"],
[Directive.STYLE_SRC]: ["'self'"],
[Directive.IMG_SRC]: ["'self'"],
[Directive.OBJECT_SRC]: ["'none'"],
[Directive.BASE_URI]: ["'self'"],
[Directive.FORM_ACTION]: ["'self'"],
};
const cspString = create(csp);
// "base-uri 'self'; default-src 'self'; form-action 'self'; img-src 'self'; object-src 'none'; script-src 'self'; style-src 'self';"
```
### 示例 2:允许 Google Analytics
```
import {create, Directive, ContentSecurityPolicy} from "csprefabricate";
const csp: ContentSecurityPolicy = {
[Directive.DEFAULT_SRC]: ["'self'"],
[Directive.SCRIPT_SRC]: ["'self'", "*.googletagmanager.com"],
[Directive.STYLE_SRC]: ["'self'"],
[Directive.IMG_SRC]: [
"'self'",
"https://*.google-analytics.com",
"https://*.googletagmanager.com",
],
[Directive.OBJECT_SRC]: ["'none'"],
[Directive.BASE_URI]: ["'self'"],
[Directive.FORM_ACTION]: ["'self'"],
[Directive.CONNECT_SRC]: [
"'self'",
"https://*.google-analytics.com",
"https://*.analytics.google.com",
"https://*.googletagmanager.com",
],
};
const cspString = create(csp);
// "base-uri 'self'; connect-src 'self' https://*.analytics.google.com https://*.google-analytics.com https://*.googletagmanager.com; default-src 'self'; form-action 'self'; img-src 'self' https://*.google-analytics.com https://*.googletagmanager.com; object-src 'none'; script-src 'self' *.googletagmanager.com; style-src 'self';"
```
### 示例 3:对多个域名使用 TLD 扩展
```
import {create, Directive, ContentSecurityPolicy} from "csprefabricate";
const csp: ContentSecurityPolicy = {
[Directive.IMG_SRC]: ["self", {"*.example": [".com", ".co.uk", ".net"]}],
};
const cspString = create(csp);
// "img-src 'self' *.example.co.uk *.example.com *.example.net;"
```
### 示例 4:使用 CSP Level 3 指令和关键字
CSP Level 3 引入了对脚本和样式更细粒度的控制,以及新的关键字源:
```
import {create, Directive, ContentSecurityPolicy} from "csprefabricate";
const csp: ContentSecurityPolicy = {
[Directive.DEFAULT_SRC]: ["self"],
// Control