cc-safety-net 0.8.1 → 0.8.2
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/bin/cc-safety-net.js +14 -37
- package/dist/core/rules-rm.d.ts +1 -0
- package/dist/index.js +10 -23
- package/package.json +1 -1
|
@@ -2865,6 +2865,7 @@ function normalizePathForComparison(p) {
|
|
|
2865
2865
|
}
|
|
2866
2866
|
var REASON_RM_RF = "rm -rf outside cwd is blocked. Use explicit paths within the current directory, or delete manually.";
|
|
2867
2867
|
var REASON_RM_RF_ROOT_HOME = "rm -rf targeting root or home directory is extremely dangerous and always blocked.";
|
|
2868
|
+
var REASON_RM_HOME_CWD = "rm -rf in home directory is dangerous. Change to a project directory first.";
|
|
2868
2869
|
function analyzeRm(tokens, options = {}) {
|
|
2869
2870
|
const {
|
|
2870
2871
|
cwd,
|
|
@@ -2921,18 +2922,16 @@ function classifyTarget(target, ctx) {
|
|
|
2921
2922
|
if (isDangerousRootOrHomeTarget(target)) {
|
|
2922
2923
|
return { kind: "root_or_home_target" };
|
|
2923
2924
|
}
|
|
2924
|
-
const anchoredCwd = ctx.anchoredCwd;
|
|
2925
|
-
if (anchoredCwd) {
|
|
2926
|
-
if (isCwdSelfTarget(target, anchoredCwd)) {
|
|
2927
|
-
return { kind: "cwd_self_target" };
|
|
2928
|
-
}
|
|
2929
|
-
}
|
|
2930
2925
|
if (isTempTarget(target, ctx.trustTmpdirVar)) {
|
|
2931
2926
|
return { kind: "temp_target" };
|
|
2932
2927
|
}
|
|
2928
|
+
const anchoredCwd = ctx.anchoredCwd;
|
|
2933
2929
|
if (anchoredCwd) {
|
|
2934
2930
|
if (isCwdHomeForRmPolicy(anchoredCwd, ctx.homeDir)) {
|
|
2935
|
-
return { kind: "
|
|
2931
|
+
return { kind: "home_cwd_target" };
|
|
2932
|
+
}
|
|
2933
|
+
if (isCwdSelfTarget(target, anchoredCwd)) {
|
|
2934
|
+
return { kind: "cwd_self_target" };
|
|
2936
2935
|
}
|
|
2937
2936
|
if (isTargetWithinCwd(target, anchoredCwd, ctx.resolvedCwd ?? anchoredCwd)) {
|
|
2938
2937
|
return { kind: "within_anchored_cwd" };
|
|
@@ -2944,10 +2943,12 @@ function reasonForClassification(classification, ctx) {
|
|
|
2944
2943
|
switch (classification.kind) {
|
|
2945
2944
|
case "root_or_home_target":
|
|
2946
2945
|
return REASON_RM_RF_ROOT_HOME;
|
|
2947
|
-
case "cwd_self_target":
|
|
2948
|
-
return REASON_RM_RF;
|
|
2949
2946
|
case "temp_target":
|
|
2950
2947
|
return null;
|
|
2948
|
+
case "home_cwd_target":
|
|
2949
|
+
return REASON_RM_HOME_CWD;
|
|
2950
|
+
case "cwd_self_target":
|
|
2951
|
+
return REASON_RM_RF;
|
|
2951
2952
|
case "within_anchored_cwd":
|
|
2952
2953
|
if (ctx.paranoid) {
|
|
2953
2954
|
return `${REASON_RM_RF} (SAFETY_NET_PARANOID_RM enabled)`;
|
|
@@ -3069,14 +3070,6 @@ function isTargetWithinCwd(target, originalCwd, effectiveCwd) {
|
|
|
3069
3070
|
return false;
|
|
3070
3071
|
}
|
|
3071
3072
|
}
|
|
3072
|
-
function isHomeDirectory(cwd) {
|
|
3073
|
-
const home = process.env.HOME ?? homedir3();
|
|
3074
|
-
try {
|
|
3075
|
-
return normalizePathForComparison(cwd) === normalizePathForComparison(home);
|
|
3076
|
-
} catch {
|
|
3077
|
-
return false;
|
|
3078
|
-
}
|
|
3079
|
-
}
|
|
3080
3073
|
|
|
3081
3074
|
// src/core/analyze/parallel.ts
|
|
3082
3075
|
var REASON_PARALLEL_RM = "parallel rm -rf with dynamic input is dangerous. Use explicit file list instead.";
|
|
@@ -3497,7 +3490,6 @@ function matchesBlockArgs(tokens, blockArgs, shortOpts) {
|
|
|
3497
3490
|
// src/core/analyze/segment.ts
|
|
3498
3491
|
var REASON_INTERPRETER_DANGEROUS = "Detected potentially dangerous command in interpreter code.";
|
|
3499
3492
|
var REASON_INTERPRETER_BLOCKED = "Interpreter one-liners are blocked in paranoid mode.";
|
|
3500
|
-
var REASON_RM_HOME_CWD = "rm -rf in home directory is dangerous. Change to a project directory first.";
|
|
3501
3493
|
function deriveCwdContext(options) {
|
|
3502
3494
|
const cwdUnknown = options.effectiveCwd === null;
|
|
3503
3495
|
const cwdForRm = cwdUnknown ? undefined : options.effectiveCwd ?? options.cwd;
|
|
@@ -3561,11 +3553,6 @@ function analyzeSegment(tokens, depth, options) {
|
|
|
3561
3553
|
}
|
|
3562
3554
|
}
|
|
3563
3555
|
if (isRm) {
|
|
3564
|
-
if (cwdForRm && isHomeDirectory(cwdForRm)) {
|
|
3565
|
-
if (hasRecursiveForceFlags(stripped)) {
|
|
3566
|
-
return REASON_RM_HOME_CWD;
|
|
3567
|
-
}
|
|
3568
|
-
}
|
|
3569
3556
|
const rmResult = analyzeRm(stripped, {
|
|
3570
3557
|
cwd: cwdForRm,
|
|
3571
3558
|
originalCwd,
|
|
@@ -4208,7 +4195,7 @@ function detectAllHooks(cwd, options) {
|
|
|
4208
4195
|
|
|
4209
4196
|
// src/bin/doctor/system-info.ts
|
|
4210
4197
|
import { spawn } from "node:child_process";
|
|
4211
|
-
var CURRENT_VERSION = "0.8.
|
|
4198
|
+
var CURRENT_VERSION = "0.8.2";
|
|
4212
4199
|
var VERSION_FETCH_TIMEOUT_MS = 2000;
|
|
4213
4200
|
function getPackageVersion() {
|
|
4214
4201
|
return CURRENT_VERSION;
|
|
@@ -4682,19 +4669,9 @@ function explainSegment(tokens, depth, options, steps) {
|
|
|
4682
4669
|
return { reason };
|
|
4683
4670
|
}
|
|
4684
4671
|
if (isRm) {
|
|
4685
|
-
if (effectiveCwd && isHomeDirectory(effectiveCwd) && hasRecursiveForceFlags(strippedTokens)) {
|
|
4686
|
-
const reason2 = "rm -rf in home directory is dangerous. Change to a project directory first.";
|
|
4687
|
-
steps.push({
|
|
4688
|
-
type: "rule-check",
|
|
4689
|
-
ruleModule: "rules-rm.ts",
|
|
4690
|
-
ruleFunction: "isHomeDirectory",
|
|
4691
|
-
matched: true,
|
|
4692
|
-
reason: reason2
|
|
4693
|
-
});
|
|
4694
|
-
return { reason: reason2 };
|
|
4695
|
-
}
|
|
4696
4672
|
const reason = analyzeRm(strippedTokens, {
|
|
4697
|
-
cwd:
|
|
4673
|
+
cwd: cwdForRm,
|
|
4674
|
+
originalCwd,
|
|
4698
4675
|
paranoid: options.paranoidRm,
|
|
4699
4676
|
allowTmpdirVar
|
|
4700
4677
|
});
|
|
@@ -5291,7 +5268,7 @@ function formatTraceJson(result) {
|
|
|
5291
5268
|
return JSON.stringify(result, null, 2);
|
|
5292
5269
|
}
|
|
5293
5270
|
// src/bin/help.ts
|
|
5294
|
-
var version = "0.8.
|
|
5271
|
+
var version = "0.8.2";
|
|
5295
5272
|
var INDENT = " ";
|
|
5296
5273
|
var PROGRAM_NAME = "cc-safety-net";
|
|
5297
5274
|
function formatOptionFlags(option) {
|
package/dist/core/rules-rm.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1724,6 +1724,7 @@ function normalizePathForComparison(p) {
|
|
|
1724
1724
|
}
|
|
1725
1725
|
var REASON_RM_RF = "rm -rf outside cwd is blocked. Use explicit paths within the current directory, or delete manually.";
|
|
1726
1726
|
var REASON_RM_RF_ROOT_HOME = "rm -rf targeting root or home directory is extremely dangerous and always blocked.";
|
|
1727
|
+
var REASON_RM_HOME_CWD = "rm -rf in home directory is dangerous. Change to a project directory first.";
|
|
1727
1728
|
function analyzeRm(tokens, options = {}) {
|
|
1728
1729
|
const {
|
|
1729
1730
|
cwd,
|
|
@@ -1780,18 +1781,16 @@ function classifyTarget(target, ctx) {
|
|
|
1780
1781
|
if (isDangerousRootOrHomeTarget(target)) {
|
|
1781
1782
|
return { kind: "root_or_home_target" };
|
|
1782
1783
|
}
|
|
1783
|
-
const anchoredCwd = ctx.anchoredCwd;
|
|
1784
|
-
if (anchoredCwd) {
|
|
1785
|
-
if (isCwdSelfTarget(target, anchoredCwd)) {
|
|
1786
|
-
return { kind: "cwd_self_target" };
|
|
1787
|
-
}
|
|
1788
|
-
}
|
|
1789
1784
|
if (isTempTarget(target, ctx.trustTmpdirVar)) {
|
|
1790
1785
|
return { kind: "temp_target" };
|
|
1791
1786
|
}
|
|
1787
|
+
const anchoredCwd = ctx.anchoredCwd;
|
|
1792
1788
|
if (anchoredCwd) {
|
|
1793
1789
|
if (isCwdHomeForRmPolicy(anchoredCwd, ctx.homeDir)) {
|
|
1794
|
-
return { kind: "
|
|
1790
|
+
return { kind: "home_cwd_target" };
|
|
1791
|
+
}
|
|
1792
|
+
if (isCwdSelfTarget(target, anchoredCwd)) {
|
|
1793
|
+
return { kind: "cwd_self_target" };
|
|
1795
1794
|
}
|
|
1796
1795
|
if (isTargetWithinCwd(target, anchoredCwd, ctx.resolvedCwd ?? anchoredCwd)) {
|
|
1797
1796
|
return { kind: "within_anchored_cwd" };
|
|
@@ -1803,10 +1802,12 @@ function reasonForClassification(classification, ctx) {
|
|
|
1803
1802
|
switch (classification.kind) {
|
|
1804
1803
|
case "root_or_home_target":
|
|
1805
1804
|
return REASON_RM_RF_ROOT_HOME;
|
|
1806
|
-
case "cwd_self_target":
|
|
1807
|
-
return REASON_RM_RF;
|
|
1808
1805
|
case "temp_target":
|
|
1809
1806
|
return null;
|
|
1807
|
+
case "home_cwd_target":
|
|
1808
|
+
return REASON_RM_HOME_CWD;
|
|
1809
|
+
case "cwd_self_target":
|
|
1810
|
+
return REASON_RM_RF;
|
|
1810
1811
|
case "within_anchored_cwd":
|
|
1811
1812
|
if (ctx.paranoid) {
|
|
1812
1813
|
return `${REASON_RM_RF} (SAFETY_NET_PARANOID_RM enabled)`;
|
|
@@ -1928,14 +1929,6 @@ function isTargetWithinCwd(target, originalCwd, effectiveCwd) {
|
|
|
1928
1929
|
return false;
|
|
1929
1930
|
}
|
|
1930
1931
|
}
|
|
1931
|
-
function isHomeDirectory(cwd) {
|
|
1932
|
-
const home = process.env.HOME ?? homedir();
|
|
1933
|
-
try {
|
|
1934
|
-
return normalizePathForComparison(cwd) === normalizePathForComparison(home);
|
|
1935
|
-
} catch {
|
|
1936
|
-
return false;
|
|
1937
|
-
}
|
|
1938
|
-
}
|
|
1939
1932
|
|
|
1940
1933
|
// src/core/analyze/parallel.ts
|
|
1941
1934
|
var REASON_PARALLEL_RM = "parallel rm -rf with dynamic input is dangerous. Use explicit file list instead.";
|
|
@@ -2356,7 +2349,6 @@ function matchesBlockArgs(tokens, blockArgs, shortOpts) {
|
|
|
2356
2349
|
// src/core/analyze/segment.ts
|
|
2357
2350
|
var REASON_INTERPRETER_DANGEROUS = "Detected potentially dangerous command in interpreter code.";
|
|
2358
2351
|
var REASON_INTERPRETER_BLOCKED = "Interpreter one-liners are blocked in paranoid mode.";
|
|
2359
|
-
var REASON_RM_HOME_CWD = "rm -rf in home directory is dangerous. Change to a project directory first.";
|
|
2360
2352
|
function deriveCwdContext(options) {
|
|
2361
2353
|
const cwdUnknown = options.effectiveCwd === null;
|
|
2362
2354
|
const cwdForRm = cwdUnknown ? undefined : options.effectiveCwd ?? options.cwd;
|
|
@@ -2420,11 +2412,6 @@ function analyzeSegment(tokens, depth, options) {
|
|
|
2420
2412
|
}
|
|
2421
2413
|
}
|
|
2422
2414
|
if (isRm) {
|
|
2423
|
-
if (cwdForRm && isHomeDirectory(cwdForRm)) {
|
|
2424
|
-
if (hasRecursiveForceFlags(stripped)) {
|
|
2425
|
-
return REASON_RM_HOME_CWD;
|
|
2426
|
-
}
|
|
2427
|
-
}
|
|
2428
2415
|
const rmResult = analyzeRm(stripped, {
|
|
2429
2416
|
cwd: cwdForRm,
|
|
2430
2417
|
originalCwd,
|
package/package.json
CHANGED