@runa-ai/runa-cli 0.5.31 → 0.5.33
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/commands/db/commands/db-rollback.d.ts.map +1 -1
- package/dist/commands/db/commands/db-seed-verify.d.ts.map +1 -1
- package/dist/commands/db/utils/db-target.d.ts.map +1 -1
- package/dist/commands/db/utils/schema-detector.d.ts +5 -1
- package/dist/commands/db/utils/schema-detector.d.ts.map +1 -1
- package/dist/commands/db/utils/schema-sync.d.ts.map +1 -1
- package/dist/commands/db/utils/table-registry.d.ts.map +1 -1
- package/dist/commands/env/commands/env-encrypt.d.ts.map +1 -1
- package/dist/commands/env/commands/env-pull.d.ts.map +1 -1
- package/dist/index.js +214 -42
- package/dist/internal/vuln-checker/config/loader.d.ts +10 -0
- package/dist/internal/vuln-checker/config/loader.d.ts.map +1 -1
- package/dist/internal/vuln-checker/index.d.ts +4 -0
- package/dist/internal/vuln-checker/index.d.ts.map +1 -1
- package/dist/internal/vuln-checker/security/path-validation.d.ts +66 -0
- package/dist/internal/vuln-checker/security/path-validation.d.ts.map +1 -0
- package/dist/utils/license/index.d.ts +6 -4
- package/dist/utils/license/index.d.ts.map +1 -1
- package/dist/utils/license/types.d.ts +3 -1
- package/dist/utils/license/types.d.ts.map +1 -1
- package/dist/utils/secure-exec.d.ts +13 -0
- package/dist/utils/secure-exec.d.ts.map +1 -1
- package/dist/utils/template-fetcher.d.ts.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-rollback.d.ts","sourceRoot":"","sources":["../../../../src/commands/db/commands/db-rollback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"db-rollback.d.ts","sourceRoot":"","sources":["../../../../src/commands/db/commands/db-rollback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsNpC;;GAEG;AACH,eAAO,MAAM,eAAe,SAoBxB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-seed-verify.d.ts","sourceRoot":"","sources":["../../../../src/commands/db/commands/db-seed-verify.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"db-seed-verify.d.ts","sourceRoot":"","sources":["../../../../src/commands/db/commands/db-seed-verify.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgFpC;;;GAGG;AACH,eAAO,MAAM,iBAAiB,SA6C3B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-target.d.ts","sourceRoot":"","sources":["../../../../src/commands/db/utils/db-target.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"db-target.d.ts","sourceRoot":"","sources":["../../../../src/commands/db/utils/db-target.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,YAAY,CAAC;AAyBpE;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,SAAS,GAAG,MAAM,CAqDjE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAUhF"}
|
|
@@ -23,8 +23,12 @@ export declare function detectAppSchemas(schemasDir: string, verbose: boolean):
|
|
|
23
23
|
*
|
|
24
24
|
* @param schemas Array of schema names
|
|
25
25
|
* @returns Formatted string for SQL: "'public', 'accounts', 'repos'"
|
|
26
|
+
* @throws Error if any schema name fails validation
|
|
27
|
+
*
|
|
28
|
+
* SECURITY (Issue #535): Defense-in-depth for SQL injection prevention:
|
|
29
|
+
* 1. Validates each schema is a safe PostgreSQL identifier
|
|
30
|
+
* 2. Escapes single quotes (even though valid identifiers won't have them)
|
|
26
31
|
*
|
|
27
|
-
* Note: Escapes single quotes for SQL injection defense.
|
|
28
32
|
* While schema names from detectAppSchemas() are already safe (regex \w+),
|
|
29
33
|
* this provides defense-in-depth for future code paths.
|
|
30
34
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-detector.d.ts","sourceRoot":"","sources":["../../../../src/commands/db/utils/schema-detector.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH;;GAEG;AACH,eAAO,MAAM,gBAAgB,aAsB3B,CAAC;AAEH;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,CAoC/E;
|
|
1
|
+
{"version":3,"file":"schema-detector.d.ts","sourceRoot":"","sources":["../../../../src/commands/db/utils/schema-detector.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH;;GAEG;AACH,eAAO,MAAM,gBAAgB,aAsB3B,CAAC;AAEH;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,CAoC/E;AAQD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAW7D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-sync.d.ts","sourceRoot":"","sources":["../../../../src/commands/db/utils/schema-sync.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema-sync.d.ts","sourceRoot":"","sources":["../../../../src/commands/db/utils/schema-sync.ts"],"names":[],"mappings":"AA0KA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC3C,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAErC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,mBAAmB,EAAE,KAAK,CAAC;QACzB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC,CAAC;CACJ;AAMD;;;;;;;;;;;GAWG;AACH,wBAAsB,2BAA2B,CAC/C,aAAa,EAAE,MAAM,EACrB,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC;IACT,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC5C,CAAC,CAoCD;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;IACR,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;CACpC,GACA,OAAO,CAAC;IACT,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACtC,CAAC,CAoDD;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE;IACjC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC3C,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACtC,GAAG,QAAQ,CAuCX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-registry.d.ts","sourceRoot":"","sources":["../../../../src/commands/db/utils/table-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EAMV,UAAU,EACV,cAAc,EAEf,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EAAyC,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"table-registry.d.ts","sourceRoot":"","sources":["../../../../src/commands/db/utils/table-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EAMV,UAAU,EACV,cAAc,EAEf,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EAAyC,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AA4ElG;;;;;;;;;;;GAWG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,UAAU,EAAE,CAAC,CAmDvB;AA4PD;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,UAAU,EAAE,EACvB,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC;IACT,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC,CAYD;AAMD;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,UAAU,EAAE,GACnB,OAAO,CAAC,UAAU,EAAE,CAAC,CA2HvB;AAMD,MAAM,WAAW,uBAAuB;IACtC,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,6DAA6D;IAC7D,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAuCD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,cAAc,CAAC,CA6GzB;AA+FD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAa7E;AAMD,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,oBAAoB,EACpB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,YAAY,EACZ,aAAa,EACb,oBAAoB,EACpB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env-encrypt.d.ts","sourceRoot":"","sources":["../../../../src/commands/env/commands/env-encrypt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"env-encrypt.d.ts","sourceRoot":"","sources":["../../../../src/commands/env/commands/env-encrypt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiOpC,eAAO,MAAM,cAAc,SAqBvB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env-pull.d.ts","sourceRoot":"","sources":["../../../../src/commands/env/commands/env-pull.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;
|
|
1
|
+
{"version":3,"file":"env-pull.d.ts","sourceRoot":"","sources":["../../../../src/commands/env/commands/env-pull.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAaH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA88BpC,eAAO,MAAM,WAAW,SA+BpB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,10 +5,10 @@ import path10__default, { join, dirname, resolve, relative, basename, sep, isAbs
|
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import { execSync, spawnSync, execFileSync, exec, spawn } from 'child_process';
|
|
7
7
|
import * as fs6 from 'fs';
|
|
8
|
-
import fs6__default, { existsSync, readFileSync, readdirSync, mkdtempSync, writeFileSync, mkdirSync, copyFileSync, createWriteStream, statSync, rmSync, realpathSync, promises, lstatSync,
|
|
8
|
+
import fs6__default, { existsSync, readFileSync, readdirSync, mkdtempSync, writeFileSync, mkdirSync, copyFileSync, createWriteStream, statSync, rmSync, realpathSync, promises, lstatSync, accessSync, constants, chmodSync, unlinkSync } from 'fs';
|
|
9
9
|
import { createCLILogger, cacheClear, CacheClearOutputSchema, CLIError, cachePrune, CachePruneOutputSchema, cacheStats, CacheStatsOutputSchema, cacheList, CacheListOutputSchema, cacheInvalidate, CacheInvalidateOutputSchema, syncFromProduction, dbGenerateDiagram, DbDiagramGenerateOutputSchema, createDbSnapshot, syncDatabase, emitDbPushFailureCapsule, emitDbAnnotations, writeDbPushStepSummary, exportDbReportJson, DbSyncOutputSchema, databasePaths, detectRequiredServices, formatDetectionResults, dbStart, DbLifecycleStartOutputSchema, dbStop, DbLifecycleStopOutputSchema, dbReset, DbLifecycleResetOutputSchema, dbValidateSchemas, DbSchemaValidateOutputSchema, DbSchemaRisksOutputSchema, dbDetectSchemaRisks, dbApplySchemas, DbSchemaApplyOutputSchema, dbGenerateTypes, DbSchemaGenerateOutputSchema, extractSchemaFilter, dbSeedInit, DbSeedInitOutputSchema, dbSeedValidate, DbSeedValidateOutputSchema, dbSeedGenerate, DbSeedGenerateOutputSchema, dbVerifySeeds, DbSeedVerifyOutputSchema, DbSnapshotCreateOutputSchema, restoreDbSnapshot, DbSnapshotRestoreOutputSchema, listDbSnapshots, DbSnapshotListOutputSchema, dbGeneratePgTapTests, DbTestGenOutputSchema, dbUpdateGoldenRecord, DbTestUpdateGoldenOutputSchema, repairRunaConfig, detectExistingInitConfig, initProject, validateInitResult, linkCliGlobally, LinkCliOutputSchema, unlinkCliGlobally, UnlinkCliOutputSchema, checkRepoStatus, CheckRepoStatusOutputSchema, enableTelemetry, disableTelemetry, getTelemetryStatus, uploadTelemetry, TelemetryUploadOutputSchema, runTest, TestRunOutputSchema, runTestService, TestServiceOutputSchema, runTestIntegration, TestIntegrationOutputSchema, runTestStatic, TestStaticOutputSchema, generateOwaspTop10Tests, TestOwaspGenerateOutputSchema, updateGoldenRecord, generateE2ETests, generateSecurityTests, generateUnitTests, generateApiTests, generateComponentTests, generateE2EScaffold, validateConfig, ValidateConfigOutputSchema, deploySchemaToProduction, WorkflowNotifyOutputSchema, devopsSync, workflowSync, validateInfrastructure, emitWorkflowValidateFailureCapsule, emitWorkflowAnnotations, writeWorkflowValidateStepSummary, exportWorkflowReportJson, WorkflowValidateInfrastructureOutputSchema, createSuccessEnvelopeSchema, CLI_CONTRACT_VERSION, runChecks, RunCheckOutputSchema, formatDuration as formatDuration$1, GITHUB_API, loadRunaConfig, getClassificationForProfile, recordSchemaAudit, RecordSchemaAuditOutputSchema, createBackup, CreateBackupOutputSchema, listBackups, ListBackupsOutputSchema, getBackupMetadata, restoreBackup, RestoreBackupOutputSchema, deleteBackup, DeleteBackupOutputSchema, detectSchemaNames, SUPABASE_SYSTEM_SCHEMAS, loadRunaConfigOrThrow, dbSeedApply, writeDbSeedStepSummary, DbSeedApplyOutputSchema, emitDbSeedFailureCapsule, syncEnvironment, EnvSyncOutputSchema, detectDatabasePackage, findProjectRoot as findProjectRoot$1, TelemetryEnableOutputSchema, TelemetryDisableOutputSchema, TelemetryStatusOutputSchema, workflowNotify, DevOpsSyncOutputSchema, WorkflowSyncOutputSchema, formatCLIError, DATABASE_PACKAGE_CANDIDATES, getStatusIcon as getStatusIcon$1, findWorkspaceRoot as findWorkspaceRoot$1, checkExtensionConfig, UpgradeTransaction, readRunaVersion, syncTemplates, SyncOutputSchema, ErrorEnvelopeSchema, preCheckSync, findConflictFiles, TestUnitGenOutputSchema, TestE2EGenerateOutputSchema, TestSecurityGenOutputSchema, TestApiGenOutputSchema, TestComponentGenOutputSchema } from '@runa-ai/runa';
|
|
10
10
|
import { z } from 'zod';
|
|
11
|
-
import fs10, { mkdir, writeFile, appendFile, readFile, rm, stat, realpath, cp, readdir } from 'fs/promises';
|
|
11
|
+
import fs10, { mkdir, writeFile, appendFile, readFile, rm, stat, realpath, cp, readdir, lstat } from 'fs/promises';
|
|
12
12
|
import { promisify } from 'util';
|
|
13
13
|
import { glob } from 'glob';
|
|
14
14
|
import { Project, Node, SyntaxKind } from 'ts-morph';
|
|
@@ -925,7 +925,7 @@ var CLI_VERSION, HAS_ADMIN_COMMAND;
|
|
|
925
925
|
var init_version = __esm({
|
|
926
926
|
"src/version.ts"() {
|
|
927
927
|
init_esm_shims();
|
|
928
|
-
CLI_VERSION = "0.5.
|
|
928
|
+
CLI_VERSION = "0.5.33";
|
|
929
929
|
HAS_ADMIN_COMMAND = false;
|
|
930
930
|
}
|
|
931
931
|
});
|
|
@@ -3030,8 +3030,50 @@ var init_typescript_analyzer = __esm({
|
|
|
3030
3030
|
};
|
|
3031
3031
|
}
|
|
3032
3032
|
});
|
|
3033
|
+
function containsPathTraversal4(inputPath) {
|
|
3034
|
+
const normalized = path10__default.normalize(inputPath);
|
|
3035
|
+
if (normalized.includes("..")) return true;
|
|
3036
|
+
if (inputPath.includes("\0")) return true;
|
|
3037
|
+
return false;
|
|
3038
|
+
}
|
|
3039
|
+
function isPathWithinBoundary(filePath, boundaryDir) {
|
|
3040
|
+
try {
|
|
3041
|
+
const resolvedFile = path10__default.resolve(filePath);
|
|
3042
|
+
const resolvedBoundary = path10__default.resolve(boundaryDir);
|
|
3043
|
+
const relative8 = path10__default.relative(resolvedBoundary, resolvedFile);
|
|
3044
|
+
return !relative8.startsWith("..") && !path10__default.isAbsolute(relative8);
|
|
3045
|
+
} catch {
|
|
3046
|
+
return false;
|
|
3047
|
+
}
|
|
3048
|
+
}
|
|
3049
|
+
function resolvePathWithinBoundary(inputPath, boundaryDir) {
|
|
3050
|
+
if (containsPathTraversal4(inputPath)) {
|
|
3051
|
+
throw new Error(`Path contains traversal patterns: ${inputPath}`);
|
|
3052
|
+
}
|
|
3053
|
+
const resolvedPath = path10__default.isAbsolute(inputPath) ? inputPath : path10__default.resolve(boundaryDir, inputPath);
|
|
3054
|
+
if (!isPathWithinBoundary(resolvedPath, boundaryDir)) {
|
|
3055
|
+
throw new Error(`Path is outside allowed boundary: ${inputPath}`);
|
|
3056
|
+
}
|
|
3057
|
+
return resolvedPath;
|
|
3058
|
+
}
|
|
3059
|
+
function filterPathsWithinBoundary(files, boundaryDir) {
|
|
3060
|
+
const resolvedBoundary = path10__default.resolve(boundaryDir);
|
|
3061
|
+
return files.filter((file) => isPathWithinBoundary(file, resolvedBoundary));
|
|
3062
|
+
}
|
|
3063
|
+
function validateGlobPatterns(patterns) {
|
|
3064
|
+
for (const pattern of patterns) {
|
|
3065
|
+
if (containsPathTraversal4(pattern)) {
|
|
3066
|
+
throw new Error(`Glob pattern contains path traversal: ${pattern}`);
|
|
3067
|
+
}
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
var init_path_validation = __esm({
|
|
3071
|
+
"src/internal/vuln-checker/security/path-validation.ts"() {
|
|
3072
|
+
init_esm_shims();
|
|
3073
|
+
}
|
|
3074
|
+
});
|
|
3033
3075
|
async function loadConfig(configPath, rootDir) {
|
|
3034
|
-
const fullPath =
|
|
3076
|
+
const fullPath = resolvePathWithinBoundary(configPath, rootDir);
|
|
3035
3077
|
try {
|
|
3036
3078
|
const content = await fs10.readFile(fullPath, "utf-8");
|
|
3037
3079
|
if (fullPath.endsWith(".yml") || fullPath.endsWith(".yaml")) {
|
|
@@ -3046,7 +3088,7 @@ async function loadConfig(configPath, rootDir) {
|
|
|
3046
3088
|
}
|
|
3047
3089
|
}
|
|
3048
3090
|
async function loadIgnores(ignorePath, rootDir) {
|
|
3049
|
-
const fullPath =
|
|
3091
|
+
const fullPath = resolvePathWithinBoundary(ignorePath, rootDir);
|
|
3050
3092
|
try {
|
|
3051
3093
|
const content = await fs10.readFile(fullPath, "utf-8");
|
|
3052
3094
|
let parsed;
|
|
@@ -3072,6 +3114,7 @@ async function loadIgnores(ignorePath, rootDir) {
|
|
|
3072
3114
|
var init_loader = __esm({
|
|
3073
3115
|
"src/internal/vuln-checker/config/loader.ts"() {
|
|
3074
3116
|
init_esm_shims();
|
|
3117
|
+
init_path_validation();
|
|
3075
3118
|
}
|
|
3076
3119
|
});
|
|
3077
3120
|
function normalizePath(filePath) {
|
|
@@ -3661,6 +3704,7 @@ var init_vuln_checker = __esm({
|
|
|
3661
3704
|
init_json_reporter();
|
|
3662
3705
|
init_markdown_reporter();
|
|
3663
3706
|
init_sarif_reporter();
|
|
3707
|
+
init_path_validation();
|
|
3664
3708
|
init_types2();
|
|
3665
3709
|
SEVERITY_ORDER2 = {
|
|
3666
3710
|
critical: 5,
|
|
@@ -3748,11 +3792,16 @@ var init_vuln_checker = __esm({
|
|
|
3748
3792
|
return result;
|
|
3749
3793
|
}
|
|
3750
3794
|
async getFiles() {
|
|
3751
|
-
|
|
3795
|
+
validateGlobPatterns(this.options.include);
|
|
3796
|
+
if (this.options.exclude) {
|
|
3797
|
+
validateGlobPatterns(this.options.exclude);
|
|
3798
|
+
}
|
|
3799
|
+
const files = await glob(this.options.include, {
|
|
3752
3800
|
cwd: this.options.rootDir,
|
|
3753
3801
|
ignore: this.options.exclude,
|
|
3754
3802
|
absolute: true
|
|
3755
3803
|
});
|
|
3804
|
+
return filterPathsWithinBoundary(files, this.options.rootDir);
|
|
3756
3805
|
}
|
|
3757
3806
|
async runAnalyzers(inlineAnnotations) {
|
|
3758
3807
|
const findings = [];
|
|
@@ -5343,6 +5392,26 @@ function isExecutable(filePath) {
|
|
|
5343
5392
|
return false;
|
|
5344
5393
|
}
|
|
5345
5394
|
}
|
|
5395
|
+
function resolveAndValidateSymlink(filePath) {
|
|
5396
|
+
try {
|
|
5397
|
+
const lstats = lstatSync(filePath);
|
|
5398
|
+
if (lstats.isSymbolicLink()) {
|
|
5399
|
+
const realPath = realpathSync(filePath);
|
|
5400
|
+
const realDir = dirname(realPath);
|
|
5401
|
+
if (!isTrustedDirectory(realDir)) {
|
|
5402
|
+
return null;
|
|
5403
|
+
}
|
|
5404
|
+
const realStats = statSync(realPath);
|
|
5405
|
+
if (!realStats.isFile()) {
|
|
5406
|
+
return null;
|
|
5407
|
+
}
|
|
5408
|
+
return realPath;
|
|
5409
|
+
}
|
|
5410
|
+
return filePath;
|
|
5411
|
+
} catch {
|
|
5412
|
+
return null;
|
|
5413
|
+
}
|
|
5414
|
+
}
|
|
5346
5415
|
function isTrustedDirectory(dir) {
|
|
5347
5416
|
const normalizedDir = normalize(dir).replace(/[/\\]$/, "");
|
|
5348
5417
|
if (process.platform === "win32") {
|
|
@@ -5350,7 +5419,7 @@ function isTrustedDirectory(dir) {
|
|
|
5350
5419
|
}
|
|
5351
5420
|
for (const trusted of TRUSTED_DIRECTORIES_UNIX) {
|
|
5352
5421
|
const normalizedTrusted = normalize(trusted).replace(/[/\\]$/, "");
|
|
5353
|
-
if (normalizedDir === normalizedTrusted || normalizedDir.startsWith(normalizedTrusted
|
|
5422
|
+
if (normalizedDir === normalizedTrusted || normalizedDir.startsWith(`${normalizedTrusted}/`)) {
|
|
5354
5423
|
return true;
|
|
5355
5424
|
}
|
|
5356
5425
|
}
|
|
@@ -5396,8 +5465,9 @@ function resolveBinaryPath(binaryName) {
|
|
|
5396
5465
|
const isExpired = now - cached.resolvedAt >= CACHE_TTL_MS;
|
|
5397
5466
|
const pathChanged = cached.pathFingerprint !== currentPathFingerprint;
|
|
5398
5467
|
if (!isExpired && !pathChanged) {
|
|
5399
|
-
|
|
5400
|
-
|
|
5468
|
+
const validatedPath = resolveAndValidateSymlink(cached.path);
|
|
5469
|
+
if (validatedPath && isExecutable(validatedPath)) {
|
|
5470
|
+
return validatedPath;
|
|
5401
5471
|
}
|
|
5402
5472
|
binaryPathCache.delete(binaryName);
|
|
5403
5473
|
} else {
|
|
@@ -5410,19 +5480,31 @@ function resolveBinaryPath(binaryName) {
|
|
|
5410
5480
|
`Binary '${binaryName}' not found in trusted PATH directories. Ensure ${binaryName} is installed in a system directory.`
|
|
5411
5481
|
);
|
|
5412
5482
|
}
|
|
5413
|
-
|
|
5414
|
-
|
|
5483
|
+
const realPath = resolveAndValidateSymlink(resolvedPath);
|
|
5484
|
+
if (!realPath) {
|
|
5485
|
+
throw new Error(
|
|
5486
|
+
`Security: Binary '${binaryName}' at '${resolvedPath}' is a symlink pointing outside trusted directories. This is not allowed for security reasons.`
|
|
5487
|
+
);
|
|
5488
|
+
}
|
|
5489
|
+
if (!isExecutable(realPath)) {
|
|
5490
|
+
throw new Error(`Binary '${binaryName}' at '${realPath}' is not executable.`);
|
|
5415
5491
|
}
|
|
5416
5492
|
binaryPathCache.set(binaryName, {
|
|
5417
|
-
path:
|
|
5493
|
+
path: realPath,
|
|
5418
5494
|
resolvedAt: now,
|
|
5419
5495
|
pathFingerprint: currentPathFingerprint
|
|
5420
5496
|
});
|
|
5421
|
-
return
|
|
5497
|
+
return realPath;
|
|
5422
5498
|
}
|
|
5423
5499
|
function secureExeca(binaryName, args = [], options) {
|
|
5424
5500
|
const resolvedPath = resolveBinaryPath(binaryName);
|
|
5425
|
-
|
|
5501
|
+
const finalPath = resolveAndValidateSymlink(resolvedPath);
|
|
5502
|
+
if (!finalPath || !isExecutable(finalPath)) {
|
|
5503
|
+
throw new Error(
|
|
5504
|
+
`Security: Binary '${binaryName}' validation failed just before execution. The file may have been modified.`
|
|
5505
|
+
);
|
|
5506
|
+
}
|
|
5507
|
+
return execa(finalPath, args, { ...options, shell: false });
|
|
5426
5508
|
}
|
|
5427
5509
|
function securePnpm(args = [], options) {
|
|
5428
5510
|
return secureExeca("pnpm", args, options);
|
|
@@ -7115,9 +7197,9 @@ function printSummary(logger15, output3) {
|
|
|
7115
7197
|
}
|
|
7116
7198
|
function findRepoRoot(startDir) {
|
|
7117
7199
|
const { existsSync: existsSync49, readFileSync: readFileSync27 } = __require("fs");
|
|
7118
|
-
const { join: join22, dirname:
|
|
7200
|
+
const { join: join22, dirname: dirname5 } = __require("path");
|
|
7119
7201
|
let current = startDir;
|
|
7120
|
-
while (current !==
|
|
7202
|
+
while (current !== dirname5(current)) {
|
|
7121
7203
|
if (existsSync49(join22(current, "turbo.json"))) {
|
|
7122
7204
|
return current;
|
|
7123
7205
|
}
|
|
@@ -7131,7 +7213,7 @@ function findRepoRoot(startDir) {
|
|
|
7131
7213
|
} catch {
|
|
7132
7214
|
}
|
|
7133
7215
|
}
|
|
7134
|
-
current =
|
|
7216
|
+
current = dirname5(current);
|
|
7135
7217
|
}
|
|
7136
7218
|
return startDir;
|
|
7137
7219
|
}
|
|
@@ -9279,8 +9361,14 @@ function detectAppSchemas(schemasDir, verbose) {
|
|
|
9279
9361
|
}
|
|
9280
9362
|
return result;
|
|
9281
9363
|
}
|
|
9364
|
+
var VALID_PG_IDENTIFIER = /^[a-zA-Z_][a-zA-Z0-9_]{0,62}$/;
|
|
9282
9365
|
function formatSchemasForSql(schemas) {
|
|
9283
|
-
return schemas.map((s) =>
|
|
9366
|
+
return schemas.map((s) => {
|
|
9367
|
+
if (!VALID_PG_IDENTIFIER.test(s)) {
|
|
9368
|
+
throw new Error(`Invalid schema name "${s}": must be a valid PostgreSQL identifier`);
|
|
9369
|
+
}
|
|
9370
|
+
return `'${s.replace(/'/g, "''")}'`;
|
|
9371
|
+
}).join(", ");
|
|
9284
9372
|
}
|
|
9285
9373
|
async function detectStack(repoRoot, tmpDir, productionDbUrlAdmin) {
|
|
9286
9374
|
const res = await runLogged({
|
|
@@ -16722,7 +16810,8 @@ function resolveDatabaseUrl(environment) {
|
|
|
16722
16810
|
if (!isLocalDatabaseUrl(url)) {
|
|
16723
16811
|
throw new CLIError("Local database URL appears to be a remote URL", "LOCAL_DB_URL_REMOTE", [
|
|
16724
16812
|
"Local operations should use the local Supabase instance",
|
|
16725
|
-
|
|
16813
|
+
// SECURITY (Issue #513): Redact credentials from database URL in error message
|
|
16814
|
+
`Current URL: ${redactSecrets(url)}`,
|
|
16726
16815
|
"If you need to connect to a remote DB, use --env preview or --env production"
|
|
16727
16816
|
]);
|
|
16728
16817
|
}
|
|
@@ -19344,6 +19433,34 @@ init_config_loader();
|
|
|
19344
19433
|
|
|
19345
19434
|
// src/commands/db/utils/schema-sync.ts
|
|
19346
19435
|
init_esm_shims();
|
|
19436
|
+
var VALID_PG_IDENTIFIER_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]{0,62}$/;
|
|
19437
|
+
function validatePgIdentifier(name, context) {
|
|
19438
|
+
if (!name || typeof name !== "string") {
|
|
19439
|
+
throw new Error(`Invalid ${context}: empty or not a string`);
|
|
19440
|
+
}
|
|
19441
|
+
if (!VALID_PG_IDENTIFIER_PATTERN.test(name)) {
|
|
19442
|
+
throw new Error(
|
|
19443
|
+
`Invalid ${context} "${name}": must start with letter/underscore and contain only alphanumeric/underscore characters`
|
|
19444
|
+
);
|
|
19445
|
+
}
|
|
19446
|
+
}
|
|
19447
|
+
function escapePgStringLiteral(value) {
|
|
19448
|
+
if (typeof value !== "string") {
|
|
19449
|
+
throw new Error("Value must be a string");
|
|
19450
|
+
}
|
|
19451
|
+
return value.replace(/\\/g, "\\\\").replace(/'/g, "''");
|
|
19452
|
+
}
|
|
19453
|
+
function buildSafeSchemaInClause(schemas) {
|
|
19454
|
+
if (schemas.length === 0) {
|
|
19455
|
+
throw new Error("No schemas provided for IN clause");
|
|
19456
|
+
}
|
|
19457
|
+
const safeSchemas = [];
|
|
19458
|
+
for (const schema of schemas) {
|
|
19459
|
+
validatePgIdentifier(schema, "schema name");
|
|
19460
|
+
safeSchemas.push(`'${escapePgStringLiteral(schema)}'`);
|
|
19461
|
+
}
|
|
19462
|
+
return safeSchemas.join(",");
|
|
19463
|
+
}
|
|
19347
19464
|
var ERROR_MESSAGES2 = {
|
|
19348
19465
|
PATH_TRAVERSAL: "Schema path validation failed",
|
|
19349
19466
|
SCHEMA_NOT_FOUND: "Schema file not found"
|
|
@@ -19419,7 +19536,7 @@ async function fetchDbTablesAndEnums(databaseUrl, options) {
|
|
|
19419
19536
|
...options?.additionalSystemSchemas ?? []
|
|
19420
19537
|
]);
|
|
19421
19538
|
const filteredManagedSchemas = managedSchemas.filter((s) => !systemSchemas.has(s));
|
|
19422
|
-
const schemaList = filteredManagedSchemas
|
|
19539
|
+
const schemaList = buildSafeSchemaInClause(filteredManagedSchemas);
|
|
19423
19540
|
const tablesSql = `
|
|
19424
19541
|
SELECT schemaname || '.' || tablename
|
|
19425
19542
|
FROM pg_tables
|
|
@@ -23091,7 +23208,7 @@ async function runRollbackAction(environment, options) {
|
|
|
23091
23208
|
logger15.section("Schema Rollback");
|
|
23092
23209
|
logger15.info(`Environment: ${environment}`);
|
|
23093
23210
|
logger15.info(`Snapshot: ${snapshotFile}`);
|
|
23094
|
-
logger15.info(`Database: ${databaseUrl
|
|
23211
|
+
logger15.info(`Database: ${redactSecrets(databaseUrl)}`);
|
|
23095
23212
|
if (options.dryRun) {
|
|
23096
23213
|
logger15.info("\n[DRY RUN] Would restore from snapshot");
|
|
23097
23214
|
logger15.info("Re-run without --dry-run to apply");
|
|
@@ -23825,7 +23942,7 @@ function renderSeedVerifyText(params) {
|
|
|
23825
23942
|
const { logger: logger15, env: env2, dbUrl, result } = params;
|
|
23826
23943
|
logger15.section("Seed Data Verification");
|
|
23827
23944
|
logger15.info(`Environment: ${env2}`);
|
|
23828
|
-
logger15.info(`Database: ${dbUrl
|
|
23945
|
+
logger15.info(`Database: ${redactSecrets(dbUrl)}`);
|
|
23829
23946
|
logger15.info("");
|
|
23830
23947
|
logger15.step("Checking data counts", 1);
|
|
23831
23948
|
for (const r of result.results) {
|
|
@@ -25069,7 +25186,12 @@ var VERCEL_ENVIRONMENTS = ["development", "preview", "production"];
|
|
|
25069
25186
|
function isAlreadyEncrypted(filePath) {
|
|
25070
25187
|
if (!existsSync(filePath)) return false;
|
|
25071
25188
|
const content = readFileSync(filePath, "utf-8");
|
|
25072
|
-
|
|
25189
|
+
const hasPublicKeyDeclaration = /^DOTENV_PUBLIC_KEY_\w+\s*=\s*["']?[A-Za-z0-9+/=]+/m.test(
|
|
25190
|
+
content
|
|
25191
|
+
);
|
|
25192
|
+
if (!hasPublicKeyDeclaration) return false;
|
|
25193
|
+
const hasEncryptedValue = /^[A-Z_][A-Z0-9_]*\s*=\s*["']?encrypted:/m.test(content);
|
|
25194
|
+
return hasEncryptedValue;
|
|
25073
25195
|
}
|
|
25074
25196
|
async function encryptFile(workDir, environment, logger15, options) {
|
|
25075
25197
|
const fileName = `.env.${environment}`;
|
|
@@ -25423,6 +25545,31 @@ var ERROR_MESSAGES3 = {
|
|
|
25423
25545
|
PATH_TRAVERSAL: "Working directory path validation failed",
|
|
25424
25546
|
APP_NOT_FOUND: "App directory not found"
|
|
25425
25547
|
};
|
|
25548
|
+
function sanitizeErrorMessage(message) {
|
|
25549
|
+
if (!message || typeof message !== "string") {
|
|
25550
|
+
return "Unknown error";
|
|
25551
|
+
}
|
|
25552
|
+
let sanitized = message;
|
|
25553
|
+
sanitized = sanitized.replace(
|
|
25554
|
+
/\b(vercel_|vc_|VERCEL_TOKEN[=:]\s*)[a-zA-Z0-9_-]{20,}/gi,
|
|
25555
|
+
"$1[REDACTED]"
|
|
25556
|
+
);
|
|
25557
|
+
sanitized = sanitized.replace(/\b(Bearer\s+)[a-zA-Z0-9._-]{20,}/gi, "$1[REDACTED]");
|
|
25558
|
+
sanitized = sanitized.replace(
|
|
25559
|
+
/\b(token[=:]\s*["']?)[a-zA-Z0-9._-]{20,}(["']?)/gi,
|
|
25560
|
+
"$1[REDACTED]$2"
|
|
25561
|
+
);
|
|
25562
|
+
sanitized = sanitized.replace(
|
|
25563
|
+
/\b(api[_-]?key[=:]\s*["']?)[a-zA-Z0-9._-]{20,}(["']?)/gi,
|
|
25564
|
+
"$1[REDACTED]$2"
|
|
25565
|
+
);
|
|
25566
|
+
sanitized = sanitized.replace(
|
|
25567
|
+
/\b(Authorization[=:]\s*["']?)[a-zA-Z0-9\s._-]{20,}(["']?)/gi,
|
|
25568
|
+
"$1[REDACTED]$2"
|
|
25569
|
+
);
|
|
25570
|
+
sanitized = sanitized.replace(/:\/\/[^@\s]+@/g, "://[CREDENTIALS]@");
|
|
25571
|
+
return sanitized;
|
|
25572
|
+
}
|
|
25426
25573
|
function containsPathTraversal3(inputPath) {
|
|
25427
25574
|
const normalized = path10__default.normalize(inputPath);
|
|
25428
25575
|
return normalized.includes("..") || inputPath.includes("\0");
|
|
@@ -25606,6 +25753,7 @@ function extractAndSavePrivateKeys(workDir, envFiles, logger15) {
|
|
|
25606
25753
|
].join("\n");
|
|
25607
25754
|
const keysFile = resolve(workDir, ".env.keys");
|
|
25608
25755
|
writeFileSync(keysFile, keysContent, "utf-8");
|
|
25756
|
+
chmodSync(keysFile, 384);
|
|
25609
25757
|
logger15.success(` \u{1F511} Extracted ${Object.keys(privateKeys).length} keys \u2192 .env.keys`);
|
|
25610
25758
|
return true;
|
|
25611
25759
|
}
|
|
@@ -25687,7 +25835,7 @@ async function encryptFile2(workDir, filePath, logger15) {
|
|
|
25687
25835
|
return true;
|
|
25688
25836
|
} catch (error) {
|
|
25689
25837
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
25690
|
-
logger15.warn(` \u26A0\uFE0F Encryption failed: ${message}`);
|
|
25838
|
+
logger15.warn(` \u26A0\uFE0F Encryption failed: ${sanitizeErrorMessage(message)}`);
|
|
25691
25839
|
return false;
|
|
25692
25840
|
}
|
|
25693
25841
|
}
|
|
@@ -25701,6 +25849,7 @@ function buildVercelCmdEnv(auth) {
|
|
|
25701
25849
|
return cmdEnv;
|
|
25702
25850
|
}
|
|
25703
25851
|
function mapVercelError(message, environment, outputPath, logger15) {
|
|
25852
|
+
const safeMessage = sanitizeErrorMessage(message);
|
|
25704
25853
|
if (message.includes("not linked")) {
|
|
25705
25854
|
logger15.error(` \u2717 ${environment}: Project not linked to Vercel`);
|
|
25706
25855
|
return {
|
|
@@ -25728,8 +25877,8 @@ function mapVercelError(message, environment, outputPath, logger15) {
|
|
|
25728
25877
|
error: "Invalid VERCEL_TOKEN. Check your token is valid."
|
|
25729
25878
|
};
|
|
25730
25879
|
}
|
|
25731
|
-
logger15.error(` \u2717 ${environment}: ${
|
|
25732
|
-
return { environment, outputPath, success: false, error:
|
|
25880
|
+
logger15.error(` \u2717 ${environment}: ${safeMessage}`);
|
|
25881
|
+
return { environment, outputPath, success: false, error: safeMessage };
|
|
25733
25882
|
}
|
|
25734
25883
|
async function pullEnvironment(workDir, environment, auth, logger15, options = {}) {
|
|
25735
25884
|
const outputPath = getOutputPath(workDir, environment);
|
|
@@ -25942,16 +26091,12 @@ var pullCommand = new Command("pull").description("Pull all environments from Ve
|
|
|
25942
26091
|
await runEnvPullAction(options);
|
|
25943
26092
|
} catch (error) {
|
|
25944
26093
|
if (error instanceof CLIError) throw error;
|
|
25945
|
-
|
|
25946
|
-
|
|
25947
|
-
"
|
|
25948
|
-
|
|
25949
|
-
|
|
25950
|
-
|
|
25951
|
-
"Check network connectivity"
|
|
25952
|
-
],
|
|
25953
|
-
error instanceof Error ? error : void 0
|
|
25954
|
-
);
|
|
26094
|
+
const rawMessage = error instanceof Error ? error.message : "Environment pull failed";
|
|
26095
|
+
throw new CLIError(sanitizeErrorMessage(rawMessage), "ENV_PULL_FAILED", [
|
|
26096
|
+
"Check Vercel CLI is installed: vercel --version",
|
|
26097
|
+
"Ensure project is linked: vercel link",
|
|
26098
|
+
"Check network connectivity"
|
|
26099
|
+
]);
|
|
25955
26100
|
}
|
|
25956
26101
|
});
|
|
25957
26102
|
|
|
@@ -29361,6 +29506,29 @@ async function installTemplates(tempDir, authToken, verbose) {
|
|
|
29361
29506
|
]);
|
|
29362
29507
|
}
|
|
29363
29508
|
}
|
|
29509
|
+
async function verifyNoSymlinks(dir, baseDir) {
|
|
29510
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
29511
|
+
for (const entry of entries) {
|
|
29512
|
+
const fullPath = path10__default.join(dir, entry.name);
|
|
29513
|
+
const stats = await lstat(fullPath);
|
|
29514
|
+
if (stats.isSymbolicLink()) {
|
|
29515
|
+
const relativePath = path10__default.relative(baseDir, fullPath);
|
|
29516
|
+
throw new CLIError(
|
|
29517
|
+
"Security: Symlink detected in template package.",
|
|
29518
|
+
"SYMLINK_ATTACK_DETECTED",
|
|
29519
|
+
[
|
|
29520
|
+
`Symlink found: ${relativePath}`,
|
|
29521
|
+
"This could be an attempt to access files outside the template directory.",
|
|
29522
|
+
"The template package may be malicious or corrupted.",
|
|
29523
|
+
"Please report this issue if you believe this is a false positive."
|
|
29524
|
+
]
|
|
29525
|
+
);
|
|
29526
|
+
}
|
|
29527
|
+
if (stats.isDirectory()) {
|
|
29528
|
+
await verifyNoSymlinks(fullPath, baseDir);
|
|
29529
|
+
}
|
|
29530
|
+
}
|
|
29531
|
+
}
|
|
29364
29532
|
async function copyToCache(tempDir, cacheDir) {
|
|
29365
29533
|
const sourceTemplates = path10__default.join(tempDir, "node_modules", TEMPLATES_PACKAGE_NAME, "templates");
|
|
29366
29534
|
if (!fs6__default.existsSync(sourceTemplates)) {
|
|
@@ -29370,9 +29538,13 @@ async function copyToCache(tempDir, cacheDir) {
|
|
|
29370
29538
|
"Try running with --fresh to re-download."
|
|
29371
29539
|
]);
|
|
29372
29540
|
}
|
|
29541
|
+
await verifyNoSymlinks(sourceTemplates, sourceTemplates);
|
|
29373
29542
|
await mkdir(cacheDir, { recursive: true });
|
|
29374
29543
|
const targetTemplates = path10__default.join(cacheDir, "templates");
|
|
29375
|
-
await cp(sourceTemplates, targetTemplates, {
|
|
29544
|
+
await cp(sourceTemplates, targetTemplates, {
|
|
29545
|
+
recursive: true,
|
|
29546
|
+
dereference: false
|
|
29547
|
+
});
|
|
29376
29548
|
}
|
|
29377
29549
|
async function fetchTemplates(options = {}) {
|
|
29378
29550
|
const version = options.version ?? COMPATIBLE_TEMPLATES_VERSION;
|
|
@@ -33431,9 +33603,9 @@ function printActionsNeeded(logger15, actions) {
|
|
|
33431
33603
|
}
|
|
33432
33604
|
function findRepoRoot3(startDir) {
|
|
33433
33605
|
const { existsSync: existsSync49, readFileSync: readFileSync27 } = __require("fs");
|
|
33434
|
-
const { join: join22, dirname:
|
|
33606
|
+
const { join: join22, dirname: dirname5 } = __require("path");
|
|
33435
33607
|
let current = startDir;
|
|
33436
|
-
while (current !==
|
|
33608
|
+
while (current !== dirname5(current)) {
|
|
33437
33609
|
if (existsSync49(join22(current, "turbo.json"))) {
|
|
33438
33610
|
return current;
|
|
33439
33611
|
}
|
|
@@ -33447,7 +33619,7 @@ function findRepoRoot3(startDir) {
|
|
|
33447
33619
|
} catch {
|
|
33448
33620
|
}
|
|
33449
33621
|
}
|
|
33450
|
-
current =
|
|
33622
|
+
current = dirname5(current);
|
|
33451
33623
|
}
|
|
33452
33624
|
return startDir;
|
|
33453
33625
|
}
|
|
@@ -37146,8 +37318,8 @@ async function checkLicense() {
|
|
|
37146
37318
|
}
|
|
37147
37319
|
const result = await resolveGitHubOwner();
|
|
37148
37320
|
if (!result?.owner) {
|
|
37149
|
-
logger14.
|
|
37150
|
-
return { allowed:
|
|
37321
|
+
logger14.warn("[license] Could not determine repository owner, denying access");
|
|
37322
|
+
return { allowed: false, reason: "owner-resolution-failed" };
|
|
37151
37323
|
}
|
|
37152
37324
|
const owner = result.owner;
|
|
37153
37325
|
if (isTrustedOrg(owner)) {
|
|
@@ -3,14 +3,24 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Purpose: Load and parse configuration files
|
|
5
5
|
* Supports: YAML and JSON formats
|
|
6
|
+
*
|
|
7
|
+
* Security:
|
|
8
|
+
* - Path validation to prevent path traversal attacks (Issue #537)
|
|
9
|
+
* - Config/ignore files must be within rootDir boundary
|
|
6
10
|
*/
|
|
7
11
|
import type { IgnoreRule, VulnCheckerConfig } from '../types.js';
|
|
8
12
|
/**
|
|
9
13
|
* Load configuration file
|
|
14
|
+
*
|
|
15
|
+
* SECURITY (Issue #537): Validates that configPath is within rootDir boundary
|
|
16
|
+
* to prevent path traversal attacks.
|
|
10
17
|
*/
|
|
11
18
|
export declare function loadConfig(configPath: string, rootDir: string): Promise<VulnCheckerConfig>;
|
|
12
19
|
/**
|
|
13
20
|
* Load ignore file
|
|
21
|
+
*
|
|
22
|
+
* SECURITY (Issue #537): Validates that ignorePath is within rootDir boundary
|
|
23
|
+
* to prevent path traversal attacks.
|
|
14
24
|
*/
|
|
15
25
|
export declare function loadIgnores(ignorePath: string, rootDir: string): Promise<IgnoreRule[]>;
|
|
16
26
|
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../../src/internal/vuln-checker/config/loader.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../../src/internal/vuln-checker/config/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEjE;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAoBhG;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CA+B5F"}
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Purpose: Comprehensive security scanning for TypeScript/PostgreSQL projects
|
|
5
5
|
* Philosophy: AST-based analysis + pattern matching + false positive management
|
|
6
|
+
*
|
|
7
|
+
* Security:
|
|
8
|
+
* - Path validation to prevent path traversal attacks (Issue #537)
|
|
9
|
+
* - Glob patterns and file lists are validated to stay within rootDir
|
|
6
10
|
*/
|
|
7
11
|
import type { Category, ScanResult, Severity } from './types.js';
|
|
8
12
|
export * from './types.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/internal/vuln-checker/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/internal/vuln-checker/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAcH,OAAO,KAAK,EAGV,QAAQ,EAKR,UAAU,EACV,QAAQ,EAET,MAAM,YAAY,CAAC;AAEpB,cAAc,YAAY,CAAC;AAE3B,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;IACnD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AA6ED,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,SAAS,CAAwB;IACzC,OAAO,CAAC,MAAM,CAAmD;gBAErD,OAAO,EAAE,kBAAkB;IA6CjC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IASrB,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC;YA6BnB,QAAQ;YAkBR,YAAY;IA2B1B,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,gBAAgB;IAQxB,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM;IAQ5B,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;IAK5B,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,GAAE,QAAiB,GAAG,MAAM;IAWlE,+CAA+C;IAC/C,SAAS,IAAI,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;CAGzD"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI HINT: Path Validation Security for Vulnerability Checker
|
|
3
|
+
*
|
|
4
|
+
* Purpose: Prevent path traversal attacks in vulnerability checker
|
|
5
|
+
* Features:
|
|
6
|
+
* - Validates paths are within allowed boundaries
|
|
7
|
+
* - Detects path traversal patterns (../, etc.)
|
|
8
|
+
* - Provides reusable validation functions
|
|
9
|
+
*
|
|
10
|
+
* @see Issue #537 - Path traversal in vulnerability checker
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* SECURITY (Issue #537): Validate that a path doesn't contain traversal patterns.
|
|
14
|
+
*
|
|
15
|
+
* Checks for patterns that could escape the intended directory:
|
|
16
|
+
* - .. (parent directory)
|
|
17
|
+
* - Null bytes (\0)
|
|
18
|
+
*
|
|
19
|
+
* @param inputPath - Path to validate
|
|
20
|
+
* @returns true if path contains traversal patterns
|
|
21
|
+
*/
|
|
22
|
+
export declare function containsPathTraversal(inputPath: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* SECURITY (Issue #537): Validate that a resolved path is within the allowed boundary.
|
|
25
|
+
*
|
|
26
|
+
* @param filePath - Path to validate (absolute or relative)
|
|
27
|
+
* @param boundaryDir - Boundary directory (e.g., rootDir)
|
|
28
|
+
* @returns true if the path is within the boundary
|
|
29
|
+
*/
|
|
30
|
+
export declare function isPathWithinBoundary(filePath: string, boundaryDir: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* SECURITY (Issue #537): Validate and resolve a path safely within boundary.
|
|
33
|
+
*
|
|
34
|
+
* @param inputPath - User-provided path (may be relative or absolute)
|
|
35
|
+
* @param boundaryDir - Boundary directory that path must be within
|
|
36
|
+
* @returns Resolved absolute path
|
|
37
|
+
* @throws Error if path is outside boundary or invalid
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolvePathWithinBoundary(inputPath: string, boundaryDir: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* SECURITY (Issue #537): Validate and resolve a path with symlink resolution.
|
|
42
|
+
*
|
|
43
|
+
* This is more secure as it resolves symlinks to detect symlink-based escapes.
|
|
44
|
+
*
|
|
45
|
+
* @param inputPath - User-provided path
|
|
46
|
+
* @param boundaryDir - Boundary directory
|
|
47
|
+
* @returns Resolved real path
|
|
48
|
+
* @throws Error if path is outside boundary, invalid, or doesn't exist
|
|
49
|
+
*/
|
|
50
|
+
export declare function resolveRealPathWithinBoundary(inputPath: string, boundaryDir: string): string;
|
|
51
|
+
/**
|
|
52
|
+
* SECURITY (Issue #537): Filter file list to only include paths within boundary.
|
|
53
|
+
*
|
|
54
|
+
* @param files - Array of file paths (from glob or similar)
|
|
55
|
+
* @param boundaryDir - Boundary directory
|
|
56
|
+
* @returns Array of files that are within the boundary
|
|
57
|
+
*/
|
|
58
|
+
export declare function filterPathsWithinBoundary(files: string[], boundaryDir: string): string[];
|
|
59
|
+
/**
|
|
60
|
+
* SECURITY (Issue #537): Validate glob patterns don't contain traversal.
|
|
61
|
+
*
|
|
62
|
+
* @param patterns - Array of glob patterns
|
|
63
|
+
* @throws Error if any pattern contains traversal
|
|
64
|
+
*/
|
|
65
|
+
export declare function validateGlobPatterns(patterns: string[]): void;
|
|
66
|
+
//# sourceMappingURL=path-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-validation.d.ts","sourceRoot":"","sources":["../../../../src/internal/vuln-checker/security/path-validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAWhE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAgBnF;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAiBxF;AAED;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAsB5F;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAGxF;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAM7D"}
|
|
@@ -7,15 +7,17 @@
|
|
|
7
7
|
* Design decisions:
|
|
8
8
|
* - r06-dev: Instant allow, NO API call, NO log (zero-impact)
|
|
9
9
|
* - External org: API check via allowlist with last-known-good fallback
|
|
10
|
-
* - Fail-
|
|
10
|
+
* - Fail-closed strategy (Issue #542):
|
|
11
|
+
* - Owner resolution failure: Deny access (prevents bypass via manipulation)
|
|
11
12
|
* - API available: Use live response
|
|
12
13
|
* - API error + cached: Use last-known-good (24h window)
|
|
13
|
-
* - API error + no cache:
|
|
14
|
-
* - Escape hatch: RUNA_SKIP_LICENSE_CHECK=1 bypasses all checks
|
|
14
|
+
* - API error + no cache: Deny access (new orgs blocked during outage)
|
|
15
|
+
* - Escape hatch: RUNA_SKIP_LICENSE_CHECK=1 bypasses all checks (local only)
|
|
15
16
|
*
|
|
16
17
|
* Security model:
|
|
18
|
+
* - Fail-closed: Any resolution/validation error denies access
|
|
17
19
|
* - Known orgs protected during outages (last-known-good)
|
|
18
|
-
* - Unknown orgs cannot bypass by causing
|
|
20
|
+
* - Unknown orgs cannot bypass by causing errors (fail closed)
|
|
19
21
|
*/
|
|
20
22
|
import type { LicenseCheckResult } from './types.js';
|
|
21
23
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/license/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/license/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAOH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAerD;;;;GAIG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAqDhE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAMxD;AAGD,YAAY,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/F,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -37,6 +37,8 @@ export interface LicenseCheckResult {
|
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
39
|
* Reasons for license check decisions
|
|
40
|
+
*
|
|
41
|
+
* SECURITY (Issue #542): Fail-closed design - errors result in denial
|
|
40
42
|
*/
|
|
41
|
-
export type LicenseCheckReason = 'not-ci' | 'trusted-org' | 'allowlist' | 'not-found' | 'error' | 'skip-flag';
|
|
43
|
+
export type LicenseCheckReason = 'not-ci' | 'trusted-org' | 'allowlist' | 'not-found' | 'error' | 'owner-resolution-failed' | 'skip-flag';
|
|
42
44
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/license/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,wCAAwC;IACxC,IAAI,EAAE,OAAO,CAAC;IACd,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,MAAM,EAAE,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,cAAc,CAAC;CACrE;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/license/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,wCAAwC;IACxC,IAAI,EAAE,OAAO,CAAC;IACd,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,MAAM,EAAE,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,cAAc,CAAC;CACrE;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAC1B,QAAQ,GACR,aAAa,GACb,WAAW,GACX,WAAW,GACX,OAAO,GACP,yBAAyB,GACzB,WAAW,CAAC"}
|
|
@@ -40,6 +40,11 @@ export declare function clearBinaryPathCache(): void;
|
|
|
40
40
|
* - Caches results with TTL and PATH fingerprint for invalidation
|
|
41
41
|
* - Re-validates cached paths are still executable
|
|
42
42
|
*
|
|
43
|
+
* SECURITY (Issue #541):
|
|
44
|
+
* - Resolves symlinks and validates target is in trusted directory
|
|
45
|
+
* - Returns the real path (after symlink resolution), not the symlink
|
|
46
|
+
* - Prevents TOCTOU attacks via symlink replacement
|
|
47
|
+
*
|
|
43
48
|
* @throws Error if binary is not trusted or not found
|
|
44
49
|
*/
|
|
45
50
|
export declare function resolveBinaryPath(binaryName: string): string;
|
|
@@ -56,6 +61,10 @@ export declare function isBinaryAvailable(binaryName: string): boolean;
|
|
|
56
61
|
* 3. Validates the path is executable
|
|
57
62
|
* 4. Passes the absolute path to execa with shell: false
|
|
58
63
|
*
|
|
64
|
+
* SECURITY (Issue #541): This function also:
|
|
65
|
+
* 5. Resolves symlinks and validates target is in trusted directory
|
|
66
|
+
* 6. Performs final validation right before execution to minimize TOCTOU window
|
|
67
|
+
*
|
|
59
68
|
* @param binaryName - Name of the trusted binary to execute
|
|
60
69
|
* @param args - Arguments to pass to the binary
|
|
61
70
|
* @param options - execa options
|
|
@@ -70,6 +79,10 @@ export declare function secureExeca(binaryName: TrustedBinary, args?: readonly s
|
|
|
70
79
|
* - Only executes from the project's node_modules/.bin directory
|
|
71
80
|
* - Validates the binary name to prevent path traversal
|
|
72
81
|
* - Uses shell: false
|
|
82
|
+
*
|
|
83
|
+
* SECURITY (Issue #541):
|
|
84
|
+
* - Resolves symlinks and validates target is within project
|
|
85
|
+
* - Performs final validation before execution
|
|
73
86
|
*/
|
|
74
87
|
export declare function secureExecaLocal(binaryName: string, args?: readonly string[], options?: ExecaOptions & {
|
|
75
88
|
cwd?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secure-exec.d.ts","sourceRoot":"","sources":["../../src/utils/secure-exec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,EAAE,KAAK,OAAO,IAAI,YAAY,EAAE,KAAK,aAAa,EAAS,MAAM,OAAO,CAAC;AAMhF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,gIAenB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AA8D9D;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;
|
|
1
|
+
{"version":3,"file":"secure-exec.d.ts","sourceRoot":"","sources":["../../src/utils/secure-exec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,EAAE,KAAK,OAAO,IAAI,YAAY,EAAE,KAAK,aAAa,EAAS,MAAM,OAAO,CAAC;AAMhF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,gIAenB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AA8D9D;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAsJD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAoE5D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAO7D;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,aAAa,EACzB,IAAI,GAAE,SAAS,MAAM,EAAO,EAC5B,OAAO,CAAC,EAAE,YAAY,GACrB,aAAa,CAef;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,SAAS,MAAM,EAAO,EAC5B,OAAO,CAAC,EAAE,YAAY,GAAG;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACxC,aAAa,CAwDf;AAMD;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,GAAE,SAAS,MAAM,EAAO,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,aAAa,CAE9F;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,GAAE,SAAS,MAAM,EAAO,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,aAAa,CAE7F;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,GAAE,SAAS,MAAM,EAAO,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,aAAa,CAE5F;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,SAAS,MAAM,EAAO,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,aAAa,CAEhG;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,GAAE,SAAS,MAAM,EAAO,EAC5B,OAAO,CAAC,EAAE,YAAY,GACrB,aAAa,CAEf;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,SAAS,MAAM,EAAO,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,aAAa,CAEhG;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,GAAE,SAAS,MAAM,EAAO,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,aAAa,CAE9F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template-fetcher.d.ts","sourceRoot":"","sources":["../../src/utils/template-fetcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAkEH,MAAM,WAAW,qBAAqB;IACpC,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0BAA0B;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,MAAM,EAAE,OAAO,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"template-fetcher.d.ts","sourceRoot":"","sources":["../../src/utils/template-fetcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAkEH,MAAM,WAAW,qBAAqB;IACpC,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0BAA0B;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,MAAM,EAAE,OAAO,CAAC;CACjB;AA+RD;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,oBAAoB,CAAC,CAgF/B;AAmGD;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAKzD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runa-ai/runa-cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.33",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "AI-powered DevOps CLI",
|
|
6
6
|
"type": "module",
|
|
@@ -26,8 +26,6 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@dotenvx/dotenvx": "1.51.4",
|
|
29
|
-
"@runa-ai/runa": "^0.5.31",
|
|
30
|
-
"@runa-ai/runa-xstate-test-plugin": "^0.5.28",
|
|
31
29
|
"@types/node": "22.19.3",
|
|
32
30
|
"boxen": "7.1.1",
|
|
33
31
|
"chalk": "5.6.2",
|
|
@@ -53,7 +51,9 @@
|
|
|
53
51
|
"tsup": "8.5.1",
|
|
54
52
|
"typescript": "5.9.3",
|
|
55
53
|
"xstate": "5.25.0",
|
|
56
|
-
"zod": "4.3.5"
|
|
54
|
+
"zod": "4.3.5",
|
|
55
|
+
"@runa-ai/runa": "0.5.33",
|
|
56
|
+
"@runa-ai/runa-xstate-test-plugin": "0.5.28"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|
|
59
59
|
"node": ">=20.0.0"
|