@codacy/tools-opengrep-1 0.23.0 → 0.24.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/README.md +34 -6
- package/dist/index.js +119 -12
- package/dist/metadata.js +109 -7
- package/package.json +2 -2
- package/src/rules.yaml +26764 -13237
package/README.md
CHANGED
|
@@ -24,20 +24,47 @@ Multi-language SAST (Static Application Security Testing) scanner using the [Ope
|
|
|
24
24
|
| Strategy | CLI |
|
|
25
25
|
| Languages | 30+ (Python, JavaScript, TypeScript, Java, Go, Ruby, C, C++, etc.) |
|
|
26
26
|
| Binary | `opengrep` |
|
|
27
|
-
| File patterns |
|
|
27
|
+
| File patterns | ~70 extensions derived from the languages above, plus `Dockerfile` |
|
|
28
28
|
| Pattern count | ~2500 |
|
|
29
29
|
| Extra dependency | `yaml` (for YAML rule config parsing/generation) |
|
|
30
30
|
|
|
31
31
|
## Rule bundling
|
|
32
32
|
|
|
33
|
-
Opengrep uses YAML rule files for detection. The adapter bundles ~
|
|
33
|
+
Opengrep uses YAML rule files for detection. The adapter bundles ~2500 rules into `src/rules.yaml`, sourced from:
|
|
34
34
|
|
|
35
|
-
1. **
|
|
36
|
-
2. **GitLab SAST rules** — MIT-licensed
|
|
37
|
-
3. **Codacy custom rules** —
|
|
35
|
+
1. **opengrep/opengrep-rules** — the registry rules, pinned at the same commit as the Codacy image
|
|
36
|
+
2. **GitLab SAST rules** — MIT-licensed, from `gitlab.com/gitlab-org/security-products/sast-rules`
|
|
37
|
+
3. **Codacy custom rules** — `docs/codacy-rules*.yaml` in `codacy/codacy-opengrep`
|
|
38
38
|
|
|
39
39
|
The bundled `src/rules.yaml` is **committed to the repository** for consistency and reproducibility.
|
|
40
40
|
|
|
41
|
+
### Keeping it in step with the Codacy image
|
|
42
|
+
|
|
43
|
+
All three sources, their pinned commits and their file filters are mirrored from
|
|
44
|
+
`codacy/codacy-opengrep`'s `internal/docgen/parsing.go`. Keep them that way: the image is the
|
|
45
|
+
reference implementation, and `scripts/fetch-rules.mjs` says which upstream function each piece
|
|
46
|
+
came from.
|
|
47
|
+
|
|
48
|
+
Three mistakes in that mirroring cost **296 of 2534 patterns (12%)**, every one of them silent —
|
|
49
|
+
the pattern stays in `patterns.json`, `init --auto` enables it, the config claims it is active, and
|
|
50
|
+
it simply never fires:
|
|
51
|
+
|
|
52
|
+
- **Rule ids were derived from the file path.** GitLab ids are written in the file and must be
|
|
53
|
+
taken verbatim. Path derivation looks right for the top-level tree (`java/crypto/rule-X.yml`
|
|
54
|
+
really does hold `java_crypto_rule-X`) and is wrong for the licence-tiered one, where
|
|
55
|
+
`rules/lgpl-cc/properties/spring/accesscontrol/rule-Y.yml` holds `properties_spring_rule-Y`. The
|
|
56
|
+
sharpest case is `rule-JwtDecodeWithoutVerify.yml`, whose id uses an underscore where the
|
|
57
|
+
filename uses a hyphen. 265 of 588 GitLab rules were lost this way.
|
|
58
|
+
- **The registry source was upstream `semgrep/semgrep-rules`**, not Opengrep's fork. The two share
|
|
59
|
+
most ids, so the output looks plausible while individual rules go missing.
|
|
60
|
+
- **YAML was read and rewritten line by line.** That corrupted multi-line flow scalars — the
|
|
61
|
+
generated file stopped parsing, and opengrep then reported _zero findings for the entire run_
|
|
62
|
+
rather than an error — and it skipped every `tests/` directory, where some shipped rules live.
|
|
63
|
+
|
|
64
|
+
`test/rules-coverage.test.ts` is the guard: it fails if any catalogued pattern has no rule, and if
|
|
65
|
+
the generated file does not parse. Run `pnpm fetch-rules` when it does; the script prints the
|
|
66
|
+
orphaned ids.
|
|
67
|
+
|
|
41
68
|
## Updating patterns
|
|
42
69
|
|
|
43
70
|
```bash
|
|
@@ -57,7 +84,8 @@ Pattern IDs follow the format `Semgrep_python.lang.security.audit.exec-detected.
|
|
|
57
84
|
pnpm fetch-rules
|
|
58
85
|
|
|
59
86
|
# This clones the rule repos, extracts matching rules, and writes src/rules.yaml
|
|
60
|
-
# Only rules whose IDs match src/patterns.json are included
|
|
87
|
+
# Only rules whose IDs match src/patterns.json are included — and the script now
|
|
88
|
+
# warns loudly about the reverse, a catalogued pattern with no rule to run.
|
|
61
89
|
|
|
62
90
|
# Commit the result
|
|
63
91
|
git add src/rules.yaml
|
package/dist/index.js
CHANGED
|
@@ -30722,14 +30722,18 @@ var pattern_mappings_default = {
|
|
|
30722
30722
|
// src/metadata.ts
|
|
30723
30723
|
var descriptor = {
|
|
30724
30724
|
id: "Semgrep",
|
|
30725
|
+
shortName: "opengrep",
|
|
30725
30726
|
displayName: "Opengrep",
|
|
30726
30727
|
preferredVersion: "1.26.0",
|
|
30728
|
+
// Canonical `KNOWN_LANGUAGES` names, which is what `init --auto` matches against
|
|
30729
|
+
// (`init.ts:882`). The engine's own names differ and must be translated here:
|
|
30730
|
+
// Bash/Shell and Vue/Javascript collapse onto one entry each, since `.sh` and
|
|
30731
|
+
// `.vue` are already those languages. Guarded by `descriptor-languages.test.ts`.
|
|
30727
30732
|
languages: [
|
|
30728
30733
|
"Apex",
|
|
30729
|
-
"Bash",
|
|
30730
30734
|
"C",
|
|
30731
|
-
"
|
|
30732
|
-
"
|
|
30735
|
+
"CPP",
|
|
30736
|
+
"CSharp",
|
|
30733
30737
|
"Clojure",
|
|
30734
30738
|
"Dart",
|
|
30735
30739
|
"Dockerfile",
|
|
@@ -30737,7 +30741,7 @@ var descriptor = {
|
|
|
30737
30741
|
"Go",
|
|
30738
30742
|
"HTML",
|
|
30739
30743
|
"Java",
|
|
30740
|
-
"
|
|
30744
|
+
"Javascript",
|
|
30741
30745
|
"JSON",
|
|
30742
30746
|
"Kotlin",
|
|
30743
30747
|
"Lua",
|
|
@@ -30750,12 +30754,110 @@ var descriptor = {
|
|
|
30750
30754
|
"Swift",
|
|
30751
30755
|
"Terraform",
|
|
30752
30756
|
"TypeScript",
|
|
30753
|
-
"
|
|
30754
|
-
"Vue",
|
|
30757
|
+
"VisualBasic",
|
|
30755
30758
|
"XML",
|
|
30756
30759
|
"YAML"
|
|
30757
30760
|
],
|
|
30758
|
-
|
|
30761
|
+
// Derived from `languages` above, via `LANGUAGE_CONFIG`, plus the extensions
|
|
30762
|
+
// sibling adapters already route for those same languages (`.cjs`, `.hh`,
|
|
30763
|
+
// `.jsonc`, `.json5`, `.pyi`, `.dash`, `.ksh`) — `LANGUAGE_CONFIG` is a
|
|
30764
|
+
// detection map and does not claim to be exhaustive per tool.
|
|
30765
|
+
//
|
|
30766
|
+
// This was `["*"]`, which `routeFilesToTool` short-circuits to "every file", so
|
|
30767
|
+
// opengrep was handed the whole repository: on one 1774-file repo, 358 of them
|
|
30768
|
+
// (20%) were png/jpg/font assets. Opengrep resolves a language by extension and
|
|
30769
|
+
// skips what it cannot parse, so findings were never affected — but the paths
|
|
30770
|
+
// still cost a realpath+stat each, inflated the reported file count, and ate the
|
|
30771
|
+
// 200 KB argv budget, splitting one `opengrep scan` into two.
|
|
30772
|
+
//
|
|
30773
|
+
// Keep this a superset of `LANGUAGE_CONFIG`'s extensions for every declared
|
|
30774
|
+
// language; `opengrep-1/test/file-patterns.test.ts` fails if a language gains one
|
|
30775
|
+
// that is not routed here, because a missed extension is a silent coverage loss.
|
|
30776
|
+
filePatterns: [
|
|
30777
|
+
"**/*.bash",
|
|
30778
|
+
"**/*.c",
|
|
30779
|
+
"**/*.cc",
|
|
30780
|
+
"**/*.cjs",
|
|
30781
|
+
"**/*.clj",
|
|
30782
|
+
"**/*.cljc",
|
|
30783
|
+
"**/*.cljs",
|
|
30784
|
+
"**/*.cls",
|
|
30785
|
+
"**/*.cpp",
|
|
30786
|
+
"**/*.cs",
|
|
30787
|
+
"**/*.cxx",
|
|
30788
|
+
"**/*.dart",
|
|
30789
|
+
"**/*.dash",
|
|
30790
|
+
"**/*.dockerfile",
|
|
30791
|
+
"**/*.edn",
|
|
30792
|
+
"**/*.env",
|
|
30793
|
+
"**/*.ex",
|
|
30794
|
+
"**/*.exs",
|
|
30795
|
+
"**/*.gemspec",
|
|
30796
|
+
"**/*.go",
|
|
30797
|
+
"**/*.h",
|
|
30798
|
+
"**/*.hh",
|
|
30799
|
+
"**/*.hpp",
|
|
30800
|
+
"**/*.htm",
|
|
30801
|
+
"**/*.html",
|
|
30802
|
+
"**/*.ino",
|
|
30803
|
+
"**/*.java",
|
|
30804
|
+
"**/*.jbuilder",
|
|
30805
|
+
"**/*.js",
|
|
30806
|
+
"**/*.jsm",
|
|
30807
|
+
"**/*.json",
|
|
30808
|
+
"**/*.json5",
|
|
30809
|
+
"**/*.jsonc",
|
|
30810
|
+
"**/*.jsx",
|
|
30811
|
+
"**/*.ksh",
|
|
30812
|
+
"**/*.kt",
|
|
30813
|
+
"**/*.kts",
|
|
30814
|
+
"**/*.lua",
|
|
30815
|
+
"**/*.luau",
|
|
30816
|
+
"**/*.mjs",
|
|
30817
|
+
"**/*.opal",
|
|
30818
|
+
"**/*.php",
|
|
30819
|
+
"**/*.podspec",
|
|
30820
|
+
"**/*.pom",
|
|
30821
|
+
"**/*.py",
|
|
30822
|
+
"**/*.pyi",
|
|
30823
|
+
"**/*.rake",
|
|
30824
|
+
"**/*.rb",
|
|
30825
|
+
"**/*.rlib",
|
|
30826
|
+
"**/*.rs",
|
|
30827
|
+
"**/*.scala",
|
|
30828
|
+
"**/*.sh",
|
|
30829
|
+
"**/*.swift",
|
|
30830
|
+
"**/*.tf",
|
|
30831
|
+
"**/*.trigger",
|
|
30832
|
+
"**/*.ts",
|
|
30833
|
+
"**/*.tsx",
|
|
30834
|
+
"**/*.vb",
|
|
30835
|
+
"**/*.vue",
|
|
30836
|
+
"**/*.wsdl",
|
|
30837
|
+
"**/*.xhtml",
|
|
30838
|
+
"**/*.xml",
|
|
30839
|
+
"**/*.xsl",
|
|
30840
|
+
"**/*.yaml",
|
|
30841
|
+
"**/*.yml",
|
|
30842
|
+
// Source files with no extension. `LANGUAGE_CONFIG.files` is a *detection*
|
|
30843
|
+
// list — it is mostly lockfiles (`yarn.lock`, `go.sum`, `poetry.lock`), which
|
|
30844
|
+
// identify a language without being source in it — so only the entries
|
|
30845
|
+
// opengrep can actually parse are routed here: Dockerfiles, and Ruby's
|
|
30846
|
+
// extensionless DSL files.
|
|
30847
|
+
"**/Dockerfile",
|
|
30848
|
+
"**/Dockerfile.*",
|
|
30849
|
+
"**/Berksfile",
|
|
30850
|
+
"**/Capfile",
|
|
30851
|
+
"**/Cheffile",
|
|
30852
|
+
"**/Fastfile",
|
|
30853
|
+
"**/Gemfile",
|
|
30854
|
+
"**/Guardfile",
|
|
30855
|
+
"**/Podfile",
|
|
30856
|
+
"**/Rakefile",
|
|
30857
|
+
"**/Thorfile",
|
|
30858
|
+
"**/Vagrantfile",
|
|
30859
|
+
"**/config.ru"
|
|
30860
|
+
],
|
|
30759
30861
|
supportedOS: ["linux", "darwin"],
|
|
30760
30862
|
supportedArch: ["x64", "arm64"],
|
|
30761
30863
|
supportedRunners: ["local", "container"],
|
|
@@ -30845,9 +30947,11 @@ function stripCheckIdPrefix(checkId, configPrefix) {
|
|
|
30845
30947
|
}
|
|
30846
30948
|
return stripped;
|
|
30847
30949
|
}
|
|
30848
|
-
function
|
|
30849
|
-
|
|
30850
|
-
|
|
30950
|
+
function firstSentence(message) {
|
|
30951
|
+
const oneLine = message.replace(/\n/g, " ");
|
|
30952
|
+
const match = /(^.*?[a-z]{2,}[.!?])\s+\W*[A-Z]/.exec(oneLine);
|
|
30953
|
+
if (match) return match[1];
|
|
30954
|
+
return oneLine.length > 500 ? oneLine.slice(0, 500) : oneLine;
|
|
30851
30955
|
}
|
|
30852
30956
|
var ARGV_BYTE_BUDGET = 200 * 1024;
|
|
30853
30957
|
function chunkFilesByArgvBudget(files) {
|
|
@@ -31220,7 +31324,10 @@ var adapter = {
|
|
|
31220
31324
|
kind: errorType,
|
|
31221
31325
|
message,
|
|
31222
31326
|
level,
|
|
31223
|
-
filePath
|
|
31327
|
+
filePath,
|
|
31328
|
+
// Opengrep only reports a path on errors that stopped it scanning
|
|
31329
|
+
// that file, so a path here means the file was not analysed.
|
|
31330
|
+
...filePath ? { fileNotAnalyzed: true } : {}
|
|
31224
31331
|
});
|
|
31225
31332
|
}
|
|
31226
31333
|
}
|
|
@@ -31257,7 +31364,7 @@ var adapter = {
|
|
|
31257
31364
|
column: finding.start.col,
|
|
31258
31365
|
endLine: finding.end.line,
|
|
31259
31366
|
endColumn: finding.end.col,
|
|
31260
|
-
message:
|
|
31367
|
+
message: firstSentence(finding.extra.message ?? ""),
|
|
31261
31368
|
lineContent: (0, import_tooling.getLineContent)(lines, finding.start.line),
|
|
31262
31369
|
multilineContent: (0, import_tooling.getMultilineContent)(lines, finding.start.line, finding.end.line),
|
|
31263
31370
|
category: meta.category,
|
package/dist/metadata.js
CHANGED
|
@@ -255,14 +255,18 @@ var pattern_mappings_default = {
|
|
|
255
255
|
// src/metadata.ts
|
|
256
256
|
var descriptor = {
|
|
257
257
|
id: "Semgrep",
|
|
258
|
+
shortName: "opengrep",
|
|
258
259
|
displayName: "Opengrep",
|
|
259
260
|
preferredVersion: "1.26.0",
|
|
261
|
+
// Canonical `KNOWN_LANGUAGES` names, which is what `init --auto` matches against
|
|
262
|
+
// (`init.ts:882`). The engine's own names differ and must be translated here:
|
|
263
|
+
// Bash/Shell and Vue/Javascript collapse onto one entry each, since `.sh` and
|
|
264
|
+
// `.vue` are already those languages. Guarded by `descriptor-languages.test.ts`.
|
|
260
265
|
languages: [
|
|
261
266
|
"Apex",
|
|
262
|
-
"Bash",
|
|
263
267
|
"C",
|
|
264
|
-
"
|
|
265
|
-
"
|
|
268
|
+
"CPP",
|
|
269
|
+
"CSharp",
|
|
266
270
|
"Clojure",
|
|
267
271
|
"Dart",
|
|
268
272
|
"Dockerfile",
|
|
@@ -270,7 +274,7 @@ var descriptor = {
|
|
|
270
274
|
"Go",
|
|
271
275
|
"HTML",
|
|
272
276
|
"Java",
|
|
273
|
-
"
|
|
277
|
+
"Javascript",
|
|
274
278
|
"JSON",
|
|
275
279
|
"Kotlin",
|
|
276
280
|
"Lua",
|
|
@@ -283,12 +287,110 @@ var descriptor = {
|
|
|
283
287
|
"Swift",
|
|
284
288
|
"Terraform",
|
|
285
289
|
"TypeScript",
|
|
286
|
-
"
|
|
287
|
-
"Vue",
|
|
290
|
+
"VisualBasic",
|
|
288
291
|
"XML",
|
|
289
292
|
"YAML"
|
|
290
293
|
],
|
|
291
|
-
|
|
294
|
+
// Derived from `languages` above, via `LANGUAGE_CONFIG`, plus the extensions
|
|
295
|
+
// sibling adapters already route for those same languages (`.cjs`, `.hh`,
|
|
296
|
+
// `.jsonc`, `.json5`, `.pyi`, `.dash`, `.ksh`) — `LANGUAGE_CONFIG` is a
|
|
297
|
+
// detection map and does not claim to be exhaustive per tool.
|
|
298
|
+
//
|
|
299
|
+
// This was `["*"]`, which `routeFilesToTool` short-circuits to "every file", so
|
|
300
|
+
// opengrep was handed the whole repository: on one 1774-file repo, 358 of them
|
|
301
|
+
// (20%) were png/jpg/font assets. Opengrep resolves a language by extension and
|
|
302
|
+
// skips what it cannot parse, so findings were never affected — but the paths
|
|
303
|
+
// still cost a realpath+stat each, inflated the reported file count, and ate the
|
|
304
|
+
// 200 KB argv budget, splitting one `opengrep scan` into two.
|
|
305
|
+
//
|
|
306
|
+
// Keep this a superset of `LANGUAGE_CONFIG`'s extensions for every declared
|
|
307
|
+
// language; `opengrep-1/test/file-patterns.test.ts` fails if a language gains one
|
|
308
|
+
// that is not routed here, because a missed extension is a silent coverage loss.
|
|
309
|
+
filePatterns: [
|
|
310
|
+
"**/*.bash",
|
|
311
|
+
"**/*.c",
|
|
312
|
+
"**/*.cc",
|
|
313
|
+
"**/*.cjs",
|
|
314
|
+
"**/*.clj",
|
|
315
|
+
"**/*.cljc",
|
|
316
|
+
"**/*.cljs",
|
|
317
|
+
"**/*.cls",
|
|
318
|
+
"**/*.cpp",
|
|
319
|
+
"**/*.cs",
|
|
320
|
+
"**/*.cxx",
|
|
321
|
+
"**/*.dart",
|
|
322
|
+
"**/*.dash",
|
|
323
|
+
"**/*.dockerfile",
|
|
324
|
+
"**/*.edn",
|
|
325
|
+
"**/*.env",
|
|
326
|
+
"**/*.ex",
|
|
327
|
+
"**/*.exs",
|
|
328
|
+
"**/*.gemspec",
|
|
329
|
+
"**/*.go",
|
|
330
|
+
"**/*.h",
|
|
331
|
+
"**/*.hh",
|
|
332
|
+
"**/*.hpp",
|
|
333
|
+
"**/*.htm",
|
|
334
|
+
"**/*.html",
|
|
335
|
+
"**/*.ino",
|
|
336
|
+
"**/*.java",
|
|
337
|
+
"**/*.jbuilder",
|
|
338
|
+
"**/*.js",
|
|
339
|
+
"**/*.jsm",
|
|
340
|
+
"**/*.json",
|
|
341
|
+
"**/*.json5",
|
|
342
|
+
"**/*.jsonc",
|
|
343
|
+
"**/*.jsx",
|
|
344
|
+
"**/*.ksh",
|
|
345
|
+
"**/*.kt",
|
|
346
|
+
"**/*.kts",
|
|
347
|
+
"**/*.lua",
|
|
348
|
+
"**/*.luau",
|
|
349
|
+
"**/*.mjs",
|
|
350
|
+
"**/*.opal",
|
|
351
|
+
"**/*.php",
|
|
352
|
+
"**/*.podspec",
|
|
353
|
+
"**/*.pom",
|
|
354
|
+
"**/*.py",
|
|
355
|
+
"**/*.pyi",
|
|
356
|
+
"**/*.rake",
|
|
357
|
+
"**/*.rb",
|
|
358
|
+
"**/*.rlib",
|
|
359
|
+
"**/*.rs",
|
|
360
|
+
"**/*.scala",
|
|
361
|
+
"**/*.sh",
|
|
362
|
+
"**/*.swift",
|
|
363
|
+
"**/*.tf",
|
|
364
|
+
"**/*.trigger",
|
|
365
|
+
"**/*.ts",
|
|
366
|
+
"**/*.tsx",
|
|
367
|
+
"**/*.vb",
|
|
368
|
+
"**/*.vue",
|
|
369
|
+
"**/*.wsdl",
|
|
370
|
+
"**/*.xhtml",
|
|
371
|
+
"**/*.xml",
|
|
372
|
+
"**/*.xsl",
|
|
373
|
+
"**/*.yaml",
|
|
374
|
+
"**/*.yml",
|
|
375
|
+
// Source files with no extension. `LANGUAGE_CONFIG.files` is a *detection*
|
|
376
|
+
// list — it is mostly lockfiles (`yarn.lock`, `go.sum`, `poetry.lock`), which
|
|
377
|
+
// identify a language without being source in it — so only the entries
|
|
378
|
+
// opengrep can actually parse are routed here: Dockerfiles, and Ruby's
|
|
379
|
+
// extensionless DSL files.
|
|
380
|
+
"**/Dockerfile",
|
|
381
|
+
"**/Dockerfile.*",
|
|
382
|
+
"**/Berksfile",
|
|
383
|
+
"**/Capfile",
|
|
384
|
+
"**/Cheffile",
|
|
385
|
+
"**/Fastfile",
|
|
386
|
+
"**/Gemfile",
|
|
387
|
+
"**/Guardfile",
|
|
388
|
+
"**/Podfile",
|
|
389
|
+
"**/Rakefile",
|
|
390
|
+
"**/Thorfile",
|
|
391
|
+
"**/Vagrantfile",
|
|
392
|
+
"**/config.ru"
|
|
393
|
+
],
|
|
292
394
|
supportedOS: ["linux", "darwin"],
|
|
293
395
|
supportedArch: ["x64", "arm64"],
|
|
294
396
|
supportedRunners: ["local", "container"],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codacy/tools-opengrep-1",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "Opengrep adapter — CLI-mode multi-language SAST scanner",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
],
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"yaml": "^2.6.0",
|
|
13
|
-
"@codacy/tooling": "0.
|
|
13
|
+
"@codacy/tooling": "0.24.0"
|
|
14
14
|
},
|
|
15
15
|
"license": "MIT",
|
|
16
16
|
"author": "Codacy <support@codacy.com> (https://www.codacy.com)",
|