@rhize/skill-forge 0.11.2 → 0.11.3

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/cli.js CHANGED
@@ -1049,6 +1049,37 @@ import { execFile } from "child_process";
1049
1049
  import { delimiter as delimiter2, join as join9 } from "path";
1050
1050
  import { promisify } from "util";
1051
1051
  var execFileAsync = promisify(execFile);
1052
+ var RM_RF_TARGET_RE = /\brm\s+(?:-[a-z]+\s+)+("[^"]*"|'[^']*'|[^\s;|&)"'`]+)/i;
1053
+ function refineRmRf(line) {
1054
+ const match = line.match(RM_RF_TARGET_RE);
1055
+ if (!match) {
1056
+ return { severity: "HIGH", message: "recursive force-delete (rm -rf) with an unparseable target \u2014 verify the path is scoped" };
1057
+ }
1058
+ const target = match[1].replace(/^["']|["']$/g, "").trim();
1059
+ if (target.includes("$") || target.includes("`")) {
1060
+ return {
1061
+ severity: "HIGH",
1062
+ message: `recursive force-delete of "${target}" \u2014 the target is a shell expansion; if it is empty or unset this can delete far more than intended`
1063
+ };
1064
+ }
1065
+ if (target === "/" || target === "/*" || target === "*" || target === "." || target === ".." || target === "~" || target === "~/") {
1066
+ return { severity: "HIGH", message: `recursive force-delete of "${target}" \u2014 this targets the filesystem root, the home directory, or everything in the working directory` };
1067
+ }
1068
+ if (target.startsWith("~")) {
1069
+ return { severity: "HIGH", message: `recursive force-delete of "${target}" \u2014 targets a path inside the home directory, outside any project` };
1070
+ }
1071
+ if (target.split("/").includes("..")) {
1072
+ return { severity: "HIGH", message: `recursive force-delete of "${target}" \u2014 the target escapes the current directory via ".."` };
1073
+ }
1074
+ if (target.startsWith("/")) {
1075
+ const segments = target.split("/").filter(Boolean);
1076
+ if (segments.length < 3) {
1077
+ return { severity: "HIGH", message: `recursive force-delete of "${target}" \u2014 a shallow absolute path like this is a system directory` };
1078
+ }
1079
+ return { severity: "MEDIUM", message: `recursive force-delete of "${target}" \u2014 an absolute path outside any project directory` };
1080
+ }
1081
+ return null;
1082
+ }
1052
1083
  var DENY_RULES = [
1053
1084
  {
1054
1085
  rule: "curl-pipe-shell",
@@ -1072,7 +1103,8 @@ var DENY_RULES = [
1072
1103
  rule: "destructive-rm-rf",
1073
1104
  severity: "HIGH",
1074
1105
  pattern: /\brm\s+-[a-z]*r[a-z]*f[a-z]*\b|\brm\s+-[a-z]*f[a-z]*r[a-z]*\b/i,
1075
- message: "recursive force-delete (rm -rf) \u2014 verify the target path is scoped"
1106
+ message: "recursive force-delete (rm -rf) \u2014 verify the target path is scoped",
1107
+ refine: refineRmRf
1076
1108
  },
1077
1109
  {
1078
1110
  rule: "credential-file-access",
@@ -1127,11 +1159,13 @@ function scanStaticRules(targetPath) {
1127
1159
  for (const rule of DENY_RULES) {
1128
1160
  for (let i = 0; i < lines.length; i++) {
1129
1161
  if (rule.pattern.test(lines[i])) {
1162
+ const refined = rule.refine ? rule.refine(lines[i]) : { severity: rule.severity, message: rule.message };
1163
+ if (!refined) continue;
1130
1164
  findings.push({
1131
- severity: rule.severity,
1165
+ severity: refined.severity,
1132
1166
  rule: rule.rule,
1133
1167
  file,
1134
- detail: `line ${i + 1}: ${rule.message}`
1168
+ detail: `line ${i + 1}: ${refined.message}`
1135
1169
  });
1136
1170
  }
1137
1171
  }