Skip to content

Commit 9eab2f9

Browse files
committed
feat(security): 支持可配置的 SRI 哈希算法,增加 SHA-256 和 SHA-384 选项
1 parent d1a0012 commit 9eab2f9

2 files changed

Lines changed: 36 additions & 46 deletions

File tree

README.md

Lines changed: 13 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
## 功能特性
66

77
- 自动为 HTML 文件中的 `<script>``<link>` 标签生成 SRI 属性
8-
- 支持 SHA-512 哈希算法
8+
- 支持 SHA-256、SHA-384、SHA-512 哈希算法(可配置)
99
- 自动添加 `crossorigin="anonymous"` 属性以确保 SRI 正常工作
1010
- 仅在生产环境下生效,开发环境自动跳过
1111

@@ -34,9 +34,9 @@ export default defineConfig({
3434

3535
### `sri`
3636

37-
- **类型**: `boolean`
37+
- **类型**: `boolean | { algorithm: 'sha256' | 'sha384' | 'sha512' }`
3838
- **默认值**: 需要手动设置
39-
- **描述**: 是否启用 SRI(子资源完整性)功能
39+
- **描述**: 是否启用 SRI(子资源完整性)功能,以及可选的哈希算法配置
4040

4141
当设置为 `true` 时,插件会:
4242

@@ -45,46 +45,18 @@ export default defineConfig({
4545
3. 为所有带有 `href` 属性的 `<link>` 标签添加 `integrity` 属性
4646
4. 自动添加 `crossorigin="anonymous"` 属性(如果不存在)
4747

48-
## 示例
49-
50-
### 输入 HTML
48+
你也可以通过对象方式指定哈希算法:
5149

52-
```html
53-
<!DOCTYPE html>
54-
<html>
55-
<head>
56-
<link rel="stylesheet" href="/assets/app.css">
57-
</head>
58-
<body>
59-
<script src="/assets/app.js"></script>
60-
</body>
61-
</html>
62-
```
63-
64-
### 输出 HTML(启用 SRI 后)
65-
66-
```html
67-
<!DOCTYPE html>
68-
<html>
69-
<head>
70-
<link rel="stylesheet" href="/assets/app.css" integrity="sha512-ABC123..." crossorigin="anonymous">
71-
</head>
72-
<body>
73-
<script src="/assets/app.js" integrity="sha512-XYZ789..." crossorigin="anonymous"></script>
74-
</body>
75-
</html>
50+
```typescript
51+
security: {
52+
sri: {
53+
algorithm: 'sha512' // 可选 'sha256' | 'sha384' | 'sha512',默认 'sha512'
54+
}
55+
}
7656
```
7757

78-
## 安全说明
79-
80-
SRI(子资源完整性)是一种安全特性,允许浏览器验证获取的资源(例如从 CDN 获取的资源)没有被恶意修改。当浏览器加载资源时,会计算资源的哈希值并与 `integrity` 属性中指定的哈希值进行比较。如果哈希值不匹配,浏览器将拒绝加载该资源。
81-
82-
## 注意事项
83-
84-
1. 此插件仅在生产构建时生效,开发环境会自动跳过
85-
2. 需要确保资源文件在构建输出目录中可访问
86-
3. `integrity` 属性必须与 `crossorigin` 属性配合使用才能正常工作
58+
## 示例
8759

88-
## 许可证
60+
### 输入 HTML
8961

90-
MIT
62+
```

src/index.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import { cheerio, logger } from '@winner-fed/utils';
55
import type { IApi } from '@winner-fed/winjs';
66

77
interface SecurityConfig {
8-
sri: boolean;
8+
sri: boolean | {
9+
algorithm: 'sha256' | 'sha384' | 'sha512';
10+
};
911
}
1012

1113
export default (api: IApi) => {
@@ -15,7 +17,12 @@ export default (api: IApi) => {
1517
config: {
1618
schema({ zod }) {
1719
return zod.object({
18-
sri: zod.boolean(),
20+
sri: zod.union([
21+
zod.boolean(),
22+
zod.object({
23+
algorithm: zod.enum(['sha256', 'sha384', 'sha512']).default('sha512'),
24+
})
25+
])
1926
});
2027
},
2128
},
@@ -26,11 +33,22 @@ export default (api: IApi) => {
2633
async (html: { htmlFiles?: Array<{ path: string; content: string }> }) => {
2734
const config = api.config.security as SecurityConfig;
2835

29-
// 只有当 sri 配置为 true 时才生成 SRI
36+
// 只有当 sri 配置为 true 或对象时才生成 SRI
3037
if (!config?.sri) {
3138
return;
3239
}
3340

41+
// 处理 sri 配置,支持 boolean 和对象
42+
let sriConfig: { algorithm: 'sha256' | 'sha384' | 'sha512' };
43+
if (config.sri === true) {
44+
sriConfig = { algorithm: 'sha512' };
45+
} else if (typeof config.sri === 'object' && config.sri !== null && typeof (config.sri as any).algorithm === 'string') {
46+
sriConfig = { algorithm: (config.sri as any).algorithm };
47+
} else {
48+
// 未指定算法时,默认 sha512
49+
sriConfig = { algorithm: 'sha512' };
50+
}
51+
3452
const htmlFiles = html?.htmlFiles || [];
3553
if (api.env === 'development' || htmlFiles.length === 0) {
3654
return;
@@ -68,9 +86,9 @@ export default (api: IApi) => {
6886
}
6987

7088
if (source) {
71-
const hash = createHash('sha512').update(source).digest('base64');
89+
const hash = createHash(sriConfig.algorithm).update(source).digest('base64');
7290

73-
$el.attr('integrity', `sha512-${hash}`);
91+
$el.attr('integrity', `${sriConfig.algorithm}-${hash}`);
7492

7593
// https://developer.mozilla.org/zh-CN/docs/Web/HTML/Attributes/crossorigin
7694
// 在进行跨域资源请求时,integrity 必须配合 crossorigin 使用,不然浏览器会丢弃这个资源的请求

0 commit comments

Comments
 (0)