dw-kit 1.3.5 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/hooks/supply-chain-scan.sh +16 -14
- package/.claude/skills/dw-archive/SKILL.md +14 -0
- package/.claude/skills/dw-review/SKILL.md +33 -2
- package/.dw/config/config.schema.json +149 -121
- package/.dw/config/dw.config.yml +14 -0
- package/.dw/security/advisory-snapshot.json +157 -0
- package/.dw/security/ioc-namespaces.json +20 -8
- package/CLAUDE.md +1 -1
- package/README.md +15 -2
- package/package.json +2 -1
- package/src/cli.mjs +20 -2
- package/src/commands/doctor.mjs +41 -1
- package/src/commands/init.mjs +45 -1
- package/src/commands/review-render.mjs +255 -0
- package/src/commands/security-scan.mjs +367 -52
- package/src/lib/config.mjs +120 -104
- package/src/lib/gitignore.mjs +5 -1
- package/src/lib/npm-registry.mjs +159 -0
- package/src/lib/review/manifest-schema.json +149 -0
- package/src/lib/review/manifest-validator.mjs +93 -0
- package/src/lib/review/scope-slug.mjs +68 -0
- package/src/lib/sc-heuristic.mjs +263 -0
- package/src/lib/sc-scanner.mjs +60 -11
- package/src/lib/sc-sync.mjs +98 -8
- package/src/lib/telemetry.mjs +20 -0
|
@@ -60,9 +60,12 @@ fi
|
|
|
60
60
|
|
|
61
61
|
START_TS=$(date +%s%N 2>/dev/null || date +%s)
|
|
62
62
|
|
|
63
|
-
#
|
|
63
|
+
# Pillar 3 (ADR-0006): heuristic-only mode probes ONLY the NEW/bumped packages
|
|
64
|
+
# from the lockfile diff against npm registry metadata. Cached 1h per package
|
|
65
|
+
# so repeat edits hit cache. This is the AI-Native moat — catches zero-day-ish
|
|
66
|
+
# at the edit boundary, before OSV indexes and before any TL fixture bump.
|
|
64
67
|
set +e
|
|
65
|
-
SCAN_OUTPUT=$(cd "$LOCKFILE_DIR" && $DW_BIN security-scan --
|
|
68
|
+
SCAN_OUTPUT=$(cd "$LOCKFILE_DIR" && $DW_BIN security-scan --heuristic-only 2>&1)
|
|
66
69
|
SCAN_EXIT=$?
|
|
67
70
|
set -e
|
|
68
71
|
|
|
@@ -73,28 +76,27 @@ case "$SCAN_EXIT" in
|
|
|
73
76
|
0)
|
|
74
77
|
# Clean — silent unless verbose
|
|
75
78
|
if [ "${DW_SC_GUARD_VERBOSE:-}" = "1" ]; then
|
|
76
|
-
echo "✓ supply-chain-scan: clean (no
|
|
79
|
+
echo "✓ supply-chain-scan: clean (no heuristic flags on NEW/bumped packages in $BASENAME)" >&2
|
|
77
80
|
fi
|
|
78
81
|
;;
|
|
79
82
|
1)
|
|
80
|
-
#
|
|
83
|
+
# Mid-risk heuristic flags — warn, do not block
|
|
81
84
|
echo "" >&2
|
|
82
|
-
echo "⚠ supply-chain-scan:
|
|
83
|
-
echo "$SCAN_OUTPUT" | tail -
|
|
84
|
-
echo " (advisory — not blocking; run \`dw security-scan\` for full report)" >&2
|
|
85
|
+
echo "⚠ supply-chain-scan: heuristic flags on NEW/bumped packages in $BASENAME" >&2
|
|
86
|
+
echo "$SCAN_OUTPUT" | tail -30 >&2
|
|
87
|
+
echo " (advisory — not blocking; run \`dw security-scan\` for full pillar 1+2+3 report)" >&2
|
|
85
88
|
;;
|
|
86
89
|
2)
|
|
87
|
-
# HIGH
|
|
90
|
+
# HIGH-risk heuristic flag (score ≥80) — loud warning, still non-blocking
|
|
88
91
|
echo "" >&2
|
|
89
|
-
echo "⚠ supply-chain-scan: HIGH
|
|
90
|
-
echo "$SCAN_OUTPUT" | tail -
|
|
91
|
-
echo " ADVISORY ONLY —
|
|
92
|
-
echo " Run \`dw security-scan\` for full report. Public sunset review 2026-08-12 (ADR-0005)." >&2
|
|
92
|
+
echo "⚠ supply-chain-scan: HIGH-RISK heuristic flag on NEW/bumped package in $BASENAME" >&2
|
|
93
|
+
echo "$SCAN_OUTPUT" | tail -40 >&2
|
|
94
|
+
echo " ADVISORY ONLY — review before commit. Public sunset review 2026-08-12 (ADR-0005)." >&2
|
|
93
95
|
;;
|
|
94
96
|
*)
|
|
95
|
-
# Setup error (no
|
|
97
|
+
# Setup error (no lockfile, network failure) — quiet hint
|
|
96
98
|
if [ "${DW_SC_GUARD_VERBOSE:-}" = "1" ]; then
|
|
97
|
-
echo "supply-chain-scan:
|
|
99
|
+
echo "supply-chain-scan: heuristic check skipped or errored — run \`dw security-scan\` manually" >&2
|
|
98
100
|
fi
|
|
99
101
|
;;
|
|
100
102
|
esac
|
|
@@ -54,6 +54,20 @@ mv {paths.tasks}/[task-name] {paths.tasks}/archive/[YYYY-MM]/
|
|
|
54
54
|
|
|
55
55
|
Tổ chức theo tháng hoàn thành để dễ tìm kiếm sau.
|
|
56
56
|
|
|
57
|
+
### 4a. Clean up review render artifacts (ADR-0007)
|
|
58
|
+
|
|
59
|
+
Nếu `.dw/reviews/[task-name]/` hoặc `.dw/reviews/[task-slug]/` tồn tại:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Local-only ephemeral artifacts (gitignored) — safe to remove on archive.
|
|
63
|
+
# User can regenerate via /dw:review --visual nếu cần lại.
|
|
64
|
+
rm -rf .dw/reviews/[task-name]/
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Báo cáo trong output Bước 6: "Đã dọn .dw/reviews/[task-name]/ (regenerate via /dw:review --visual nếu cần)."
|
|
68
|
+
|
|
69
|
+
Nếu task có scope_slug khác task-name (kiểm tra `.dw/reviews/*/manifest.json` có `task_id` matching), dọn cả slug đó.
|
|
70
|
+
|
|
57
71
|
## Bước 5: Cập nhật archive index
|
|
58
72
|
|
|
59
73
|
Ghi/cập nhật `{paths.tasks}/archive/README.md`:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dw:review
|
|
3
|
-
description: "Review code thay đổi gần đây hoặc cả task. Kiểm tra correctness, security, conventions, test coverage. Tạo báo cáo phân loại Critical/Warning/Suggestion."
|
|
4
|
-
argument-hint: "[task-name | branch | file]"
|
|
3
|
+
description: "Review code thay đổi gần đây hoặc cả task. Kiểm tra correctness, security, conventions, test coverage. Tạo báo cáo phân loại Critical/Warning/Suggestion. Pass --visual để emit manifest cho visual artifacts (ADR-0007)."
|
|
4
|
+
argument-hint: "[task-name | branch | file] [--visual]"
|
|
5
5
|
context: fork
|
|
6
6
|
agent: reviewer
|
|
7
7
|
allowed-tools:
|
|
@@ -11,6 +11,8 @@ allowed-tools:
|
|
|
11
11
|
- "Bash(git diff *)"
|
|
12
12
|
- "Bash(git log *)"
|
|
13
13
|
- "Bash(git show *)"
|
|
14
|
+
- "Bash(dw review render *)"
|
|
15
|
+
- "Write(.dw/reviews/**/manifest.json)"
|
|
14
16
|
---
|
|
15
17
|
|
|
16
18
|
# Code Review
|
|
@@ -57,6 +59,35 @@ Nếu có plan file (`{paths.tasks}/$ARGUMENTS/$ARGUMENTS-plan.md`):
|
|
|
57
59
|
|
|
58
60
|
Tạo báo cáo đầy đủ theo format của reviewer agent.
|
|
59
61
|
|
|
62
|
+
### 5-alt. `--visual` flag (ADR-0007)
|
|
63
|
+
|
|
64
|
+
Nếu user pass `--visual`, KHÔNG in báo cáo inline. Thay vào đó:
|
|
65
|
+
|
|
66
|
+
1. **Tạo manifest JSON** tuân thủ `src/lib/review/manifest-schema.json` (schema_version 1):
|
|
67
|
+
- `scope`: nhãn review (branch name, task slug, hoặc free-form từ argument)
|
|
68
|
+
- `scope_slug`: sanitize qua `scope-slug` util — KHÔNG dùng scope thô làm tên thư mục
|
|
69
|
+
- `generated_at`: ISO timestamp hiện tại
|
|
70
|
+
- `task_id` (optional): nếu review thuộc một task — link tới `.dw/tasks/{id}/`
|
|
71
|
+
- `review_meta`: `{reviewer: "dw-review", depth, diff_base, files_reviewed}`
|
|
72
|
+
- `findings[]`: mỗi finding có `id, severity (critical|warning|suggestion), title, location {file, line_start, line_end}, rule_ref?, body, fix?, code_snippet (≤50 lines quanh finding), language?`
|
|
73
|
+
|
|
74
|
+
2. **Ghi manifest** ra `.dw/reviews/{scope_slug}/manifest.json` qua Write tool. Đây là file DUY NHẤT skill được phép viết.
|
|
75
|
+
|
|
76
|
+
3. **Gọi renderer**:
|
|
77
|
+
```bash
|
|
78
|
+
dw review render .dw/reviews/{scope_slug}/manifest.json
|
|
79
|
+
```
|
|
80
|
+
CLI sẽ:
|
|
81
|
+
- Validate manifest qua schema
|
|
82
|
+
- Phát hiện `dw-kit-render` package (optional sub-package)
|
|
83
|
+
- Nếu có: render SVG + PNG per finding → `.dw/reviews/{scope_slug}/finding-{id}.svg` + `.png`
|
|
84
|
+
- Nếu thiếu: ghi `summary.md` markdown + prompt user install `dw-kit-render`
|
|
85
|
+
- Luôn ghi `summary.md` tổng hợp với links tới artifacts
|
|
86
|
+
|
|
87
|
+
4. **Surface kết quả**: in danh sách artifact paths cho user; gợi ý mở `summary.md` hoặc embed image vào PR comment.
|
|
88
|
+
|
|
89
|
+
KHÔNG fallback inline report — manifest + render là contract của `--visual`.
|
|
90
|
+
|
|
60
91
|
## Sau Review
|
|
61
92
|
|
|
62
93
|
- Nếu có Critical issues: "Cần fix trước khi merge"
|
|
@@ -1,121 +1,149 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"title": "dw-kit Configuration Schema",
|
|
4
|
-
"description": "Schema for config/dw.config.yml",
|
|
5
|
-
"type": "object",
|
|
6
|
-
"additionalProperties": false,
|
|
7
|
-
"properties": {
|
|
8
|
-
"project": {
|
|
9
|
-
"type": "object",
|
|
10
|
-
"additionalProperties": false,
|
|
11
|
-
"required": ["name"],
|
|
12
|
-
"properties": {
|
|
13
|
-
"name": { "type": "string", "minLength": 1 },
|
|
14
|
-
"language": { "type": "string", "enum": ["vi", "en"], "default": "vi" }
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"workflow": {
|
|
18
|
-
"type": "object",
|
|
19
|
-
"additionalProperties": false,
|
|
20
|
-
"properties": {
|
|
21
|
-
"default_depth": {
|
|
22
|
-
"type": "string",
|
|
23
|
-
"enum": ["quick", "standard", "thorough"],
|
|
24
|
-
"default": "standard"
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
"team": {
|
|
29
|
-
"type": "object",
|
|
30
|
-
"additionalProperties": false,
|
|
31
|
-
"properties": {
|
|
32
|
-
"roles": {
|
|
33
|
-
"type": "array",
|
|
34
|
-
"items": {
|
|
35
|
-
"type": "string",
|
|
36
|
-
"enum": ["dev", "techlead", "ba", "qc", "pm"]
|
|
37
|
-
},
|
|
38
|
-
"minItems": 1,
|
|
39
|
-
"contains": { "const": "dev" },
|
|
40
|
-
"description": "dev is always required"
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
"quality": {
|
|
45
|
-
"type": "object",
|
|
46
|
-
"additionalProperties": false,
|
|
47
|
-
"properties": {
|
|
48
|
-
"test_command": { "type": "string", "default": "" },
|
|
49
|
-
"lint_command": { "type": "string", "default": "" },
|
|
50
|
-
"block_on_fail": { "type": "boolean", "default": false }
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
"tracking": {
|
|
54
|
-
"type": "object",
|
|
55
|
-
"additionalProperties": false,
|
|
56
|
-
"properties": {
|
|
57
|
-
"estimation": { "type": "boolean", "default": false },
|
|
58
|
-
"log_work": { "type": "boolean", "default": false },
|
|
59
|
-
"estimation_unit": {
|
|
60
|
-
"type": "string",
|
|
61
|
-
"enum": ["hours", "story-points", "t-shirt"],
|
|
62
|
-
"default": "hours"
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
"paths": {
|
|
67
|
-
"type": "object",
|
|
68
|
-
"additionalProperties": false,
|
|
69
|
-
"properties": {
|
|
70
|
-
"tasks": { "type": "string", "default": ".dw/tasks" },
|
|
71
|
-
"docs": { "type": "string", "default": ".dw/docs" }
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
"claude": {
|
|
75
|
-
"type": "object",
|
|
76
|
-
"additionalProperties": false,
|
|
77
|
-
"properties": {
|
|
78
|
-
"models": {
|
|
79
|
-
"type": "object",
|
|
80
|
-
"additionalProperties": false,
|
|
81
|
-
"properties": {
|
|
82
|
-
"plan": { "type": "string", "default": "" },
|
|
83
|
-
"execute": { "type": "string", "default": "" },
|
|
84
|
-
"review": { "type": "string", "default": "" }
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
"structured_output": { "type": "boolean", "default": true },
|
|
88
|
-
"worktree_execution": { "type": "boolean", "default": false },
|
|
89
|
-
"
|
|
90
|
-
"type": "
|
|
91
|
-
"
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
"
|
|
95
|
-
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
"
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "dw-kit Configuration Schema",
|
|
4
|
+
"description": "Schema for config/dw.config.yml",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"properties": {
|
|
8
|
+
"project": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"additionalProperties": false,
|
|
11
|
+
"required": ["name"],
|
|
12
|
+
"properties": {
|
|
13
|
+
"name": { "type": "string", "minLength": 1 },
|
|
14
|
+
"language": { "type": "string", "enum": ["vi", "en"], "default": "vi" }
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"workflow": {
|
|
18
|
+
"type": "object",
|
|
19
|
+
"additionalProperties": false,
|
|
20
|
+
"properties": {
|
|
21
|
+
"default_depth": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"enum": ["quick", "standard", "thorough"],
|
|
24
|
+
"default": "standard"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"team": {
|
|
29
|
+
"type": "object",
|
|
30
|
+
"additionalProperties": false,
|
|
31
|
+
"properties": {
|
|
32
|
+
"roles": {
|
|
33
|
+
"type": "array",
|
|
34
|
+
"items": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"enum": ["dev", "techlead", "ba", "qc", "pm"]
|
|
37
|
+
},
|
|
38
|
+
"minItems": 1,
|
|
39
|
+
"contains": { "const": "dev" },
|
|
40
|
+
"description": "dev is always required"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"quality": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"additionalProperties": false,
|
|
47
|
+
"properties": {
|
|
48
|
+
"test_command": { "type": "string", "default": "" },
|
|
49
|
+
"lint_command": { "type": "string", "default": "" },
|
|
50
|
+
"block_on_fail": { "type": "boolean", "default": false }
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"tracking": {
|
|
54
|
+
"type": "object",
|
|
55
|
+
"additionalProperties": false,
|
|
56
|
+
"properties": {
|
|
57
|
+
"estimation": { "type": "boolean", "default": false },
|
|
58
|
+
"log_work": { "type": "boolean", "default": false },
|
|
59
|
+
"estimation_unit": {
|
|
60
|
+
"type": "string",
|
|
61
|
+
"enum": ["hours", "story-points", "t-shirt"],
|
|
62
|
+
"default": "hours"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"paths": {
|
|
67
|
+
"type": "object",
|
|
68
|
+
"additionalProperties": false,
|
|
69
|
+
"properties": {
|
|
70
|
+
"tasks": { "type": "string", "default": ".dw/tasks" },
|
|
71
|
+
"docs": { "type": "string", "default": ".dw/docs" }
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
"claude": {
|
|
75
|
+
"type": "object",
|
|
76
|
+
"additionalProperties": false,
|
|
77
|
+
"properties": {
|
|
78
|
+
"models": {
|
|
79
|
+
"type": "object",
|
|
80
|
+
"additionalProperties": false,
|
|
81
|
+
"properties": {
|
|
82
|
+
"plan": { "type": "string", "default": "" },
|
|
83
|
+
"execute": { "type": "string", "default": "" },
|
|
84
|
+
"review": { "type": "string", "default": "" }
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
"structured_output": { "type": "boolean", "default": true },
|
|
88
|
+
"worktree_execution": { "type": "boolean", "default": false },
|
|
89
|
+
"review": {
|
|
90
|
+
"type": "object",
|
|
91
|
+
"additionalProperties": false,
|
|
92
|
+
"description": "Review render pipeline (ADR-0007).",
|
|
93
|
+
"properties": {
|
|
94
|
+
"renderer": {
|
|
95
|
+
"type": "object",
|
|
96
|
+
"additionalProperties": false,
|
|
97
|
+
"properties": {
|
|
98
|
+
"strategy": {
|
|
99
|
+
"type": "string",
|
|
100
|
+
"enum": ["auto", "plugin", "markdown-only"],
|
|
101
|
+
"default": "auto"
|
|
102
|
+
},
|
|
103
|
+
"theme": { "type": "string", "default": "github-dark" },
|
|
104
|
+
"font": { "type": "string", "default": "JetBrains Mono" },
|
|
105
|
+
"formats": {
|
|
106
|
+
"type": "array",
|
|
107
|
+
"items": { "type": "string", "enum": ["svg", "png"] },
|
|
108
|
+
"minItems": 1,
|
|
109
|
+
"uniqueItems": true,
|
|
110
|
+
"default": ["svg", "png"]
|
|
111
|
+
},
|
|
112
|
+
"output_dir": { "type": "string", "default": ".dw/reviews" }
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"mcp": {
|
|
118
|
+
"type": "array",
|
|
119
|
+
"items": {
|
|
120
|
+
"type": "object",
|
|
121
|
+
"required": ["name", "command"],
|
|
122
|
+
"additionalProperties": false,
|
|
123
|
+
"properties": {
|
|
124
|
+
"name": { "type": "string" },
|
|
125
|
+
"command": { "type": "string" },
|
|
126
|
+
"args": { "type": "array", "items": { "type": "string" } },
|
|
127
|
+
"env": {
|
|
128
|
+
"type": "object",
|
|
129
|
+
"additionalProperties": { "type": "string" }
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
"_toolkit": {
|
|
137
|
+
"type": "object",
|
|
138
|
+
"additionalProperties": true,
|
|
139
|
+
"properties": {
|
|
140
|
+
"core_version": { "type": "string" },
|
|
141
|
+
"platform_version": { "type": "string" },
|
|
142
|
+
"capability_version": { "type": "string" },
|
|
143
|
+
"installed": { "type": "string" },
|
|
144
|
+
"last_upgrade": { "type": "string" },
|
|
145
|
+
"migrated_from": { "type": "string" }
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
package/.dw/config/dw.config.yml
CHANGED
|
@@ -59,6 +59,20 @@ claude:
|
|
|
59
59
|
# Isolate execution trong git worktree (cho risky refactors)
|
|
60
60
|
worktree_execution: false
|
|
61
61
|
|
|
62
|
+
# --- Review render pipeline (ADR-0007) ------------------------------------
|
|
63
|
+
# /dw:review --visual produces a manifest.json then invokes `dw review render`.
|
|
64
|
+
# Output goes to .dw/reviews/{scope-slug}/ — see ADR-0007.
|
|
65
|
+
review:
|
|
66
|
+
renderer:
|
|
67
|
+
# auto: try dw-kit-render package, fall back to markdown summary if missing
|
|
68
|
+
# plugin: require dw-kit-render to be installed (fail if missing)
|
|
69
|
+
# markdown-only: never invoke a renderer, emit markdown summary only
|
|
70
|
+
strategy: "auto"
|
|
71
|
+
theme: "github-dark" # any shiki theme name
|
|
72
|
+
font: "JetBrains Mono" # font family for code in SVG
|
|
73
|
+
formats: ["svg", "png"] # outputs produced per finding
|
|
74
|
+
output_dir: ".dw/reviews"
|
|
75
|
+
|
|
62
76
|
# MCP servers — Claude Code sẽ load các servers này
|
|
63
77
|
mcp: []
|
|
64
78
|
# Ví dụ:
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": "1.0",
|
|
3
|
+
"fetched_at": "2026-05-12T09:57:47.323Z",
|
|
4
|
+
"source": "osv.dev",
|
|
5
|
+
"ecosystem": "npm",
|
|
6
|
+
"package_count": 13,
|
|
7
|
+
"advisory_count": 2,
|
|
8
|
+
"advisories": [
|
|
9
|
+
{
|
|
10
|
+
"id": "GHSA-q3j6-qgpj-74h6",
|
|
11
|
+
"summary": "fast-uri vulnerable to path traversal via percent-encoded dot segments",
|
|
12
|
+
"details": "### Impact\n\n`fast-uri` v3.1.0 and earlier decodes percent-encoded path separators (`%2F`) and dot segments (`%2E`) before applying dot-segment removal in `normalize()` and `equal()`. This makes encoded path data behave like real `/` and `..`, so distinct URIs collapse onto the same normalized path.\n\nFor example, `http://example.com/public/%2e%2e/admin` normalizes to `http://example.com/admin`, and `equal()` considers them the same URI.\n\nApplications that normalize or compare attacker-controlled URLs to enforce path-based policy can be bypassed. A path that looks confined under an allowed prefix can normalize to a different location.\n\n### Patches\n\nUpgrade to `fast-uri` >= 3.1.1.\n\n### Workarounds\n\nNone. Upgrade to the patched version.",
|
|
13
|
+
"aliases": [
|
|
14
|
+
"CVE-2026-6321"
|
|
15
|
+
],
|
|
16
|
+
"modified": "2026-05-09T16:44:22.524341929Z",
|
|
17
|
+
"published": "2026-05-08T17:15:09Z",
|
|
18
|
+
"related": [
|
|
19
|
+
"CGA-9j5f-2hwm-8hfc"
|
|
20
|
+
],
|
|
21
|
+
"database_specific": {
|
|
22
|
+
"cwe_ids": [
|
|
23
|
+
"CWE-22"
|
|
24
|
+
],
|
|
25
|
+
"github_reviewed": true,
|
|
26
|
+
"github_reviewed_at": "2026-05-08T17:15:09Z",
|
|
27
|
+
"severity": "HIGH",
|
|
28
|
+
"nvd_published_at": "2026-05-04T20:16:20Z"
|
|
29
|
+
},
|
|
30
|
+
"references": [
|
|
31
|
+
{
|
|
32
|
+
"type": "WEB",
|
|
33
|
+
"url": "https://github.com/fastify/fast-uri/security/advisories/GHSA-q3j6-qgpj-74h6"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"type": "ADVISORY",
|
|
37
|
+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-6321"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"type": "WEB",
|
|
41
|
+
"url": "https://cna.openjsf.org/security-advisories.html"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"type": "PACKAGE",
|
|
45
|
+
"url": "https://github.com/fastify/fast-uri"
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"affected": [
|
|
49
|
+
{
|
|
50
|
+
"package": {
|
|
51
|
+
"name": "fast-uri",
|
|
52
|
+
"ecosystem": "npm",
|
|
53
|
+
"purl": "pkg:npm/fast-uri"
|
|
54
|
+
},
|
|
55
|
+
"ranges": [
|
|
56
|
+
{
|
|
57
|
+
"type": "SEMVER",
|
|
58
|
+
"events": [
|
|
59
|
+
{
|
|
60
|
+
"introduced": "0"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"fixed": "3.1.1"
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"database_specific": {
|
|
69
|
+
"source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-q3j6-qgpj-74h6/GHSA-q3j6-qgpj-74h6.json",
|
|
70
|
+
"last_known_affected_version_range": "<= 3.1.0"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
],
|
|
74
|
+
"schema_version": "1.7.5",
|
|
75
|
+
"severity": [
|
|
76
|
+
{
|
|
77
|
+
"type": "CVSS_V3",
|
|
78
|
+
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N"
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"id": "GHSA-v39h-62p7-jpjc",
|
|
84
|
+
"summary": "fast-uri vulnerable to host confusion via percent-encoded authority delimiters",
|
|
85
|
+
"details": "### Impact\n\n`fast-uri` v3.1.1 and earlier decodes percent-encoded authority delimiters (`%40` as `@`, `%3A` as `:`) inside the host component and serializes them back as raw characters. This changes the URI structure, turning a hostname into userinfo plus a different host.\n\nFor example, `http://trusted.com%40evil.com/` normalizes to `http://trusted.com@evil.com/`, which reparses as host `evil.com` with userinfo `trusted.com`.\n\nApplications that normalize untrusted URLs before host allowlist checks, redirect validation, or outbound request routing can be steered to a different authority than the original URL appeared to contain.\n\n### Patches\n\nUpgrade to `fast-uri` >= 3.1.2.\n\n### Workarounds\n\nNone. Upgrade to the patched version.",
|
|
86
|
+
"aliases": [
|
|
87
|
+
"CVE-2026-6322"
|
|
88
|
+
],
|
|
89
|
+
"modified": "2026-05-10T04:44:28.903255090Z",
|
|
90
|
+
"published": "2026-05-08T19:13:01Z",
|
|
91
|
+
"related": [
|
|
92
|
+
"CGA-5vr9-c8qr-fqvg"
|
|
93
|
+
],
|
|
94
|
+
"database_specific": {
|
|
95
|
+
"cwe_ids": [
|
|
96
|
+
"CWE-436"
|
|
97
|
+
],
|
|
98
|
+
"github_reviewed": true,
|
|
99
|
+
"github_reviewed_at": "2026-05-08T19:13:01Z",
|
|
100
|
+
"severity": "HIGH",
|
|
101
|
+
"nvd_published_at": "2026-05-05T11:16:33Z"
|
|
102
|
+
},
|
|
103
|
+
"references": [
|
|
104
|
+
{
|
|
105
|
+
"type": "WEB",
|
|
106
|
+
"url": "https://github.com/fastify/fast-uri/security/advisories/GHSA-v39h-62p7-jpjc"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"type": "ADVISORY",
|
|
110
|
+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-6322"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"type": "WEB",
|
|
114
|
+
"url": "https://cna.openjsf.org/security-advisories.html"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"type": "PACKAGE",
|
|
118
|
+
"url": "https://github.com/fastify/fast-uri"
|
|
119
|
+
}
|
|
120
|
+
],
|
|
121
|
+
"affected": [
|
|
122
|
+
{
|
|
123
|
+
"package": {
|
|
124
|
+
"name": "fast-uri",
|
|
125
|
+
"ecosystem": "npm",
|
|
126
|
+
"purl": "pkg:npm/fast-uri"
|
|
127
|
+
},
|
|
128
|
+
"ranges": [
|
|
129
|
+
{
|
|
130
|
+
"type": "SEMVER",
|
|
131
|
+
"events": [
|
|
132
|
+
{
|
|
133
|
+
"introduced": "0"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"fixed": "3.1.2"
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
],
|
|
141
|
+
"database_specific": {
|
|
142
|
+
"source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-v39h-62p7-jpjc/GHSA-v39h-62p7-jpjc.json",
|
|
143
|
+
"last_known_affected_version_range": "<= 3.1.1"
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
"schema_version": "1.7.5",
|
|
148
|
+
"severity": [
|
|
149
|
+
{
|
|
150
|
+
"type": "CVSS_V3",
|
|
151
|
+
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N"
|
|
152
|
+
}
|
|
153
|
+
]
|
|
154
|
+
}
|
|
155
|
+
],
|
|
156
|
+
"snapshot_sha": "sha256:0b6ca61019fb234c"
|
|
157
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schema_version": "1.
|
|
3
|
-
"updated": "2026-05-
|
|
4
|
-
"purpose": "Curated namespace patterns under ACTIVE incident —
|
|
2
|
+
"schema_version": "1.1",
|
|
3
|
+
"updated": "2026-05-14",
|
|
4
|
+
"purpose": "Curated namespace patterns under ACTIVE incident — wired into default scan (v1.3.6+) AND pre-install scan. Auto-expires per active_until. TL updates when new incident requires fixture-level warning before OSV propagation. Per ADR-0006: pillar 2 of the 3-pillar guard architecture; pillar 3 (NEW-package heuristic) catches incidents BEFORE TL bump.",
|
|
5
5
|
"namespaces": [
|
|
6
6
|
{
|
|
7
7
|
"pattern": "@tanstack/",
|
|
@@ -9,7 +9,11 @@
|
|
|
9
9
|
"advisory": "https://github.com/advisories/GHSA-g7cv-rxg3-hmpx",
|
|
10
10
|
"active_until": "2026-11-11",
|
|
11
11
|
"severity": "critical",
|
|
12
|
-
"
|
|
12
|
+
"affected_range": {
|
|
13
|
+
"type": "SEMVER",
|
|
14
|
+
"events": [{ "introduced": "1.169.5" }, { "fixed": "1.169.9" }]
|
|
15
|
+
},
|
|
16
|
+
"guidance": "Affected: 1.169.5-1.169.8. Safe: 1.169.9+. Verify SLSA provenance attestation matches expected publisher. If lockfile already pins affected range: rotate ALL credentials (npm tokens, GitHub PATs, SSH keys, cloud keys, Claude/AI configs) before continuing."
|
|
13
17
|
},
|
|
14
18
|
{
|
|
15
19
|
"pattern": "@uipath/",
|
|
@@ -17,7 +21,7 @@
|
|
|
17
21
|
"advisory": "https://github.com/advisories/GHSA-g7cv-rxg3-hmpx",
|
|
18
22
|
"active_until": "2026-11-11",
|
|
19
23
|
"severity": "critical",
|
|
20
|
-
"guidance": "Verify each @uipath/* install against official UiPath release notes. Worm SLSA attestations are VALID — provenance check alone is insufficient. Cross-reference with UiPath security bulletin."
|
|
24
|
+
"guidance": "Verify each @uipath/* install against official UiPath release notes. Worm SLSA attestations are VALID — provenance check alone is insufficient. Cross-reference with UiPath security bulletin. (No affected_range — range still under investigation; treat all recent versions as suspect.)"
|
|
21
25
|
},
|
|
22
26
|
{
|
|
23
27
|
"pattern": "@mistralai/",
|
|
@@ -25,7 +29,11 @@
|
|
|
25
29
|
"advisory": "https://github.com/advisories/GHSA-g7cv-rxg3-hmpx",
|
|
26
30
|
"active_until": "2026-11-11",
|
|
27
31
|
"severity": "critical",
|
|
28
|
-
"
|
|
32
|
+
"affected_range": {
|
|
33
|
+
"type": "SEMVER",
|
|
34
|
+
"events": [{ "introduced": "2.2.3" }, { "fixed": "2.2.5" }]
|
|
35
|
+
},
|
|
36
|
+
"guidance": "Affected: 2.2.3-2.2.4. Pin to 2.2.2 or 2.2.5+."
|
|
29
37
|
},
|
|
30
38
|
{
|
|
31
39
|
"pattern": "@opensearch-project/opensearch",
|
|
@@ -33,8 +41,12 @@
|
|
|
33
41
|
"advisory": "https://github.com/advisories/GHSA-g7cv-rxg3-hmpx",
|
|
34
42
|
"active_until": "2026-11-11",
|
|
35
43
|
"severity": "critical",
|
|
36
|
-
"
|
|
44
|
+
"affected_range": {
|
|
45
|
+
"type": "SEMVER",
|
|
46
|
+
"events": [{ "introduced": "3.6.2" }, { "fixed": "3.6.3" }]
|
|
47
|
+
},
|
|
48
|
+
"guidance": "Affected: 3.6.2 only. Pin to 3.6.1 or 3.6.3+."
|
|
37
49
|
}
|
|
38
50
|
],
|
|
39
|
-
"maintenance_note": "
|
|
51
|
+
"maintenance_note": "Per ADR-0005 + ADR-0006: this fixture handles the 'TL knows about incident' window (post-incident, pre-OSV-propagation). Pillar 3 (NEW-package heuristic, ADR-0006) handles the 'nobody knows yet' window. TL prunes entries past active_until on regular release cycles."
|
|
40
52
|
}
|