Skip to content

Commit 9217c38

Browse files
sectoramenunion
andauthored
fix(secrets): scope the line pre-check veto to benign manifest lines (#812)
* fix(secrets): scope the line pre-check veto to benign manifest lines containsSecretIndicators, the pre-check in front of the SECRETS keyword pass, ran three whole-line substring checks before its provider-literal admits: a version or boolean after the line's first colon, an "integrity"/"checksum" key beside the bytes sha or md5, and a "url"/"resolved"/"homepage" key beside a scheme and a registry or forge host. A hit dropped the whole line, so one "url" member hid an AKIA key ID, a ghp_/glpat-/xoxb- token, a JWT or a keyword-assigned password anywhere else on it: no finding, no redacted copy, --pre-commit-mode exit 0, and the --stdin redaction gateway passed the token through. The provider-literal admits (JWT, every provider prefix, PEM markers) now run first, and the three checks are replaced by one veto, benignManifestLine, that rejects a line only when (a) it is exactly one JSON member whose value is a version under 20 bytes, a boolean, an SRI digest or a URL with no user info, query or '=', (b) no keyword stem from the lists the keyword patterns are compiled from appears anywhere on it, and (c) one of the old checks fires as well, so the veto is a subset of what was skipped before. Checking only the key, as the issue's prototype does, is unsound: in "https://api.session:8443/..." the unquoted pattern reads `session:` as an assignment. findKeywordSecrets is split into the gate and keywordCandidates so that the gate's contract (a rejected line has no candidate) is tested. Measured against v2.5.5 on identical inputs: the issue's nine triggers report what their controls report (30 of 30 draws); matrix 1 goes from 99 to 0 of 143 trigger cells reporting nothing (controls 78/78 on both); every matrix 2 cell, as low as 0/40 before, is 40/40; the redacted copies, pre-commit exits and stdin gateway are fixed. No existing finding changes type, text, line or confidence on the matrices, the reproduction, 39 public npm lockfiles or 3,691 public files that hit an old check, and main's suppression rules still suppress all of them. The veto still skips 99.1% of the lockfile lines the old checks skipped; SECRETS CPU on those lockfiles is 3-6% above v2.5.5 (with no veto at all, 2.7x). Closes #765 * test(goldencorpus): state the #765 trigger case's password length right The fifth line of secrets_line_veto_triggers carries a 41-byte password, not the 40-byte one its description named. The value stays 41 bytes: a 40-byte value beside an AKIA key ID is the shape secret scanners read as an AWS key pair. Description only; no snapshot changes. Refs #765 * docs(changelog): count all 31 seeded draws in the #765 entry The reproduction ran on seeds 1-31; the entry quoted the 30 draws of seeds 2-31. On all 31 every trigger reports what its control reports, and main lost the 40-character password on 10 of them. Refs #765 * chore(goldencorpus,changelog): rebase #765 onto main after #811 The rebase onto main (now carrying #811 and #799) auto-merged the #765 bullet into the Security section below the Go 1.27.3 entry; it is a bug fix, so it moves under Bug Fixes, as its first entry: #813 appends its own bullet after the #773 entry, and two PRs inserting at one seam would conflict again at the second merge; distinct anchors merge in either order. corpus.go: both #811 (overlap_groups_render_once) and #765 (the two line-veto cases) appended to the case table; keep all three in that order. The metadata key census is regenerated on top of main: the only movement is +14 findings at 13 keys, which is the secrets_line_veto_triggers case; no other bucket and no existing snapshot changed, and the two new snapshots are byte-identical to the ones committed before the rebase. --------- Co-authored-by: union <union@example.invalid>
1 parent 10ef847 commit 9217c38

26 files changed

Lines changed: 3922 additions & 74 deletions

‎CHANGELOG.md‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616

1717
### 🐛 Bug Fixes
1818

19+
- **secrets (line pre-check):** a `"url"`, `"checksum"` or version/boolean member anywhere on a line no
20+
longer switches off token and keyword detection for that line
21+
([#765](https://github.com/awslabs/ferret-scan/issues/765)). `containsSecretIndicators`, the pre-check
22+
in front of the keyword pass, ran three whole-line substring checks before its provider-literal
23+
admits, and a hit dropped the line: one `"url": "https://github.com/…"` member, a
24+
`"bucket": "shared-assets"` beside a `"checksum"` key (`shared` holds `sha`) or a trailing
25+
`"verbose": true` hid an AKIA key ID, a `ghp_`/`glpat-`/`xoxb-` token, a JWT or a keyword-assigned
26+
password anywhere else on it. Nothing reached the redactor, so no redacted copy was written,
27+
`--pre-commit-mode` exited 0 and the `--stdin --enable-redaction` gateway passed the token through.
28+
Measured on v2.5.5 with the issue's nine trigger files and their one-word controls: seven reported
29+
nothing where the control reported every value, one (`"url"` beside a 40-character password) lost
30+
its AKIA key ID on every draw and the password on 10 of 31, and one reported only the token that
31+
#766's URI source finds outside the pre-check; 99 of 143 cells of 13 secret shapes × 11 trigger
32+
contexts reported nothing; `glpat-`, `xoxb-`, AKIA, JWT and 12–20-character passwords were found 0
33+
of 40 times after a `"url"` or `"integrity"` member and 40 of 40 after `"name"`. Now the
34+
provider-literal admits (JWT, every provider prefix, PEM markers) run first, and the three checks
35+
are replaced by one veto that skips a line only when it is wholly one benign manifest member — a
36+
version under 20 bytes, a boolean, an SRI digest or a URL with no user info, query or `=` — with no
37+
keyword stem anywhere on it, and was skipped before. Every trigger now reports what its control
38+
reports (31 of 31 seeded draws), all 143 cells and every matrix cell (40 of 40) detect the value,
39+
the lockfile decoy stays silent, both redacted copies hold no value, both pre-commit runs exit 1
40+
and the gateway emits no token. **New findings only:** on the matrices,
41+
the reproduction, 39 public npm lockfiles and 3,691 public files that hit one of the old checks, no
42+
existing finding changes type, text, line or confidence, and main's suppression rules still suppress
43+
every one of them; on a line whose token in URL user info is also a provider literal, the finding's
44+
`detection_method` now reads `keyword_pattern` instead of `uri_userinfo`. One shape, absent from all
45+
of those sets, does change an existing finding: a password in the user info of a `"url"`,
46+
`"resolved"` or `"homepage"` URL on a registry or forge host whose user name ends in a keyword stem
47+
(`https://deploy-token:<pw>@registry…`) is now reported, as on every other line, as the keyword
48+
pass's wider `<pw>@host/path` span, so a rule written against the narrower finding must be
49+
regenerated. The veto still skips 99.1% of the lockfile lines the old checks skipped; SECRETS CPU on
50+
those lockfiles is 3–6% above v2.5.5 (deleting the checks outright measured 2.7x).
1951
- **redaction (overlapping findings):** two findings on one line whose values share bytes are now one
2052
write over their union, in every writer, so no part of either survives and which one is written no
2153
longer depends on input order ([#773](https://github.com/awslabs/ferret-scan/issues/773)). Each writer
@@ -39,6 +71,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3971
instead of writing part of it, and the audit log records one entry per group with every member's type
4072
in `member_types`. The `secrets_uri_userinfo_email_overlap` snapshot now masks the password's first
4173
character, which the email's mask used to keep.
74+
4275
### 🔒 Security
4376

4477
- **build (go 1.27.3):** move every Go pin to **1.27.3**, which carries the fix for the one open Go

‎internal/goldencorpus/corpus.go‎

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ package goldencorpus
2323
import (
2424
"archive/zip"
2525
"bytes"
26+
"crypto/sha512"
27+
"encoding/base64"
2628
"encoding/binary"
2729
"encoding/json"
2830
"encoding/xml"
@@ -57,6 +59,13 @@ func stripeKey(tag byte, bodyLen int) string {
5759
return "pk_" + "live_" + body[:bodyLen-1] + "1"
5860
}
5961

62+
// sriDigest is a real Subresource Integrity value, `sha512-` and the base64 SHA-512 of name, the
63+
// shape npm writes in every lockfile "integrity" member.
64+
func sriDigest(name string) string {
65+
sum := sha512.Sum512([]byte(name))
66+
return "sha512-" + base64.StdEncoding.EncodeToString(sum[:])
67+
}
68+
6069
// Case is one corpus entry: a named input plus the validator set to run against
6170
// it. Keeping checks explicit per-case (rather than always "all") makes each
6271
// snapshot small, focused, and stable — adding a new validator does not churn
@@ -534,6 +543,110 @@ var Cases = []Case{
534543
"call +1 449-87-4100\n" +
535544
"call 212-555-0142 or card 4532-0151-1283-0366\n",
536545
},
546+
{
547+
Name: "secrets_line_veto_triggers",
548+
Description: "The #765 false negative: a benign manifest member anywhere on a line switched the " +
549+
"keyword pass off for the WHOLE line. containsSecretIndicators ran three whole-line " +
550+
"substring checks before its provider-literal admits -- a version or boolean after the " +
551+
"line's first colon, an \"integrity\"/\"checksum\" key beside the bytes `sha` or `md5`, " +
552+
"a \"url\"/\"resolved\"/\"homepage\" key beside a scheme and a registry or forge host -- " +
553+
"and a hit dropped the line, so nothing on it reached a redacted copy, the pre-commit " +
554+
"exit status or the stdin gateway.\n" +
555+
" These are the issue's nine triggers, one per line. Lines 1-5 are the URL check: a " +
556+
"`\"url\"` member beside a password and an AWS key ID, a JSON-lines request log with a " +
557+
"GitHub token in its Authorization header, a token in a `\"url\"`'s user info, a minified " +
558+
"config whose `\"homepage\"` hid a Stripe key and a password, and the first line again " +
559+
"with a 41-byte password. Line 6 is the checksum check fired by `shared-assets`. Lines 7-9 " +
560+
"are the version/boolean check: a `\"verbose\": true` in a trailing shell comment, a " +
561+
"provider literal as a key with a boolean value, and a password whose value looks like a " +
562+
"version. Before the fix lines 1-4 and 6-9 reported nothing (line 3's token alone was " +
563+
"found, by #766's URI source, which runs outside the gate) and line 5 only its 41-byte " +
564+
"value. Each must now report what the line reports with the member's key, host or word " +
565+
"changed, and the redaction snapshots must show no byte of any value. The values are " +
566+
"synthetic: consonants and digits, the AWS key ID and GitHub token other cases already " +
567+
"use. The issue's minified config carries a Slack bot token; a publishable Stripe key (see " +
568+
"stripeKey) stands in for it, because push protection refuses a Slack-shaped value in a " +
569+
"committed snapshot and any provider literal shows the same thing.",
570+
Checks: []string{"SECRETS"},
571+
Input: "{\"url\": \"https://github.com/orders/app\", \"password\": \"Vn3kQ8tZp6Wd2sHx\", \"key_id\": \"AKIA" + "QZ7MK2PL9VNB4RTX\"}\n" +
572+
"{\"ts\":\"2026-01-01T00:00:00Z\",\"method\":\"GET\",\"url\":\"https://api.github.com/user\",\"headers\":{\"Authorization\":\"token ghp_" + "Q7mZ2vX9pL4kR8tB1nW6yC3hJ5dF0sG2aE7u\"}}\n" +
573+
" \"url\": \"git+https://x-access-token:ghp_" + "Q7mZ2vX9pL4kR8tB1nW6yC3hJ5dF0sG2aE7u@github.com/orders/app.git\"\n" +
574+
"{\"name\":\"svc\",\"version\":\"0.0.1\",\"homepage\":\"https://github.com/orders/svc\",\"db\":{\"host\":\"db.invalid\",\"password\":\"Hc4Rw9Tq2Mz7Kb5N\"},\"stripe\":{\"publishable_key\":\"" + stripeKey('d', 30) + "\"}}\n" +
575+
"{\"url\": \"https://github.com/orders/app\", \"password\": \"Rk7Pq2Wz9Mx4Lc8Vb3Nt6Hd5Gf2Js7Kw9Qp4Zr3Tn\", \"key_id\": \"AKIA" + "QZ7MK2PL9VNB4RTX\"}\n" +
576+
"{\"bucket\":\"shared-assets\",\"checksum\":\"crc32:00000000\",\"password\":\"Jx8Bv3Nq6Wr2Kt9P\",\"key_id\":\"AKIA" + "QZ7MK2PL9VNB4RTX\"}\n" +
577+
"export API_TOKEN=Mz5Hq8Tc3Vw7Rb2K # \"verbose\": true\n" +
578+
" \"AKIA" + "QZ7MK2PL9VNB4RTX\": true\n" +
579+
" \"password\": \"7.Kq4Zt9Wm2B\"\n",
580+
},
581+
{
582+
Name: "secrets_line_veto_lockfile_decoys",
583+
Description: "The lines the #765 veto exists for, which must stay EMPTY: an npm v3 lockfile and a " +
584+
"package.json excerpt. Since #765 the keyword pass skips a line only when it is wholly one " +
585+
"benign manifest member -- a version under 20 bytes, a boolean, an SRI digest, or a URL with " +
586+
"no user info, query or `=` -- carries no keyword stem, and was skipped before. Every " +
587+
"version, resolved, integrity, dev, homepage and repository line here is such a line. The " +
588+
"ones that are not (the `||` range, the sponsor URL with its query, `js-tokens`, which " +
589+
"spells the stem `token`) are scanned again, find nothing, and must stay empty too. The " +
590+
"digests are real SHA-512 digests of the package names. `\"dev\": true` makes this file " +
591+
"`development` for the file-wide environment verdict, as it does on main.",
592+
Checks: []string{"SECRETS"},
593+
Input: "{\n" +
594+
" \"name\": \"orders-app\",\n" +
595+
" \"version\": \"1.0.0\",\n" +
596+
" \"lockfileVersion\": 3,\n" +
597+
" \"requires\": true,\n" +
598+
" \"packages\": {\n" +
599+
" \"node_modules/left-pad\": {\n" +
600+
" \"version\": \"1.3.0\",\n" +
601+
" \"resolved\": \"https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz\",\n" +
602+
" \"integrity\": \"" + sriDigest("left-pad") + "\",\n" +
603+
" \"dev\": true,\n" +
604+
" \"license\": \"WTFPL\"\n" +
605+
" },\n" +
606+
" \"node_modules/@babel/core\": {\n" +
607+
" \"version\": \"7.22.5\",\n" +
608+
" \"resolved\": \"https://registry.npmjs.org/@babel/core/-/core-7.22.5.tgz\",\n" +
609+
" \"integrity\": \"" + sriDigest("@babel/core") + "\",\n" +
610+
" \"dependencies\": {\n" +
611+
" \"debug\": \"^4.1.0\",\n" +
612+
" \"semver\": \"^6.3.1\",\n" +
613+
" \"js-tokens\": \"^4.0.0\",\n" +
614+
" \"chalk\": \"^3.0.0 || ^4.0.0\"\n" +
615+
" },\n" +
616+
" \"engines\": {\n" +
617+
" \"node\": \">=6.9.0\"\n" +
618+
" },\n" +
619+
" \"funding\": {\n" +
620+
" \"type\": \"opencollective\",\n" +
621+
" \"url\": \"https://opencollective.com/babel\"\n" +
622+
" }\n" +
623+
" },\n" +
624+
" \"node_modules/js-tokens\": {\n" +
625+
" \"version\": \"4.0.0\",\n" +
626+
" \"resolved\": \"https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz\",\n" +
627+
" \"integrity\": \"" + sriDigest("js-tokens") + "\",\n" +
628+
" \"optional\": true\n" +
629+
" },\n" +
630+
" \"node_modules/ansi-styles\": {\n" +
631+
" \"version\": \"6.2.1\",\n" +
632+
" \"resolved\": \"https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz\",\n" +
633+
" \"integrity\": \"" + sriDigest("ansi-styles") + "\",\n" +
634+
" \"funding\": {\n" +
635+
" \"url\": \"https://github.com/chalk/ansi-styles?sponsor=1\"\n" +
636+
" }\n" +
637+
" }\n" +
638+
" },\n" +
639+
" \"homepage\": \"https://github.com/orders/app#readme\",\n" +
640+
" \"repository\": {\n" +
641+
" \"type\": \"git\",\n" +
642+
" \"url\": \"git+https://github.com/orders/app.git\"\n" +
643+
" },\n" +
644+
" \"bugs\": {\n" +
645+
" \"url\": \"https://gitlab.com/orders/app/-/issues\"\n" +
646+
" },\n" +
647+
" \"checksum\": \"" + sriDigest("orders-app") + "\"\n" +
648+
"}\n",
649+
},
537650
{
538651
Name: "ip_addresses",
539652
Description: "Public vs private/loopback IPv4; locks IP_ADDRESS context handling.",

‎internal/goldencorpus/testdata/golden/metadata-key-census.txt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ VISA keys=13 band=1
468468
# 10 keys: 26 findings (band 1)
469469
# 11 keys: 22 findings (band 1)
470470
# 12 keys: 14 findings (band 1)
471-
# 13 keys: 88 findings (band 1)
471+
# 13 keys: 102 findings (band 1)
472472
# 14 keys: 18 findings (band 1)
473473
# 15 keys: 30 findings (band 2)
474474
# 17 keys: 1 findings (band 2)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Filename,Type,Confidence Level,Confidence %,Line Number,Text
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"remediations": [],
3+
"scan": {
4+
"analyzer": {
5+
"id": "ferret-scan",
6+
"name": "Ferret Scan",
7+
"url": "https://github.com/awslabs/ferret-scan",
8+
"vendor": {
9+
"name": "Amazon Web Services"
10+
},
11+
"version": "0.0.0-development"
12+
},
13+
"end_time": "<TIMESTAMP>",
14+
"scanner": {
15+
"id": "ferret-scan",
16+
"name": "Ferret Scan",
17+
"url": "https://github.com/awslabs/ferret-scan",
18+
"vendor": {
19+
"name": "Amazon Web Services"
20+
},
21+
"version": "0.0.0-development"
22+
},
23+
"start_time": "<TIMESTAMP>",
24+
"status": "success",
25+
"type": "sast"
26+
},
27+
"version": "15.0.4",
28+
"vulnerabilities": []
29+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"results": []
3+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<testsuites name="ferret-scan" tests="0" failures="0" errors="0" time="0.000">
3+
<testsuite name="security-scan" tests="0" failures="0" errors="0" time="0.000"></testsuite>
4+
</testsuites>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
=== REDACTED ===
2+
{
3+
"name": "orders-app",
4+
"version": "1.0.0",
5+
"lockfileVersion": 3,
6+
"requires": true,
7+
"packages": {
8+
"node_modules/left-pad": {
9+
"version": "1.3.0",
10+
"resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz",
11+
"integrity": "sha512-XRcglhh3p2lHAu4gFg75i5owZ3/uttIZh11iKj+W2fqc4Iu8OvwIHkDSftaw4gURo0WA2fT2oguwTa4HChLwJw==",
12+
"dev": true,
13+
"license": "WTFPL"
14+
},
15+
"node_modules/@babel/core": {
16+
"version": "7.22.5",
17+
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.5.tgz",
18+
"integrity": "sha512-A/7v7t3swT1cyX5u/GhFT+yzhPPSdlJHh0dfFfuBJs/T6uhVVD4namjWQM5JVWUzdCVXmbe6CY1TKJv9RAOcsw==",
19+
"dependencies": {
20+
"debug": "^4.1.0",
21+
"semver": "^6.3.1",
22+
"js-tokens": "^4.0.0",
23+
"chalk": "^3.0.0 || ^4.0.0"
24+
},
25+
"engines": {
26+
"node": ">=6.9.0"
27+
},
28+
"funding": {
29+
"type": "opencollective",
30+
"url": "https://opencollective.com/babel"
31+
}
32+
},
33+
"node_modules/js-tokens": {
34+
"version": "4.0.0",
35+
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
36+
"integrity": "sha512-fIvNBV3y6EBRV/ibHHjLBDSpRbdhtKXf61DSzOV50xIpPgfbW/5lxDDVRmx4fZwRHf77QMVfworHea2SkYxOUA==",
37+
"optional": true
38+
},
39+
"node_modules/ansi-styles": {
40+
"version": "6.2.1",
41+
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
42+
"integrity": "sha512-EhXoniJkJjbZMaPS9yC77u2K93fKsYbaCeSyOCRST6uRDoAjzpTgKzF+7j3yt8UFq8cS9s+2q1DnnuYgNymgMQ==",
43+
"funding": {
44+
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
45+
}
46+
}
47+
},
48+
"homepage": "https://github.com/orders/app#readme",
49+
"repository": {
50+
"type": "git",
51+
"url": "git+https://github.com/orders/app.git"
52+
},
53+
"bugs": {
54+
"url": "https://gitlab.com/orders/app/-/issues"
55+
},
56+
"checksum": "sha512-J+kyFiBsBm/fD8hhvHNNhwAwtxrtThSi5Bex9sbmegf4MdcWwPTn+Mv/OmIAJTWuSKOctlW0Iduj4/oo6+BT9w=="
57+
}
58+
=== FINDINGS (sorted) ===
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
=== REDACTED ===
2+
{
3+
"name": "orders-app",
4+
"version": "1.0.0",
5+
"lockfileVersion": 3,
6+
"requires": true,
7+
"packages": {
8+
"node_modules/left-pad": {
9+
"version": "1.3.0",
10+
"resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz",
11+
"integrity": "sha512-XRcglhh3p2lHAu4gFg75i5owZ3/uttIZh11iKj+W2fqc4Iu8OvwIHkDSftaw4gURo0WA2fT2oguwTa4HChLwJw==",
12+
"dev": true,
13+
"license": "WTFPL"
14+
},
15+
"node_modules/@babel/core": {
16+
"version": "7.22.5",
17+
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.5.tgz",
18+
"integrity": "sha512-A/7v7t3swT1cyX5u/GhFT+yzhPPSdlJHh0dfFfuBJs/T6uhVVD4namjWQM5JVWUzdCVXmbe6CY1TKJv9RAOcsw==",
19+
"dependencies": {
20+
"debug": "^4.1.0",
21+
"semver": "^6.3.1",
22+
"js-tokens": "^4.0.0",
23+
"chalk": "^3.0.0 || ^4.0.0"
24+
},
25+
"engines": {
26+
"node": ">=6.9.0"
27+
},
28+
"funding": {
29+
"type": "opencollective",
30+
"url": "https://opencollective.com/babel"
31+
}
32+
},
33+
"node_modules/js-tokens": {
34+
"version": "4.0.0",
35+
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
36+
"integrity": "sha512-fIvNBV3y6EBRV/ibHHjLBDSpRbdhtKXf61DSzOV50xIpPgfbW/5lxDDVRmx4fZwRHf77QMVfworHea2SkYxOUA==",
37+
"optional": true
38+
},
39+
"node_modules/ansi-styles": {
40+
"version": "6.2.1",
41+
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
42+
"integrity": "sha512-EhXoniJkJjbZMaPS9yC77u2K93fKsYbaCeSyOCRST6uRDoAjzpTgKzF+7j3yt8UFq8cS9s+2q1DnnuYgNymgMQ==",
43+
"funding": {
44+
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
45+
}
46+
}
47+
},
48+
"homepage": "https://github.com/orders/app#readme",
49+
"repository": {
50+
"type": "git",
51+
"url": "git+https://github.com/orders/app.git"
52+
},
53+
"bugs": {
54+
"url": "https://gitlab.com/orders/app/-/issues"
55+
},
56+
"checksum": "sha512-J+kyFiBsBm/fD8hhvHNNhwAwtxrtThSi5Bex9sbmegf4MdcWwPTn+Mv/OmIAJTWuSKOctlW0Iduj4/oo6+BT9w=="
57+
}
58+
=== FINDINGS (sorted) ===
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/refs/heads/main/sarif-2.1/schema/sarif-schema-2.1.0.json",
3+
"runs": [
4+
{
5+
"results": [],
6+
"tool": {
7+
"driver": {
8+
"informationUri": "https://github.com/awslabs/ferret-scan",
9+
"name": "Ferret Scan",
10+
"semanticVersion": "0.0.0-development",
11+
"version": "0.0.0-development"
12+
}
13+
}
14+
}
15+
],
16+
"version": "2.1.0"
17+
}

0 commit comments

Comments
 (0)