@ploaness/governance 1.2.0 → 1.3.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/dist/checkov-check.d.ts +9 -0
- package/dist/checkov-check.d.ts.map +1 -0
- package/dist/checkov-check.js +4 -0
- package/dist/checkov-check.js.map +1 -0
- package/dist/checkov-checks-aws.d.ts +4 -0
- package/dist/checkov-checks-aws.d.ts.map +1 -0
- package/dist/checkov-checks-aws.js +93 -0
- package/dist/checkov-checks-aws.js.map +1 -0
- package/dist/checkov-checks-azure.d.ts +4 -0
- package/dist/checkov-checks-azure.d.ts.map +1 -0
- package/dist/checkov-checks-azure.js +32 -0
- package/dist/checkov-checks-azure.js.map +1 -0
- package/dist/checkov-checks-google.d.ts +6 -0
- package/dist/checkov-checks-google.d.ts.map +1 -0
- package/dist/checkov-checks-google.js +53 -0
- package/dist/checkov-checks-google.js.map +1 -0
- package/dist/checkov-policy.d.ts +63 -0
- package/dist/checkov-policy.d.ts.map +1 -0
- package/dist/checkov-policy.js +105 -0
- package/dist/checkov-policy.js.map +1 -0
- package/dist/environment-coherence.d.ts +59 -5
- package/dist/environment-coherence.d.ts.map +1 -1
- package/dist/environment-coherence.js +107 -5
- package/dist/environment-coherence.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/payload-bootstrap.d.ts +52 -0
- package/dist/payload-bootstrap.d.ts.map +1 -0
- package/dist/payload-bootstrap.js +195 -0
- package/dist/payload-bootstrap.js.map +1 -0
- package/dist/payload-database.d.ts +80 -0
- package/dist/payload-database.d.ts.map +1 -0
- package/dist/payload-database.js +164 -0
- package/dist/payload-database.js.map +1 -0
- package/dist/payload-policy.d.ts +8 -0
- package/dist/payload-policy.d.ts.map +1 -1
- package/dist/payload-policy.js +12 -4
- package/dist/payload-policy.js.map +1 -1
- package/dist/shell-files.d.ts +45 -0
- package/dist/shell-files.d.ts.map +1 -0
- package/dist/shell-files.js +105 -0
- package/dist/shell-files.js.map +1 -0
- package/dist/source-security.d.ts +10 -0
- package/dist/source-security.d.ts.map +1 -1
- package/dist/source-security.js +88 -1
- package/dist/source-security.js.map +1 -1
- package/dist/terraform-files.d.ts +29 -0
- package/dist/terraform-files.d.ts.map +1 -0
- package/dist/terraform-files.js +50 -0
- package/dist/terraform-files.js.map +1 -0
- package/dist/terraform-policy.d.ts +13 -0
- package/dist/terraform-policy.d.ts.map +1 -0
- package/dist/terraform-policy.js +261 -0
- package/dist/terraform-policy.js.map +1 -0
- package/dist/terraform-providers.d.ts +28 -0
- package/dist/terraform-providers.d.ts.map +1 -0
- package/dist/terraform-providers.js +68 -0
- package/dist/terraform-providers.js.map +1 -0
- package/dist/toolchain-pins.d.ts +1 -1
- package/dist/toolchain-pins.d.ts.map +1 -1
- package/dist/toolchain-pins.js +9 -2
- package/dist/toolchain-pins.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// Whether a project's schema changes are recorded where a reader can review them.
|
|
2
|
+
//
|
|
3
|
+
// Payload's Postgres adapter can apply a schema by pushing it: at boot, it diffs the configuration
|
|
4
|
+
// against the live database and issues whatever closes the gap. Nothing is written down, so there is no
|
|
5
|
+
// artefact to review before it runs and none to roll back after. The guard Payload applies is
|
|
6
|
+
// `this.push !== false`, which is why an UNDECLARED push is the dangerous spelling rather than a neutral
|
|
7
|
+
// one, and why this rule reports it.
|
|
8
|
+
//
|
|
9
|
+
// Push is also skipped where `NODE_ENV` is production, and a production boot then falls to
|
|
10
|
+
// `prodMigrations`. A project that pushes instead of migrating therefore has no mechanism that creates
|
|
11
|
+
// its schema in production at all, which is the second rule here.
|
|
12
|
+
//
|
|
13
|
+
// The value is read from SOURCE rather than from the built configuration. `postgresAdapter()` returns a
|
|
14
|
+
// factory whose `init` closure carries `push`, and Payload calls that closure at `payload.init()`, not
|
|
15
|
+
// during `buildConfig`. A probe that imports the built configuration reads `undefined` for every project
|
|
16
|
+
// and would pass every defect.
|
|
17
|
+
import { depthOneValue } from './payload-source.js';
|
|
18
|
+
import { balancedArguments, lineOf, occurrences, topLevelSlice } from './source-text.js';
|
|
19
|
+
const BUILD_CONFIG_CALL = 'buildConfig(';
|
|
20
|
+
/**
|
|
21
|
+
* Every root configuration literal the source declares.
|
|
22
|
+
*
|
|
23
|
+
* The collection and global readers key on a type marker, which the root configuration does not carry:
|
|
24
|
+
* it is an argument to a call rather than an annotated declaration. So this reads the call instead.
|
|
25
|
+
* @param code the file's text, with comments already stripped.
|
|
26
|
+
* @returns one entry per `buildConfig` call whose argument is an object literal.
|
|
27
|
+
*/
|
|
28
|
+
export const rootConfigsIn = (code) => occurrences(code, BUILD_CONFIG_CALL).flatMap((found) => {
|
|
29
|
+
const argumentText = balancedArguments(code, found + BUILD_CONFIG_CALL.length - 1);
|
|
30
|
+
return argumentText?.trimStart().startsWith('{') === true
|
|
31
|
+
? [{ body: argumentText, line: lineOf(code, found) }]
|
|
32
|
+
: [];
|
|
33
|
+
});
|
|
34
|
+
/**
|
|
35
|
+
* The database adapters whose schema Payload can apply by pushing it.
|
|
36
|
+
*
|
|
37
|
+
* Only the adapter whose behaviour is established belongs here. Naming one that does not carry the
|
|
38
|
+
* option would report a project for failing to disable something it never had, and an adapter left out
|
|
39
|
+
* is merely unreported - the safe direction of the two.
|
|
40
|
+
*/
|
|
41
|
+
export const PUSHING_ADAPTERS = ['postgresAdapter'];
|
|
42
|
+
const ADAPTER_CALL = /^\s*([a-z_$][\w$]*)\s*\(/i;
|
|
43
|
+
const adapterCallIn = (databaseValue) => {
|
|
44
|
+
const matched = ADAPTER_CALL.exec(databaseValue);
|
|
45
|
+
if (matched === null) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
const options = balancedArguments(databaseValue, matched[0].length - 1);
|
|
49
|
+
return options === undefined ? undefined : { name: matched[1] ?? '', options };
|
|
50
|
+
};
|
|
51
|
+
// `push` is read from the depth-one text of the adapter's own options, so a key nested inside `pool`
|
|
52
|
+
// cannot be mistaken for the adapter's own - the protection `topLevelSlice` exists to give.
|
|
53
|
+
//
|
|
54
|
+
// `migrationDir` cannot be read the same way, and that is a property of the scan rather than an
|
|
55
|
+
// oversight: the walk jumps a string literal whole, so the fold never sees the quoted value and the
|
|
56
|
+
// slice a quoted value would land in comes back empty. It is therefore read from the raw options, where
|
|
57
|
+
// the key boundary alone separates it from a value nested beneath. `push` is unaffected because `false`
|
|
58
|
+
// is not a string literal and survives the slice intact.
|
|
59
|
+
const PUSH_PROPERTY = /(?:^|,)\s*push\s*:\s*([^,]*)/;
|
|
60
|
+
const MIGRATION_DIR_PROPERTY = /(?:^|[{,])\s*migrationDir\s*:\s*['"]([^'"]*)['"]/;
|
|
61
|
+
const declaredPushIn = (options) => PUSH_PROPERTY.exec(topLevelSlice(options))?.[1]?.trim();
|
|
62
|
+
/** The rule name a schema-push finding carries. */
|
|
63
|
+
export const SCHEMA_PUSH_RULE = 'no-unreviewed-schema-push';
|
|
64
|
+
const REPAIR = 'set push: false and record the schema with `payload migrate:create`';
|
|
65
|
+
const pushReason = (adapter, declared) => declared === undefined
|
|
66
|
+
? `${adapter} declares no push; Payload treats an undeclared push as on, so it rewrites the ` +
|
|
67
|
+
'schema at every boot outside production and no committed artefact records what the schema ' +
|
|
68
|
+
`became - ${REPAIR}`
|
|
69
|
+
: `${adapter} sets push: ${declared}; Payload rewrites the schema at every boot outside ` +
|
|
70
|
+
`production and no committed artefact records what the schema became - ${REPAIR}`;
|
|
71
|
+
// The adapter a configuration's `db` names, when it is one that can push. Shared by every rule here, so
|
|
72
|
+
// the question "does this project push?" is answered in one place.
|
|
73
|
+
const pushingAdapterIn = (body) => {
|
|
74
|
+
const databaseValue = depthOneValue(body, 'db');
|
|
75
|
+
if (databaseValue === undefined) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
const adapter = adapterCallIn(databaseValue);
|
|
79
|
+
return adapter !== undefined && PUSHING_ADAPTERS.includes(adapter.name) ? adapter : undefined;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Report a root configuration whose database adapter does not disable schema push.
|
|
83
|
+
* @param code the file's text, with comments already stripped.
|
|
84
|
+
* @returns one violation per configuration that pushes, declared or by omission.
|
|
85
|
+
*/
|
|
86
|
+
export const findUnreviewedSchemaPush = (code) => rootConfigsIn(code).flatMap((config) => {
|
|
87
|
+
const adapter = pushingAdapterIn(config.body);
|
|
88
|
+
if (adapter === undefined) {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
const declared = declaredPushIn(adapter.options);
|
|
92
|
+
return declared === 'false'
|
|
93
|
+
? []
|
|
94
|
+
: [
|
|
95
|
+
{
|
|
96
|
+
line: config.line,
|
|
97
|
+
rule: SCHEMA_PUSH_RULE,
|
|
98
|
+
reason: pushReason(adapter.name, declared),
|
|
99
|
+
},
|
|
100
|
+
];
|
|
101
|
+
});
|
|
102
|
+
/**
|
|
103
|
+
* Whether a source declares a database adapter whose schema is applied by push.
|
|
104
|
+
* @param code the file's text, with comments already stripped.
|
|
105
|
+
* @returns true when at least one root configuration names such an adapter.
|
|
106
|
+
*/
|
|
107
|
+
export const declaresPushingAdapter = (code) => rootConfigsIn(code).some((config) => pushingAdapterIn(config.body) !== undefined);
|
|
108
|
+
/**
|
|
109
|
+
* The migration directory a configuration names, when it names one.
|
|
110
|
+
* @param code the file's text, with comments already stripped.
|
|
111
|
+
* @returns the declared directory, or undefined when the adapter leaves it to Payload's default.
|
|
112
|
+
*/
|
|
113
|
+
export const declaredMigrationDirectoryIn = (code) => rootConfigsIn(code)
|
|
114
|
+
.map((config) => {
|
|
115
|
+
const adapter = pushingAdapterIn(config.body);
|
|
116
|
+
return adapter === undefined ? undefined : MIGRATION_DIR_PROPERTY.exec(adapter.options)?.[1];
|
|
117
|
+
})
|
|
118
|
+
.find((declared) => declared !== undefined);
|
|
119
|
+
/** The directories Payload looks in, in the order its own resolver tries them. */
|
|
120
|
+
export const MIGRATION_DIRECTORY_CANDIDATES = [
|
|
121
|
+
'src/migrations',
|
|
122
|
+
'dist/migrations',
|
|
123
|
+
'migrations',
|
|
124
|
+
];
|
|
125
|
+
const MIGRATION_EXTENSIONS = ['.ts', '.js'];
|
|
126
|
+
const BARRELS = new Set(['index.ts', 'index.js']);
|
|
127
|
+
/**
|
|
128
|
+
* Whether a file name is one Payload reads as a migration.
|
|
129
|
+
*
|
|
130
|
+
* Taken from Payload's own reader rather than invented here: a `.ts` or `.js` file that is not the
|
|
131
|
+
* barrel. An empty directory, or one holding only a barrel, records no schema - and that is exactly the
|
|
132
|
+
* distinction a project would otherwise satisfy the rule with.
|
|
133
|
+
* @param name the file's base name.
|
|
134
|
+
* @returns true when Payload would read it as a migration.
|
|
135
|
+
*/
|
|
136
|
+
export const isMigrationFile = (name) => MIGRATION_EXTENSIONS.some((extension) => name.endsWith(extension)) &&
|
|
137
|
+
!BARRELS.has(name);
|
|
138
|
+
/**
|
|
139
|
+
* The directories to read for a member, the declared one first.
|
|
140
|
+
* @param declared the directory the configuration names, when it names one.
|
|
141
|
+
* @returns the candidate paths, relative to the member root.
|
|
142
|
+
*/
|
|
143
|
+
export const migrationDirectoriesFor = (declared) => declared === undefined
|
|
144
|
+
? MIGRATION_DIRECTORY_CANDIDATES
|
|
145
|
+
: [declared, ...MIGRATION_DIRECTORY_CANDIDATES];
|
|
146
|
+
/** The rule name a missing-migration finding carries. */
|
|
147
|
+
export const RECORDED_MIGRATIONS_RULE = 'require-recorded-migrations';
|
|
148
|
+
const MISSING_MIGRATIONS = `[${RECORDED_MIGRATIONS_RULE}] no migration is recorded; this member declares a database adapter ` +
|
|
149
|
+
'whose schema is applied by push, and push is skipped where NODE_ENV is production - so a ' +
|
|
150
|
+
'production boot creates nothing and no file in the repository states what the schema should be. ' +
|
|
151
|
+
'Run `payload migrate:create` and commit the file it writes';
|
|
152
|
+
/**
|
|
153
|
+
* Report a member that records no migration for the schema it expects.
|
|
154
|
+
* @param evidence the adapter it declares, and the candidate directories as they were read.
|
|
155
|
+
* @returns one finding when the member pushes and records nothing, or none.
|
|
156
|
+
*/
|
|
157
|
+
export const findMissingMigrations = (evidence) => {
|
|
158
|
+
if (!evidence.declaresPushingAdapter) {
|
|
159
|
+
return [];
|
|
160
|
+
}
|
|
161
|
+
const carriesMigration = evidence.directories.some((directory) => directory.names.some((name) => isMigrationFile(name)));
|
|
162
|
+
return carriesMigration ? [] : [MISSING_MIGRATIONS];
|
|
163
|
+
};
|
|
164
|
+
//# sourceMappingURL=payload-database.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload-database.js","sourceRoot":"","sources":["../src/payload-database.ts"],"names":[],"mappings":"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"}
|
package/dist/payload-policy.d.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { PayloadViolation } from './payload-source.js';
|
|
2
|
+
/**
|
|
3
|
+
* Recognized Payload receivers, which exclude unrelated collection methods such as array.find().
|
|
4
|
+
*
|
|
5
|
+
* Exported so a rule about WHERE a Local API call runs derives the receiver from here rather than
|
|
6
|
+
* restating it. Two spellings of "this is Payload" would be two rules disagreeing about what Payload is.
|
|
7
|
+
*/
|
|
8
|
+
export declare const PAYLOAD_RECEIVER: RegExp;
|
|
9
|
+
export declare const LOCAL_API_CALLS: readonly string[];
|
|
2
10
|
/**
|
|
3
11
|
* The rules that are about the language rather than about Payload.
|
|
4
12
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payload-policy.d.ts","sourceRoot":"","sources":["../src/payload-policy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"payload-policy.d.ts","sourceRoot":"","sources":["../src/payload-policy.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAyC3D;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,MACsC,CAAA;AA0DrE,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAgB5C,CAAA;AAiMD;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,KAAG,SAAS,gBAAgB,EAI9E,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,KAAG,SAAS,gBAAgB,EAoB/E,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,GACjC,UAAU,MAAM,EAChB,QAAQ,MAAM,KACb,SAAS,gBAAgB,EAiB3B,CAAA"}
|
package/dist/payload-policy.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// Payload source policy for explicit read bounds, request threading, and access decisions.
|
|
2
2
|
import { findAnonymousDraftReads, findUndecidedSvgHeaders, findUndeclaredAccess, findUndeclaredVersionReads, findUnhardenedAuth, findUnlockableAuth, findUnrestrictedUploads, } from './payload-access.js';
|
|
3
|
+
import { findUnreviewedSchemaPush } from './payload-database.js';
|
|
3
4
|
import { findUnprotectedPrivilegedFields } from './payload-field-access.js';
|
|
4
|
-
import { findFailOpenSecretGuards } from './source-security.js';
|
|
5
|
+
import { findAbsentSecretAcceptances, findFailOpenSecretGuards } from './source-security.js';
|
|
5
6
|
import { balancedArguments, lineOf, occurrences, stripComments, topLevelSlice, } from './source-text.js';
|
|
6
7
|
// The Local API reads that must declare their bound. `find` returns a page, so either `depth` or `limit`
|
|
7
8
|
// bounds it; the single-document and global reads return one document, so only `depth` applies.
|
|
@@ -25,8 +26,13 @@ const BOUNDED_CALLS = [
|
|
|
25
26
|
reason: 'bound payload.findGlobal() with an explicit depth to cap relationship population',
|
|
26
27
|
},
|
|
27
28
|
];
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Recognized Payload receivers, which exclude unrelated collection methods such as array.find().
|
|
31
|
+
*
|
|
32
|
+
* Exported so a rule about WHERE a Local API call runs derives the receiver from here rather than
|
|
33
|
+
* restating it. Two spellings of "this is Payload" would be two rules disagreeing about what Payload is.
|
|
34
|
+
*/
|
|
35
|
+
export const PAYLOAD_RECEIVER = /(?:^|[^\w$.])(?:payload|(?:[\w$]+\.)*req\.payload|this\.payload)$/;
|
|
30
36
|
// A property boundary keeps a value such as request: req from being read as a req property.
|
|
31
37
|
const declaresProperty = (topLevel, key) => new RegExp(String.raw `(?:^|,)\s*${key}\s*(?::|,|$)`).test(topLevel);
|
|
32
38
|
// The depth-one text of a call's options literal, or undefined when the call is not one to judge.
|
|
@@ -60,7 +66,7 @@ const findUnboundedCalls = (source) => BOUNDED_CALLS.flatMap((rule) => occurrenc
|
|
|
60
66
|
// One catalogue feeds both rules below: adding a Payload operation to one contract and not the other
|
|
61
67
|
// would leave a call either outside its transaction or running as an administrator with a decorative
|
|
62
68
|
// user value.
|
|
63
|
-
const LOCAL_API_CALLS = [
|
|
69
|
+
export const LOCAL_API_CALLS = [
|
|
64
70
|
'.count(',
|
|
65
71
|
'.create(',
|
|
66
72
|
'.delete(',
|
|
@@ -211,6 +217,7 @@ const findDeepRelativeImports = (source) => [...source.matchAll(RELATIVE_IMPORT)
|
|
|
211
217
|
export const findSourceViolations = (source) => [
|
|
212
218
|
...findDeepRelativeImports(stripComments(source)),
|
|
213
219
|
...findFailOpenSecretGuards(source),
|
|
220
|
+
...findAbsentSecretAcceptances(source),
|
|
214
221
|
];
|
|
215
222
|
/**
|
|
216
223
|
* The rules that are about Payload itself, which only a Payload package can break.
|
|
@@ -235,6 +242,7 @@ export const findPayloadViolations = (source) => {
|
|
|
235
242
|
...findUnrestrictedUploads(code),
|
|
236
243
|
...findUndecidedSvgHeaders(code),
|
|
237
244
|
...findUnprotectedPrivilegedFields(code),
|
|
245
|
+
...findUnreviewedSchemaPush(code),
|
|
238
246
|
];
|
|
239
247
|
};
|
|
240
248
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payload-policy.js","sourceRoot":"","sources":["../src/payload-policy.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,0BAA0B,EAC1B,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAA;AAE3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"payload-policy.js","sourceRoot":"","sources":["../src/payload-policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** The extensions ShellCheck recognises as naming a dialect it reads. */
|
|
2
|
+
export declare const SHELL_EXTENSIONS: readonly string[];
|
|
3
|
+
/**
|
|
4
|
+
* Whether a first line names an interpreter ShellCheck reads.
|
|
5
|
+
* @param firstLine the file's first line.
|
|
6
|
+
* @returns true for a shell shebang, false for any other interpreter and for no shebang at all.
|
|
7
|
+
*/
|
|
8
|
+
export declare const isShellShebang: (firstLine: string) => boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Whether a path's extension names a shell dialect.
|
|
11
|
+
* @param file the repo-relative path.
|
|
12
|
+
* @returns true when the extension is one ShellCheck reads.
|
|
13
|
+
*/
|
|
14
|
+
export declare const isShellScript: (file: string) => boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Whether a path's first line is worth reading to classify it.
|
|
17
|
+
*
|
|
18
|
+
* Only an extensionless basename: anything carrying a dot has already been answered by its extension,
|
|
19
|
+
* and reading it would be an I/O cost with no question behind it.
|
|
20
|
+
* @param file the repo-relative path.
|
|
21
|
+
* @returns true when only the shebang can decide.
|
|
22
|
+
*/
|
|
23
|
+
export declare const requiresShebangRead: (file: string) => boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Every shell script the repository tracks.
|
|
26
|
+
*
|
|
27
|
+
* A shebang DECIDES where one is present, so a `.sh` file written for zsh leaves scope rather than
|
|
28
|
+
* being sent to an analyzer that refuses it. Where none is present the extension stands.
|
|
29
|
+
* @param tracked the repo-relative paths of the tracked files.
|
|
30
|
+
* @param firstLineOf reads one file's first line; called only for paths that could be shell.
|
|
31
|
+
* @returns the scripts, ordered so a report reads the same on every machine.
|
|
32
|
+
*/
|
|
33
|
+
export declare const shellScriptsIn: (tracked: readonly string[], firstLineOf: (file: string) => string) => readonly string[];
|
|
34
|
+
/** One blanket suppression: the line it sits on, and what it disables. */
|
|
35
|
+
export interface ShellDirective {
|
|
36
|
+
readonly line: number;
|
|
37
|
+
readonly directive: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Report every blanket ShellCheck suppression a script applies to itself.
|
|
41
|
+
* @param text the script's contents.
|
|
42
|
+
* @returns one entry per blanket directive, in the order they appear.
|
|
43
|
+
*/
|
|
44
|
+
export declare const findBlanketShellDirectives: (text: string) => readonly ShellDirective[];
|
|
45
|
+
//# sourceMappingURL=shell-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-files.d.ts","sourceRoot":"","sources":["../src/shell-files.ts"],"names":[],"mappings":"AAQA,yEAAyE;AACzE,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAA+C,CAAA;AAY7F;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,WAAW,MAAM,KAAG,OAWlD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,OACoC,CAAA;AAEjF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,KAAG,OAA0C,CAAA;AAE7F;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GACzB,SAAS,SAAS,MAAM,EAAE,EAC1B,aAAa,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,KACpC,SAAS,MAAM,EAO+D,CAAA;AAEjF,0EAA0E;AAC1E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AA8CD;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,GAAI,MAAM,MAAM,KAAG,SAAS,cAAc,EAOtE,CAAA"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// Which tracked files are shell scripts, and which suppressions inside them are blanket ones.
|
|
2
|
+
//
|
|
3
|
+
// Extension AND shebang. `scripts/deploy.sh` announces itself, but `hooks/pre-commit` and `bin/release`
|
|
4
|
+
// are shell too and carry no extension, so an extension-only rule would leave exactly the operational
|
|
5
|
+
// scripts unread. Reading the first line of every tracked file would be a sweep of the whole tree, so
|
|
6
|
+
// the read is bounded to the paths whose extension could not already have answered. The reader is
|
|
7
|
+
// injected rather than imported, which is what keeps this layer free of the filesystem.
|
|
8
|
+
/** The extensions ShellCheck recognises as naming a dialect it reads. */
|
|
9
|
+
export const SHELL_EXTENSIONS = ['.sh', '.bash', '.ksh', '.dash', '.bats'];
|
|
10
|
+
// The interpreters ShellCheck can analyse. zsh and fish are deliberately absent: ShellCheck refuses a
|
|
11
|
+
// zsh script with SC1071 and exits non-zero, so treating one as in scope would manufacture a finding
|
|
12
|
+
// about a file written in a dialect it never claimed to read.
|
|
13
|
+
const SHELL_INTERPRETERS = new Set(['sh', 'bash', 'ksh', 'dash', 'bats']);
|
|
14
|
+
const SHEBANG = /^#!\s*(?<command>\S+)(?:[ \t]+(?<argument>\S+))?/;
|
|
15
|
+
const ENV_COMMAND = '/env';
|
|
16
|
+
const basenameOf = (file) => file.slice(file.lastIndexOf('/') + 1);
|
|
17
|
+
/**
|
|
18
|
+
* Whether a first line names an interpreter ShellCheck reads.
|
|
19
|
+
* @param firstLine the file's first line.
|
|
20
|
+
* @returns true for a shell shebang, false for any other interpreter and for no shebang at all.
|
|
21
|
+
*/
|
|
22
|
+
export const isShellShebang = (firstLine) => {
|
|
23
|
+
const found = SHEBANG.exec(firstLine);
|
|
24
|
+
if (found === null) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const command = found.groups?.['command'] ?? '';
|
|
28
|
+
// `#!/usr/bin/env bash` names the interpreter in the argument; everything else names it in the path.
|
|
29
|
+
const interpreter = command.endsWith(ENV_COMMAND)
|
|
30
|
+
? (found.groups?.['argument'] ?? '')
|
|
31
|
+
: basenameOf(command);
|
|
32
|
+
return SHELL_INTERPRETERS.has(interpreter);
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Whether a path's extension names a shell dialect.
|
|
36
|
+
* @param file the repo-relative path.
|
|
37
|
+
* @returns true when the extension is one ShellCheck reads.
|
|
38
|
+
*/
|
|
39
|
+
export const isShellScript = (file) => SHELL_EXTENSIONS.some((extension) => file.endsWith(extension));
|
|
40
|
+
/**
|
|
41
|
+
* Whether a path's first line is worth reading to classify it.
|
|
42
|
+
*
|
|
43
|
+
* Only an extensionless basename: anything carrying a dot has already been answered by its extension,
|
|
44
|
+
* and reading it would be an I/O cost with no question behind it.
|
|
45
|
+
* @param file the repo-relative path.
|
|
46
|
+
* @returns true when only the shebang can decide.
|
|
47
|
+
*/
|
|
48
|
+
export const requiresShebangRead = (file) => !basenameOf(file).includes('.');
|
|
49
|
+
/**
|
|
50
|
+
* Every shell script the repository tracks.
|
|
51
|
+
*
|
|
52
|
+
* A shebang DECIDES where one is present, so a `.sh` file written for zsh leaves scope rather than
|
|
53
|
+
* being sent to an analyzer that refuses it. Where none is present the extension stands.
|
|
54
|
+
* @param tracked the repo-relative paths of the tracked files.
|
|
55
|
+
* @param firstLineOf reads one file's first line; called only for paths that could be shell.
|
|
56
|
+
* @returns the scripts, ordered so a report reads the same on every machine.
|
|
57
|
+
*/
|
|
58
|
+
export const shellScriptsIn = (tracked, firstLineOf) => tracked
|
|
59
|
+
.filter((file) => isShellScript(file) || requiresShebangRead(file))
|
|
60
|
+
.filter((file) => {
|
|
61
|
+
const first = firstLineOf(file);
|
|
62
|
+
return first.startsWith('#!') ? isShellShebang(first) : isShellScript(file);
|
|
63
|
+
})
|
|
64
|
+
.toSorted((left, right) => left.localeCompare(right));
|
|
65
|
+
// A directive that names its codes is the legitimate form, and ShellCheck offers no flag to refuse one.
|
|
66
|
+
// What is refused here is the in-file equivalent of an rc file: `disable=all`, and a range wide enough
|
|
67
|
+
// to mean the same thing. `--norc` removes the project-wide spelling; this removes the per-file one.
|
|
68
|
+
const DISABLE_DIRECTIVE = /#[ \t]*shellcheck[ \t]+disable=(?<codes>\S+)/;
|
|
69
|
+
const BLANKET_CODES = /^(?:all|SC\d+-SC\d+)$/;
|
|
70
|
+
const FIRST_LINE = 1;
|
|
71
|
+
// A heredoc body is data rather than script. A script that WRITES another script carries that script's
|
|
72
|
+
// directives inside it, and reading them as its own reports a repository for the contents of a file it
|
|
73
|
+
// generates. ShellCheck itself draws this line, so a rule that supplements it must draw it too - the
|
|
74
|
+
// same reason `stripComments` exists for source: prose naming a construct is not that construct.
|
|
75
|
+
const HEREDOC_OPEN = /<<-?[ \t]*(?<quote>['"]?)(?<delimiter>[a-z_]\w*)\k<quote>/i;
|
|
76
|
+
// `<<-` strips leading tabs from the terminator, which trimming covers without the scan needing to know
|
|
77
|
+
// which of the two forms opened the body.
|
|
78
|
+
const endsHeredoc = (line, delimiter) => line.trim() === delimiter;
|
|
79
|
+
const blanketDirectiveAt = (line, index) => {
|
|
80
|
+
const codes = DISABLE_DIRECTIVE.exec(line)?.groups?.['codes'];
|
|
81
|
+
return codes !== undefined && BLANKET_CODES.test(codes)
|
|
82
|
+
? { line: index + FIRST_LINE, directive: codes }
|
|
83
|
+
: undefined;
|
|
84
|
+
};
|
|
85
|
+
const afterLine = (state, line, index) => {
|
|
86
|
+
// Inside a heredoc nothing is read but its terminator.
|
|
87
|
+
if (state.delimiter !== undefined) {
|
|
88
|
+
return endsHeredoc(line, state.delimiter) ? { ...state, delimiter: undefined } : state;
|
|
89
|
+
}
|
|
90
|
+
const opened = HEREDOC_OPEN.exec(line)?.groups?.['delimiter'];
|
|
91
|
+
if (opened !== undefined) {
|
|
92
|
+
return { ...state, delimiter: opened };
|
|
93
|
+
}
|
|
94
|
+
const directive = blanketDirectiveAt(line, index);
|
|
95
|
+
return directive === undefined ? state : { ...state, found: [...state.found, directive] };
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Report every blanket ShellCheck suppression a script applies to itself.
|
|
99
|
+
* @param text the script's contents.
|
|
100
|
+
* @returns one entry per blanket directive, in the order they appear.
|
|
101
|
+
*/
|
|
102
|
+
export const findBlanketShellDirectives = (text) => text
|
|
103
|
+
.split('\n')
|
|
104
|
+
.reduce((state, line, index) => afterLine(state, line, index), { delimiter: undefined, found: [] }).found;
|
|
105
|
+
//# sourceMappingURL=shell-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-files.js","sourceRoot":"","sources":["../src/shell-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
import type { PayloadViolation } from './payload-source.js';
|
|
2
2
|
/** Report credential guards whose rejection disappears when the credential is absent. */
|
|
3
3
|
export declare const findFailOpenSecretGuards: (source: string) => readonly PayloadViolation[];
|
|
4
|
+
/**
|
|
5
|
+
* Report guards that admit the caller when the credential is absent.
|
|
6
|
+
*
|
|
7
|
+
* The mirror of {@link findFailOpenSecretGuards}: that rule reads a rejection guarded by the
|
|
8
|
+
* credential's own truthiness, this one an acceptance guarded by its absence. The two never report the
|
|
9
|
+
* same line, because one requires a top-level `&&` in the condition and the other refuses it.
|
|
10
|
+
* @param source the file's text.
|
|
11
|
+
* @returns one violation per guard that opens on a missing credential.
|
|
12
|
+
*/
|
|
13
|
+
export declare const findAbsentSecretAcceptances: (source: string) => readonly PayloadViolation[];
|
|
4
14
|
//# sourceMappingURL=source-security.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-security.d.ts","sourceRoot":"","sources":["../src/source-security.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"source-security.d.ts","sourceRoot":"","sources":["../src/source-security.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAqD3D,yFAAyF;AACzF,eAAO,MAAM,wBAAwB,GAAI,QAAQ,MAAM,KAAG,SAAS,gBAAgB,EAoBlF,CAAA;AAmFD;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,GAAI,QAAQ,MAAM,KAAG,SAAS,gBAAgB,EAwBrF,CAAA"}
|
package/dist/source-security.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { balancedArguments, lineOf, maskLiterals } from './source-text.js';
|
|
1
|
+
import { balancedArguments, lineOf, maskLiterals, scanDelimited, } from './source-text.js';
|
|
2
2
|
const GUARDED_IF = /\bif\s*\(\s*([a-z_$][\w$]*(?:\s*\.\s*[a-z_$][\w$]*)*)\s*&&/gi;
|
|
3
3
|
const PENULTIMATE = -2;
|
|
4
4
|
const credentialSegments = (name) => name
|
|
@@ -53,4 +53,91 @@ export const findFailOpenSecretGuards = (source) => {
|
|
|
53
53
|
: [];
|
|
54
54
|
});
|
|
55
55
|
};
|
|
56
|
+
const IF_STATEMENT = /\bif\s*\(/g;
|
|
57
|
+
// An operator is top level when no bracket is open at it, which is what separates `a || (b && c)` -
|
|
58
|
+
// two disjuncts - from `(a || b) && c`, a conjunction. Both characters of the operator are found at
|
|
59
|
+
// the first, because the scan asks whether the operator STARTS here.
|
|
60
|
+
const OPERATOR_WIDTH = 2;
|
|
61
|
+
const topLevelOperators = (condition, operator) => scanDelimited(condition, 0, (found, step) => ({
|
|
62
|
+
state: step.depth === 0 && condition.startsWith(operator, step.index)
|
|
63
|
+
? [...found, step.index]
|
|
64
|
+
: found,
|
|
65
|
+
stop: false,
|
|
66
|
+
}), []);
|
|
67
|
+
const splitTopLevel = (condition, operator) => {
|
|
68
|
+
const cuts = topLevelOperators(condition, operator);
|
|
69
|
+
const ends = [...cuts, condition.length];
|
|
70
|
+
return [0, ...cuts.map((cut) => cut + OPERATOR_WIDTH)].map((start, position) => condition.slice(start, ends[position] ?? condition.length).trim());
|
|
71
|
+
};
|
|
72
|
+
// The ways a value is tested for absence. `=== ''` is deliberately absent: `maskLiterals` fills a
|
|
73
|
+
// string literal INCLUDING its quotes, so an empty string is indistinguishable from an identifier by
|
|
74
|
+
// the time this reads the text. `.length === 0` expresses the same test and survives masking.
|
|
75
|
+
const ABSENCE_SHAPES = [
|
|
76
|
+
/^!\s*([\w$]+(?:\s*\??\.\s*[\w$]+)*)$/,
|
|
77
|
+
/^([\w$]+(?:\s*\??\.\s*[\w$]+)*)\s*===?\s*(?:undefined|null)$/,
|
|
78
|
+
/^([\w$]+(?:\s*\??\.\s*[\w$]+)*)\s*\.\s*length\s*===?\s*0$/,
|
|
79
|
+
];
|
|
80
|
+
const absentNameIn = (disjunct) => {
|
|
81
|
+
const matched = ABSENCE_SHAPES.map((shape) => shape.exec(disjunct)).find((found) => found !== null);
|
|
82
|
+
return matched?.[1]?.replaceAll(/\s/g, '').replaceAll('?.', '.');
|
|
83
|
+
};
|
|
84
|
+
// The credential a condition admits on absence, or nothing when the condition is not that shape.
|
|
85
|
+
//
|
|
86
|
+
// A conjunction is refused outright: `if (secret === undefined && enabled)` narrows the branch to a
|
|
87
|
+
// case the project chose, and it is the fail-closed shape the sibling rule's tests already pin. Every
|
|
88
|
+
// disjunct must be an absence test, which is the conservative reading - `if (!secret || isDevelopment)`
|
|
89
|
+
// is fail-open too, but it is not PROVABLY this defect from text, and a false positive here costs more
|
|
90
|
+
// than the finding is worth.
|
|
91
|
+
const acceptedAbsence = (condition) => {
|
|
92
|
+
if (topLevelOperators(condition, '&&').length > 0) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
const names = splitTopLevel(condition, '||').map((disjunct) => absentNameIn(disjunct));
|
|
96
|
+
if (names.includes(undefined)) {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
return names.find((name) => name !== undefined && isCredential(name));
|
|
100
|
+
};
|
|
101
|
+
// The returned VALUE decides, not the presence of a return: `if (!secret) { return unauthorized() }`
|
|
102
|
+
// refuses the caller and is correct, while `return true` admits them. `true` is not a string literal,
|
|
103
|
+
// so it survives masking intact and can be recognised here.
|
|
104
|
+
const ACCEPTANCE = /\breturn\s+true\b/;
|
|
105
|
+
const hasAcceptanceAfter = (masked, close) => {
|
|
106
|
+
const statementStart = masked.slice(close + 1).search(/\S/);
|
|
107
|
+
if (statementStart < 0) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
return ACCEPTANCE.test(statementAt(masked, close + 1 + statementStart));
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Report guards that admit the caller when the credential is absent.
|
|
114
|
+
*
|
|
115
|
+
* The mirror of {@link findFailOpenSecretGuards}: that rule reads a rejection guarded by the
|
|
116
|
+
* credential's own truthiness, this one an acceptance guarded by its absence. The two never report the
|
|
117
|
+
* same line, because one requires a top-level `&&` in the condition and the other refuses it.
|
|
118
|
+
* @param source the file's text.
|
|
119
|
+
* @returns one violation per guard that opens on a missing credential.
|
|
120
|
+
*/
|
|
121
|
+
export const findAbsentSecretAcceptances = (source) => {
|
|
122
|
+
const masked = maskLiterals(source);
|
|
123
|
+
return [...masked.matchAll(IF_STATEMENT)].flatMap((match) => {
|
|
124
|
+
const open = masked.indexOf('(', match.index);
|
|
125
|
+
const condition = balancedArguments(masked, open);
|
|
126
|
+
if (condition === undefined) {
|
|
127
|
+
return [];
|
|
128
|
+
}
|
|
129
|
+
const credential = acceptedAbsence(condition);
|
|
130
|
+
return credential !== undefined && hasAcceptanceAfter(masked, open + condition.length + 1)
|
|
131
|
+
? [
|
|
132
|
+
{
|
|
133
|
+
line: lineOf(source, match.index),
|
|
134
|
+
rule: 'no-absent-secret-acceptance',
|
|
135
|
+
reason: `refuse the caller when ${credential} is absent; this admits them instead, so the ` +
|
|
136
|
+
'endpoint is open exactly when the credential is unset and no request is ever ' +
|
|
137
|
+
'refused - reject the absence and report the misconfiguration',
|
|
138
|
+
},
|
|
139
|
+
]
|
|
140
|
+
: [];
|
|
141
|
+
});
|
|
142
|
+
};
|
|
56
143
|
//# sourceMappingURL=source-security.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-security.js","sourceRoot":"","sources":["../src/source-security.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"source-security.js","sourceRoot":"","sources":["../src/source-security.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decide whether a path names an OpenTofu or Terraform source.
|
|
3
|
+
*
|
|
4
|
+
* An example file is not one. `terraform.tfvars.example` documents the variables an environment needs
|
|
5
|
+
* and is meant to carry placeholders, so reading it as configuration would report a project for the
|
|
6
|
+
* one file whose job is to hold the values it tells a reader to replace.
|
|
7
|
+
* @param file a repo-relative path.
|
|
8
|
+
* @returns true when the file is configuration the gate judges.
|
|
9
|
+
*/
|
|
10
|
+
export declare const isTerraformFile: (file: string) => boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Every OpenTofu or Terraform source the repository tracks.
|
|
13
|
+
* @param tracked the repo-relative paths of the tracked files.
|
|
14
|
+
* @returns the sources, ordered so a report reads the same on every machine.
|
|
15
|
+
*/
|
|
16
|
+
export declare const terraformFilesIn: (tracked: readonly string[]) => readonly string[];
|
|
17
|
+
/**
|
|
18
|
+
* Decide whether a path names a checkov configuration.
|
|
19
|
+
* @param file a repo-relative path.
|
|
20
|
+
* @returns true for a configuration checkov would read on its own, at any depth.
|
|
21
|
+
*/
|
|
22
|
+
export declare const isCheckovConfigFile: (file: string) => boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Every checkov configuration the repository tracks.
|
|
25
|
+
* @param tracked the repo-relative paths of the tracked files.
|
|
26
|
+
* @returns the configurations, ordered so a report reads the same on every machine.
|
|
27
|
+
*/
|
|
28
|
+
export declare const checkovConfigsIn: (tracked: readonly string[]) => readonly string[];
|
|
29
|
+
//# sourceMappingURL=terraform-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terraform-files.d.ts","sourceRoot":"","sources":["../src/terraform-files.ts"],"names":[],"mappings":"AAaA;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,KAAG,OACsC,CAAA;AAErF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,SAAS,SAAS,MAAM,EAAE,KAAG,SAAS,MAAM,EAGI,CAAA;AAUjF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,KAAG,OACH,CAAA;AAEhD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,SAAS,SAAS,MAAM,EAAE,KAAG,SAAS,MAAM,EAGI,CAAA"}
|