fixyoursecret 0.4.0 → 0.4.3
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/CHANGELOG.md +35 -0
- package/README.md +4 -0
- package/package.json +3 -3
- package/utils/verifier.js +56 -18
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,41 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.4.3] - 2026-03-26
|
|
6
|
+
|
|
7
|
+
### Improved
|
|
8
|
+
- Further reduced residual generic noise on 500 quick corpus runs.
|
|
9
|
+
- Better path-segment detection for `test/spec/examples/docs` style locations.
|
|
10
|
+
- Added targeted generic suppressions for tutorial/audio/base64 and known non-secret artifacts.
|
|
11
|
+
- Strengthened placeholder suppression in non-production contexts.
|
|
12
|
+
- 500 quick tuning snapshot improved from 51 findings to 38 findings.
|
|
13
|
+
|
|
14
|
+
### CI/Release
|
|
15
|
+
- Release workflow now publishes a quality summary in job summary and uploads release-quality artifacts.
|
|
16
|
+
- Added release artifact bundle:
|
|
17
|
+
- `docs/tuning/report-500.json`
|
|
18
|
+
- `docs/tuning/false-positive-review-500.md`
|
|
19
|
+
- `docs/tuning/release-quality-summary.json`
|
|
20
|
+
|
|
21
|
+
## [0.4.2] - 2026-03-26
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
- Release automation now forces Trusted Publisher OIDC mode in GitHub Actions by unsetting token auth in publish step.
|
|
25
|
+
- Prevents npm auth-token fallback issues (`E404`) when publishing from tag workflow.
|
|
26
|
+
|
|
27
|
+
## [0.4.1] - 2026-03-26
|
|
28
|
+
|
|
29
|
+
### Improved
|
|
30
|
+
- Tightened residual generic-noise filtering for large real-world corpora:
|
|
31
|
+
- better `.test/.spec` context detection
|
|
32
|
+
- stronger URL/base64/tutorial-data suppression for generic detector paths
|
|
33
|
+
- additional non-production placeholder filtering for provider fixtures
|
|
34
|
+
- Reduced quick 500-corpus findings from 117 to 51 while preserving quality gates.
|
|
35
|
+
|
|
36
|
+
### CI/Release
|
|
37
|
+
- Switched release workflow to Trusted Publisher OIDC mode for npm publish.
|
|
38
|
+
- Kept tag-based automated publish via `.github/workflows/release-publish.yml`.
|
|
39
|
+
|
|
5
40
|
## [0.4.0] - 2026-03-26
|
|
6
41
|
|
|
7
42
|
### Added
|
package/README.md
CHANGED
|
@@ -227,6 +227,10 @@ Workflow file included:
|
|
|
227
227
|
|
|
228
228
|
It runs tests, benchmark gate, scan, and uploads SARIF.
|
|
229
229
|
|
|
230
|
+
Automated npm release workflow:
|
|
231
|
+
- [./.github/workflows/release-publish.yml](./.github/workflows/release-publish.yml)
|
|
232
|
+
- Triggered by pushing version tags like `v0.4.1`
|
|
233
|
+
|
|
230
234
|
---
|
|
231
235
|
|
|
232
236
|
## Publish
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fixyoursecret",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "CLI tool to detect leaked secrets, frontend exposure, and generate safe fixes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"fixyoursecret": "bin/index.js",
|
|
8
|
-
"secretlint": "bin/index.js"
|
|
7
|
+
"fixyoursecret": "./bin/index.js",
|
|
8
|
+
"secretlint": "./bin/index.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"bin/",
|
package/utils/verifier.js
CHANGED
|
@@ -74,8 +74,18 @@ export function shouldSkipAsNonSecret(match, snippet = "", filePath = "", hints
|
|
|
74
74
|
const lowerSnippet = snippet.toLowerCase();
|
|
75
75
|
const lowerPath = filePath.toLowerCase();
|
|
76
76
|
const value = String(match.value || "");
|
|
77
|
-
const isNonProdPath =
|
|
78
|
-
|
|
77
|
+
const isNonProdPath = (
|
|
78
|
+
hasPathSegment(lowerPath, "test") ||
|
|
79
|
+
hasPathSegment(lowerPath, "tests") ||
|
|
80
|
+
hasPathSegment(lowerPath, "__tests__") ||
|
|
81
|
+
hasPathSegment(lowerPath, "fixtures") ||
|
|
82
|
+
hasPathSegment(lowerPath, "docs") ||
|
|
83
|
+
hasPathSegment(lowerPath, "examples") ||
|
|
84
|
+
hasPathSegment(lowerPath, "spec") ||
|
|
85
|
+
hasPathSegment(lowerPath, "specs") ||
|
|
86
|
+
/\.test\.[a-z0-9]+$/i.test(lowerPath) ||
|
|
87
|
+
/\.spec\.[a-z0-9]+$/i.test(lowerPath)
|
|
88
|
+
);
|
|
79
89
|
|
|
80
90
|
const builtinHints = ["example", "dummy", "fake", "sample", "not_secret", "replace_in_runtime_only", "docs_only"];
|
|
81
91
|
const allHints = [...builtinHints, ...hints.map((h) => String(h).toLowerCase())];
|
|
@@ -94,26 +104,28 @@ export function shouldSkipAsNonSecret(match, snippet = "", filePath = "", hints
|
|
|
94
104
|
if (
|
|
95
105
|
match.rule === "generic-high-entropy" &&
|
|
96
106
|
[
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
"
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
"
|
|
105
|
-
"
|
|
106
|
-
"
|
|
107
|
-
"
|
|
108
|
-
"
|
|
109
|
-
"
|
|
110
|
-
"
|
|
111
|
-
|
|
107
|
+
"test",
|
|
108
|
+
"tests",
|
|
109
|
+
"__tests__",
|
|
110
|
+
"fixtures",
|
|
111
|
+
"docs",
|
|
112
|
+
"spec",
|
|
113
|
+
"specs",
|
|
114
|
+
"bench",
|
|
115
|
+
"benchmark",
|
|
116
|
+
"examples",
|
|
117
|
+
"migrations",
|
|
118
|
+
"generated",
|
|
119
|
+
"api-client",
|
|
120
|
+
"fonts",
|
|
121
|
+
"vendor"
|
|
122
|
+
].some((segment) => hasPathSegment(lowerPath, segment))
|
|
112
123
|
) {
|
|
113
124
|
return true;
|
|
114
125
|
}
|
|
115
126
|
|
|
116
127
|
if (match.rule === "generic-high-entropy") {
|
|
128
|
+
if (/(?:https?:\/\/|url:|href=|source:|fileName:|filename:|data:image|base64)/.test(lowerSnippet)) return true;
|
|
117
129
|
const genericNoiseHints = [
|
|
118
130
|
"canvasrenderingcontext2d",
|
|
119
131
|
"axios parameter creator",
|
|
@@ -132,11 +144,31 @@ export function shouldSkipAsNonSecret(match, snippet = "", filePath = "", hints
|
|
|
132
144
|
"anthropiccontext1m",
|
|
133
145
|
"bigint64arraybytes_per_element",
|
|
134
146
|
"claude-sonnet",
|
|
135
|
-
"gemini-"
|
|
147
|
+
"gemini-",
|
|
148
|
+
"oauth/callback?code=",
|
|
149
|
+
"audio-16khz-16bit",
|
|
150
|
+
"i18next-browser-languagedetector",
|
|
151
|
+
"msapplication-square70x70logo",
|
|
152
|
+
"apps.googleusercontent.com",
|
|
153
|
+
"downloaded-logs-",
|
|
154
|
+
"webkiformboundary",
|
|
155
|
+
"gpt-4o-realtime-preview",
|
|
156
|
+
"audio-16khz-32kbitrate",
|
|
157
|
+
"toolchain-profile.zip",
|
|
158
|
+
"gocspx-",
|
|
159
|
+
"useandom-"
|
|
136
160
|
];
|
|
137
161
|
if (genericNoiseHints.some((hint) => lowerSnippet.includes(hint))) return true;
|
|
138
162
|
}
|
|
139
163
|
|
|
164
|
+
if (
|
|
165
|
+
match.rule === "private-key-block" &&
|
|
166
|
+
isNonProdPath &&
|
|
167
|
+
/(?:example|dummy|placeholder|mock|do not share|xxxxx|\.{3})/.test(lowerSnippet)
|
|
168
|
+
) {
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
|
|
140
172
|
return false;
|
|
141
173
|
}
|
|
142
174
|
|
|
@@ -161,3 +193,9 @@ function hasDiversityScore(value, minClasses) {
|
|
|
161
193
|
].filter(Boolean).length;
|
|
162
194
|
return classes >= minClasses;
|
|
163
195
|
}
|
|
196
|
+
|
|
197
|
+
function hasPathSegment(filePath, segment) {
|
|
198
|
+
const escaped = segment.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
199
|
+
const re = new RegExp(`(?:^|/)${escaped}(?:/|$)`);
|
|
200
|
+
return re.test(filePath);
|
|
201
|
+
}
|