@saltcorn/cli
Command-line interface for Saltcorn, open-source no-code platform
Supply chain provenance
Status for the latest visible version.
Without SLSA provenance there is no cryptographic link between this tarball and the public source — the axios compromise (March 2026) relied on exactly this gap.
Maintainers
Keywords
Accepted risks
Findings the reviewer chose to accept rather than block on.
| Source | Rule | Reason | Accepted by | When |
|---|---|---|---|---|
| semgrep | semgrep:env-spread | AI (semgrep): Intentional pattern: spreads process.env to inject PGPASSWORD for pg backup utilities — expected CLI behavior. | ai | |
| semgrep | semgrep:child-process-import | AI (semgrep): CLI tool legitimately uses child_process for backup/restore commands; stable pattern across all versions. | ai | |
| semgrep | semgrep:dynamic-require | AI (semgrep): Dynamic require resolves a package.json path for plugin localization — not arbitrary user input. | ai | |
| typosquat | typosquat.levenshtein:joi | AI (typosquat): @saltcorn/cli is a scoped package in the saltcorn org; not a typosquat of joi. | ai | |
| phantom-deps | phantom-dep:node-watch | AI (phantom-deps): Referenced in oclif config/runtime; false positive for this CLI package. | ai | |
| phantom-deps | phantom-dep:source-map-support | AI (phantom-deps): Loaded via oclif bootstrap, not direct import; stable false positive. | ai | |
| phantom-deps | phantom-dep:@oclif/plugin-plugins | AI (phantom-deps): Declared as oclif plugin in config; not directly imported by design. | ai | |
| phantom-deps | phantom-dep:@saltcorn/common-code | AI (phantom-deps): Same-org dependency; may be transitively loaded; stable false positive. | ai |
Versions (showing 4 of 4)
| Version | Deps | Published |
|---|---|---|
| 1.5.6 | 20 / 3 | |
| 1.5.3 | 20 / 3 | |
| 1.5.0 | 20 / 3 | |
| 1.4.3 | 20 / 3 |
v1.5.6
9 findingsSpreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/f9d5efcf835f47d4cc29943a374e05b2350b0a10/src/commands/backup.js#L100 98 | const pgport = connobj.port || 5432; 99 | const outfnm = flags.output || default_filenm; > 100 | const env = { ...process.env, PGPASSWORD: connobj.password }; 101 | 102 | if (flags.verbose) {
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/f9d5efcf835f47d4cc29943a374e05b2350b0a10/src/commands/dev/plugin-test.js#L70 68 | stdio: "inherit", 69 | env: !env > 70 | ? { 71 | ...process.env, 72 | ...scEnvVars,
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/f9d5efcf835f47d4cc29943a374e05b2350b0a10/src/commands/dev/plugin-test.js#L165 163 | const testdbpath = "/tmp/sctestdb"; 164 | await db.changeConnection({ sqlite_path: testdbpath }); > 165 | env = { ...process.env, SQLITE_FILEPATH: testdbpath }; 166 | } else if (db.connectObj.database !== dbname) { 167 | await db.changeConnection({ database: dbname });
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/f9d5efcf835f47d4cc29943a374e05b2350b0a10/src/commands/dev/plugin-test.js#L168 166 | } else if (db.connectObj.database !== dbname) { 167 | await db.changeConnection({ database: dbname }); > 168 | env = { ...process.env, PGDATABASE: dbname }; 169 | } 170 | let jestStatus = null;
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/f9d5efcf835f47d4cc29943a374e05b2350b0a10/src/commands/dev/post-release.js#L50 48 | this.exit(1); 49 | } > 50 | const env = { ...process.env, TAG: tag }; 51 | 52 | spawnSync("bash", ["deploy/docker_build_push.sh"], {
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/f9d5efcf835f47d4cc29943a374e05b2350b0a10/src/commands/restore.js#L29 27 | const pguser = connobj.user; 28 | const pghost = connobj.host || "localhost"; > 29 | const env = { ...process.env, PGPASSWORD: connobj.password }; 30 | const res = spawnSync( 31 | "pg_restore",
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/f9d5efcf835f47d4cc29943a374e05b2350b0a10/src/commands/run-tests.js#L135 133 | const testdbpath = "/tmp/sctestdb"; 134 | await db.changeConnection({ sqlite_path: testdbpath }); > 135 | env = { ...process.env, SQLITE_FILEPATH: testdbpath }; 136 | } else if (db.connectObj.database !== dbname) { 137 | await db.changeConnection({ database: dbname });
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/f9d5efcf835f47d4cc29943a374e05b2350b0a10/src/commands/run-tests.js#L138 136 | } else if (db.connectObj.database !== dbname) { 137 | await db.changeConnection({ database: dbname }); > 138 | env = { ...process.env, PGDATABASE: dbname }; 139 | } 140 | spawnSync("npm", ["run", "tsc"], {
Package was published without Sigstore provenance. Only ~12% of npm packages have provenance, so this is common but not ideal.
v1.5.3
9 findingsSpreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/6ad7246ffc90f6043f7d53c7a83e8d301dae71bb/src/commands/backup.js#L100 98 | const pgport = connobj.port || 5432; 99 | const outfnm = flags.output || default_filenm; > 100 | const env = { ...process.env, PGPASSWORD: connobj.password }; 101 | 102 | if (flags.verbose) {
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/6ad7246ffc90f6043f7d53c7a83e8d301dae71bb/src/commands/dev/plugin-test.js#L70 68 | stdio: "inherit", 69 | env: !env > 70 | ? { 71 | ...process.env, 72 | ...scEnvVars,
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/6ad7246ffc90f6043f7d53c7a83e8d301dae71bb/src/commands/dev/plugin-test.js#L165 163 | const testdbpath = "/tmp/sctestdb"; 164 | await db.changeConnection({ sqlite_path: testdbpath }); > 165 | env = { ...process.env, SQLITE_FILEPATH: testdbpath }; 166 | } else if (db.connectObj.database !== dbname) { 167 | await db.changeConnection({ database: dbname });
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/6ad7246ffc90f6043f7d53c7a83e8d301dae71bb/src/commands/dev/plugin-test.js#L168 166 | } else if (db.connectObj.database !== dbname) { 167 | await db.changeConnection({ database: dbname }); > 168 | env = { ...process.env, PGDATABASE: dbname }; 169 | } 170 | let jestStatus = null;
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/6ad7246ffc90f6043f7d53c7a83e8d301dae71bb/src/commands/dev/post-release.js#L50 48 | this.exit(1); 49 | } > 50 | const env = { ...process.env, TAG: tag }; 51 | 52 | spawnSync("bash", ["deploy/docker_build_push.sh"], {
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/6ad7246ffc90f6043f7d53c7a83e8d301dae71bb/src/commands/restore.js#L29 27 | const pguser = connobj.user; 28 | const pghost = connobj.host || "localhost"; > 29 | const env = { ...process.env, PGPASSWORD: connobj.password }; 30 | const res = spawnSync( 31 | "pg_restore",
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/6ad7246ffc90f6043f7d53c7a83e8d301dae71bb/src/commands/run-tests.js#L135 133 | const testdbpath = "/tmp/sctestdb"; 134 | await db.changeConnection({ sqlite_path: testdbpath }); > 135 | env = { ...process.env, SQLITE_FILEPATH: testdbpath }; 136 | } else if (db.connectObj.database !== dbname) { 137 | await db.changeConnection({ database: dbname });
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/6ad7246ffc90f6043f7d53c7a83e8d301dae71bb/src/commands/run-tests.js#L138 136 | } else if (db.connectObj.database !== dbname) { 137 | await db.changeConnection({ database: dbname }); > 138 | env = { ...process.env, PGDATABASE: dbname }; 139 | } 140 | spawnSync("npm", ["run", "tsc"], {
Package was published without Sigstore provenance. Only ~12% of npm packages have provenance, so this is common but not ideal.
v1.5.0
9 findingsSpreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/785b3bf06227a077b9d0880744e5da5bea4cd5c1/src/commands/backup.js#L100 98 | const pgport = connobj.port || 5432; 99 | const outfnm = flags.output || default_filenm; > 100 | const env = { ...process.env, PGPASSWORD: connobj.password }; 101 | 102 | if (flags.verbose) {
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/785b3bf06227a077b9d0880744e5da5bea4cd5c1/src/commands/dev/plugin-test.js#L70 68 | stdio: "inherit", 69 | env: !env > 70 | ? { 71 | ...process.env, 72 | ...scEnvVars,
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/785b3bf06227a077b9d0880744e5da5bea4cd5c1/src/commands/dev/plugin-test.js#L165 163 | const testdbpath = "/tmp/sctestdb"; 164 | await db.changeConnection({ sqlite_path: testdbpath }); > 165 | env = { ...process.env, SQLITE_FILEPATH: testdbpath }; 166 | } else if (db.connectObj.database !== dbname) { 167 | await db.changeConnection({ database: dbname });
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/785b3bf06227a077b9d0880744e5da5bea4cd5c1/src/commands/dev/plugin-test.js#L168 166 | } else if (db.connectObj.database !== dbname) { 167 | await db.changeConnection({ database: dbname }); > 168 | env = { ...process.env, PGDATABASE: dbname }; 169 | } 170 | let jestStatus = null;
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/785b3bf06227a077b9d0880744e5da5bea4cd5c1/src/commands/dev/post-release.js#L50 48 | this.exit(1); 49 | } > 50 | const env = { ...process.env, TAG: tag }; 51 | 52 | spawnSync("bash", ["deploy/docker_build_push.sh"], {
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/785b3bf06227a077b9d0880744e5da5bea4cd5c1/src/commands/restore.js#L29 27 | const pguser = connobj.user; 28 | const pghost = connobj.host || "localhost"; > 29 | const env = { ...process.env, PGPASSWORD: connobj.password }; 30 | const res = spawnSync( 31 | "pg_restore",
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/785b3bf06227a077b9d0880744e5da5bea4cd5c1/src/commands/run-tests.js#L135 133 | const testdbpath = "/tmp/sctestdb"; 134 | await db.changeConnection({ sqlite_path: testdbpath }); > 135 | env = { ...process.env, SQLITE_FILEPATH: testdbpath }; 136 | } else if (db.connectObj.database !== dbname) { 137 | await db.changeConnection({ database: dbname });
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/785b3bf06227a077b9d0880744e5da5bea4cd5c1/src/commands/run-tests.js#L138 136 | } else if (db.connectObj.database !== dbname) { 137 | await db.changeConnection({ database: dbname }); > 138 | env = { ...process.env, PGDATABASE: dbname }; 139 | } 140 | spawnSync("npm", ["run", "tsc"], {
Package was published without Sigstore provenance. Only ~12% of npm packages have provenance, so this is common but not ideal.
v1.4.3
9 findingsSpreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/2852a9f2e1b9d3d12cbe98ed2e1c4aec055bc918/src/commands/backup.js#L100 98 | const pgport = connobj.port || 5432; 99 | const outfnm = flags.output || default_filenm; > 100 | const env = { ...process.env, PGPASSWORD: connobj.password }; 101 | 102 | if (flags.verbose) {
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/2852a9f2e1b9d3d12cbe98ed2e1c4aec055bc918/src/commands/dev/plugin-test.js#L70 68 | stdio: "inherit", 69 | env: !env > 70 | ? { 71 | ...process.env, 72 | ...scEnvVars,
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/2852a9f2e1b9d3d12cbe98ed2e1c4aec055bc918/src/commands/dev/plugin-test.js#L165 163 | const testdbpath = "/tmp/sctestdb"; 164 | await db.changeConnection({ sqlite_path: testdbpath }); > 165 | env = { ...process.env, SQLITE_FILEPATH: testdbpath }; 166 | } else if (db.connectObj.database !== dbname) { 167 | await db.changeConnection({ database: dbname });
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/2852a9f2e1b9d3d12cbe98ed2e1c4aec055bc918/src/commands/dev/plugin-test.js#L168 166 | } else if (db.connectObj.database !== dbname) { 167 | await db.changeConnection({ database: dbname }); > 168 | env = { ...process.env, PGDATABASE: dbname }; 169 | } 170 | let jestStatus = null;
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/2852a9f2e1b9d3d12cbe98ed2e1c4aec055bc918/src/commands/dev/post-release.js#L50 48 | this.exit(1); 49 | } > 50 | const env = { ...process.env, TAG: tag }; 51 | 52 | spawnSync("bash", ["deploy/docker_build_push.sh"], {
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/2852a9f2e1b9d3d12cbe98ed2e1c4aec055bc918/src/commands/restore.js#L29 27 | const pguser = connobj.user; 28 | const pghost = connobj.host || "localhost"; > 29 | const env = { ...process.env, PGPASSWORD: connobj.password }; 30 | const res = spawnSync( 31 | "pg_restore",
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/2852a9f2e1b9d3d12cbe98ed2e1c4aec055bc918/src/commands/run-tests.js#L135 133 | const testdbpath = "/tmp/sctestdb"; 134 | await db.changeConnection({ sqlite_path: testdbpath }); > 135 | env = { ...process.env, SQLITE_FILEPATH: testdbpath }; 136 | } else if (db.connectObj.database !== dbname) { 137 | await db.changeConnection({ database: dbname });
Spreading entire process.env into an object — may capture all secrets Source: https://github.com/saltcorn/saltcorn/blob/2852a9f2e1b9d3d12cbe98ed2e1c4aec055bc918/src/commands/run-tests.js#L138 136 | } else if (db.connectObj.database !== dbname) { 137 | await db.changeConnection({ database: dbname }); > 138 | env = { ...process.env, PGDATABASE: dbname }; 139 | } 140 | spawnSync("npm", ["run", "tsc"], {
Package was published without Sigstore provenance. Only ~12% of npm packages have provenance, so this is common but not ideal.