@wrongstack/tools 0.276.3 → 0.277.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/exec.js CHANGED
@@ -809,16 +809,28 @@ function resolveWin32Command(cmd) {
809
809
  }
810
810
  return cmd;
811
811
  }
812
- var WIN32_SHELL_META = /[&|<>\r\n\0]/;
812
+ var WIN32_SHELL_META = /[&|<>"\r\n\0]/;
813
813
  function assertSafeWin32ShellArgs(args) {
814
- for (const a of args) {
815
- if (typeof a === "string" && WIN32_SHELL_META.test(a)) {
814
+ for (const arg of args) {
815
+ if (typeof arg === "string" && WIN32_SHELL_META.test(arg)) {
816
816
  throw new Error(
817
- "win32 shell spawn: argument contains a shell metacharacter (one of & | < > or a newline) that could enable command injection through the .cmd/.bat wrapper \u2014 refusing to run. Offending argument: " + JSON.stringify(a)
817
+ 'win32 cmd shim spawn: argument contains a shell metacharacter (one of & | < > ", or a newline) that could enable command injection through the .cmd/.bat wrapper - refusing to run. Offending argument: ' + JSON.stringify(arg)
818
818
  );
819
819
  }
820
820
  }
821
821
  }
822
+ function buildWin32CmdShimInvocation(command, args = []) {
823
+ assertSafeWin32ShellArgs([command, ...args]);
824
+ const line = ["call", quoteWin32CmdArg(command), ...args.map(quoteWin32CmdArg)].join(" ");
825
+ return {
826
+ command: process.env["COMSPEC"] ?? "cmd.exe",
827
+ args: ["/d", "/c", line],
828
+ windowsVerbatimArguments: true
829
+ };
830
+ }
831
+ function quoteWin32CmdArg(arg) {
832
+ return `"${arg}"`;
833
+ }
822
834
 
823
835
  // src/exec.ts
824
836
  var isWin = process.platform === "win32";
@@ -889,10 +901,20 @@ var DEFAULT_ALLOWED_COMMANDS = /* @__PURE__ */ new Set([
889
901
  // C / C++ / native build
890
902
  "make",
891
903
  "cmake",
904
+ "ninja",
905
+ "clang",
906
+ "clang-cl",
907
+ "gcc",
908
+ "g++",
909
+ "link",
910
+ "msbuild",
892
911
  // containers / orchestration
893
912
  "docker",
894
913
  "podman",
895
914
  "kubectl",
915
+ // network (read-only intent; destructive ops still blocked by BLOCKED_ARG_PATTERNS)
916
+ "curl",
917
+ "wget",
896
918
  // common POSIX file/text utilities
897
919
  "pwd",
898
920
  "ls",
@@ -912,7 +934,496 @@ var DEFAULT_ALLOWED_COMMANDS = /* @__PURE__ */ new Set([
912
934
  "cp",
913
935
  "mv",
914
936
  "rm",
915
- "touch"
937
+ "touch",
938
+ "tar",
939
+ // Windows-native tooling (win32). All non-destructive binaries; per-arg
940
+ // safety is still enforced by BLOCKED_ARG_PATTERNS + the destructive-ops
941
+ // gate in bash-kill-guard.ts. `gh` is included even though it lives at
942
+ // "C:\Program Files\GitHub CLI\gh.exe" — resolveWin32Command handles the
943
+ // space in the path.
944
+ "gh",
945
+ "where",
946
+ "tasklist",
947
+ "systeminfo",
948
+ "wmic",
949
+ "sc",
950
+ "netstat",
951
+ "ipconfig",
952
+ "nslookup",
953
+ "tracert",
954
+ "pathping",
955
+ // [core] Extended default allowlist (added 4b3d18d1 + this commit). All
956
+ // non-destructive, broadly-used dev binaries. Per-arg safety is still
957
+ // enforced by BLOCKED_ARG_PATTERNS + bash-kill-guard.ts.
958
+ // --- Archives & compression ---
959
+ "7z",
960
+ "7za",
961
+ "bzip2",
962
+ "gzip",
963
+ "xz",
964
+ "unzip",
965
+ "zip",
966
+ "gtar",
967
+ "bsdtar",
968
+ "star",
969
+ "pax",
970
+ "cpio",
971
+ // --- Android / mobile dev ---
972
+ "adb",
973
+ "fastboot",
974
+ "sdkmanager",
975
+ // --- DevOps / config mgmt ---
976
+ "ansible",
977
+ "ansible-playbook",
978
+ "ansible-vault",
979
+ "ansible-lint",
980
+ "ansible-galaxy",
981
+ "molecule",
982
+ // --- Cloud CLIs ---
983
+ "aws",
984
+ "aws-vault",
985
+ "awslocal",
986
+ "az",
987
+ "azcopy",
988
+ "gcloud",
989
+ "gsutil",
990
+ "doctl",
991
+ "linode-cli",
992
+ // --- Native / C / C++ / linker tools ---
993
+ "clang++",
994
+ "clang-format",
995
+ "clang-tidy",
996
+ "clangd",
997
+ "lld",
998
+ "lldb",
999
+ "ctest",
1000
+ "gmake",
1001
+ "meson",
1002
+ "conan",
1003
+ "vcpkg",
1004
+ "cl",
1005
+ "rc",
1006
+ "mt",
1007
+ "dumpbin",
1008
+ "dotnet-format",
1009
+ // --- Image / media / binary tools ---
1010
+ "convert",
1011
+ "ffmpeg",
1012
+ "ffprobe",
1013
+ "magick",
1014
+ "gs",
1015
+ "exiftool",
1016
+ // --- HTTP / fetch ---
1017
+ "wget2",
1018
+ "aria2c",
1019
+ "axel",
1020
+ "httpie",
1021
+ "hey",
1022
+ "ab",
1023
+ "wrk",
1024
+ "http",
1025
+ // --- Diff / patch / merge ---
1026
+ "diff",
1027
+ "diff3",
1028
+ "patch",
1029
+ "meld",
1030
+ "kdiff3",
1031
+ "kompare",
1032
+ // --- Encoding / file inspection ---
1033
+ "dos2unix",
1034
+ "unix2dos",
1035
+ "iconv",
1036
+ "file",
1037
+ "stat",
1038
+ "xxd",
1039
+ "hexdump",
1040
+ "od",
1041
+ "base64",
1042
+ // --- SSH / crypto / signing ---
1043
+ "ssh",
1044
+ "ssh-add",
1045
+ "ssh-keygen",
1046
+ "ssh-keyscan",
1047
+ "scp",
1048
+ "sftp",
1049
+ "rsync",
1050
+ "gpg",
1051
+ "gpg2",
1052
+ "gpg-agent",
1053
+ "openssl",
1054
+ "step",
1055
+ "keytool",
1056
+ // --- Search ---
1057
+ "egrep",
1058
+ "fgrep",
1059
+ "ag",
1060
+ "ack",
1061
+ "sift",
1062
+ "ugrep",
1063
+ "fd",
1064
+ "fdfind",
1065
+ "jq",
1066
+ "yq",
1067
+ "xq",
1068
+ "fx",
1069
+ "gron",
1070
+ // --- K8s / container ecosystem ---
1071
+ "kubectl.exe",
1072
+ "kubeadm",
1073
+ "kubelet",
1074
+ "helm",
1075
+ "k9s",
1076
+ "kustomize",
1077
+ "skaffold",
1078
+ "tilt",
1079
+ "minikube",
1080
+ "kind",
1081
+ "k3d",
1082
+ "k3s",
1083
+ "docker-compose",
1084
+ "buildah",
1085
+ "skopeo",
1086
+ "nerdctl",
1087
+ "ctr",
1088
+ "ctr.exe",
1089
+ // --- Databases ---
1090
+ "sqlite3",
1091
+ "sqlite",
1092
+ "psql",
1093
+ "pg_dump",
1094
+ "pg_restore",
1095
+ "mysql",
1096
+ "mysqladmin",
1097
+ "mysqldump",
1098
+ "mariadb",
1099
+ "mariadb-dump",
1100
+ "redis-cli",
1101
+ "redis-server",
1102
+ "memcached",
1103
+ "etcdctl",
1104
+ "consul",
1105
+ "vault",
1106
+ "nomad",
1107
+ "mongosh",
1108
+ "mongo",
1109
+ "mongoexport",
1110
+ "mongoimport",
1111
+ "mongodump",
1112
+ "mongorestore",
1113
+ // --- Windows extended (read-mostly ops) ---
1114
+ "taskkill",
1115
+ "gpupdate",
1116
+ "gpresult",
1117
+ "hostname",
1118
+ "whoami",
1119
+ "who",
1120
+ "net",
1121
+ "net1",
1122
+ // --- VCS ecosystem ---
1123
+ "glab",
1124
+ "hub",
1125
+ "tea",
1126
+ "git-lfs",
1127
+ "tig",
1128
+ "lazygit",
1129
+ // --- POSIX text utilities (extended; duplicates of pwd/ls/cat/head/tail/wc/
1130
+ // grep/find/echo/awk/mkdir/cp/mv/rm/touch from the base list above are
1131
+ // omitted — the Set is de-duplicated at runtime but a clean literal is
1132
+ // easier to maintain) ---
1133
+ "gawk",
1134
+ "tr",
1135
+ "cut",
1136
+ "paste",
1137
+ "join",
1138
+ "comm",
1139
+ "expand",
1140
+ "unexpand",
1141
+ "fold",
1142
+ "fmt",
1143
+ "nl",
1144
+ "pr",
1145
+ "column",
1146
+ "tsort",
1147
+ "tty",
1148
+ "ul",
1149
+ "units",
1150
+ "factor",
1151
+ "seq",
1152
+ "shuf",
1153
+ "look",
1154
+ "yes",
1155
+ "true",
1156
+ "false",
1157
+ "test",
1158
+ "[",
1159
+ "printf",
1160
+ "env",
1161
+ "tree",
1162
+ "locate",
1163
+ "which",
1164
+ "whereis",
1165
+ "type",
1166
+ "hash",
1167
+ "pushd",
1168
+ "popd",
1169
+ "dirs",
1170
+ "history",
1171
+ "fc",
1172
+ "jobs",
1173
+ "bg",
1174
+ "fg",
1175
+ "wait",
1176
+ "ulimit",
1177
+ "umask",
1178
+ "nice",
1179
+ "nohup",
1180
+ "timeout",
1181
+ "time",
1182
+ "trap",
1183
+ "exit",
1184
+ "return",
1185
+ "source",
1186
+ ".",
1187
+ "alias",
1188
+ "unalias",
1189
+ "set",
1190
+ "unset",
1191
+ "export",
1192
+ "readonly",
1193
+ "typeset",
1194
+ "declare",
1195
+ "local",
1196
+ "eval",
1197
+ "exec",
1198
+ // --- Process / system inspection ---
1199
+ "htop",
1200
+ "top",
1201
+ "atop",
1202
+ "glances",
1203
+ "iotop",
1204
+ "nethogs",
1205
+ "iftop",
1206
+ "lsof",
1207
+ "strace",
1208
+ "ltrace",
1209
+ "sysstat",
1210
+ "vmstat",
1211
+ "iostat",
1212
+ "mpstat",
1213
+ "sar",
1214
+ "free",
1215
+ "df",
1216
+ "du",
1217
+ "mount",
1218
+ "umount",
1219
+ "lsblk",
1220
+ "blkid",
1221
+ "kill",
1222
+ "killall",
1223
+ "pkill",
1224
+ "pgrep",
1225
+ "pidof",
1226
+ "ps",
1227
+ "ps.exe",
1228
+ // --- Network inspection ---
1229
+ "ip",
1230
+ "ss",
1231
+ "route",
1232
+ "arp",
1233
+ "arping",
1234
+ "ping",
1235
+ "ping6",
1236
+ "hping3",
1237
+ "mtr",
1238
+ "tracepath",
1239
+ "tcpdump",
1240
+ "nmap",
1241
+ "netcat",
1242
+ "nc",
1243
+ "ncat",
1244
+ "socat",
1245
+ // --- Sync / backup ---
1246
+ "rclone",
1247
+ "restic",
1248
+ "borg",
1249
+ "duplicati",
1250
+ "duplicacy",
1251
+ "syncthing",
1252
+ "syncthing-cli",
1253
+ // --- Permissions / users / ACLs (POSIX) ---
1254
+ "useradd",
1255
+ "userdel",
1256
+ "usermod",
1257
+ "groupadd",
1258
+ "groupdel",
1259
+ "groupmod",
1260
+ "chown",
1261
+ "chmod",
1262
+ "chgrp",
1263
+ "getfacl",
1264
+ "setfacl",
1265
+ "setcap",
1266
+ "getcap",
1267
+ // --- Crypto / cert mgmt (extended) ---
1268
+ "certbot",
1269
+ "mkcert",
1270
+ "jarsigner",
1271
+ // --- Editors ---
1272
+ "subl",
1273
+ "code",
1274
+ "code-insiders",
1275
+ "cursor",
1276
+ "atom",
1277
+ "nano",
1278
+ "vim",
1279
+ "nvim",
1280
+ "vi",
1281
+ "emacs",
1282
+ "helix",
1283
+ "hx",
1284
+ "micro",
1285
+ "jed",
1286
+ "ed",
1287
+ "ex",
1288
+ "mg",
1289
+ // --- Terminal multiplexers ---
1290
+ "asciinema",
1291
+ "script",
1292
+ "scriptreplay",
1293
+ "expect",
1294
+ "screen",
1295
+ "tmux",
1296
+ "byobu",
1297
+ "dtach",
1298
+ "abduco",
1299
+ // --- Calculators / REPLs / scientific ---
1300
+ "bc",
1301
+ "dc",
1302
+ "calc",
1303
+ "qalc",
1304
+ "genius",
1305
+ "octave",
1306
+ "R",
1307
+ "Rscript",
1308
+ "julia",
1309
+ "irb",
1310
+ "pry",
1311
+ "ghci",
1312
+ "stack",
1313
+ "cabal",
1314
+ "ghc",
1315
+ // --- PHP / Lua / Perl / Ruby ecosystem (extended) ---
1316
+ "php8",
1317
+ "php7",
1318
+ "phpcs",
1319
+ "phpcbf",
1320
+ "phpmd",
1321
+ "phpstan",
1322
+ "psalm",
1323
+ "lua",
1324
+ "lua5.1",
1325
+ "lua5.2",
1326
+ "lua5.3",
1327
+ "lua5.4",
1328
+ "luarocks",
1329
+ "perl",
1330
+ "cpan",
1331
+ "prove",
1332
+ "plackup",
1333
+ "rake",
1334
+ "rspec",
1335
+ "jekyll",
1336
+ "node-gyp",
1337
+ "node-pre-gyp",
1338
+ // --- JS / TS toolchain (extended) ---
1339
+ "electron",
1340
+ "electron-builder",
1341
+ "electron-forge",
1342
+ "vite-preview",
1343
+ "swc",
1344
+ "swc-cli",
1345
+ "swcpack",
1346
+ "mocha",
1347
+ "chai",
1348
+ "jasmine",
1349
+ "puppeteer",
1350
+ "lighthouse",
1351
+ // --- Linters / formatters (extended) ---
1352
+ "tslint",
1353
+ "stylelint",
1354
+ "htmlhint",
1355
+ "jshint",
1356
+ "jslint",
1357
+ "jscs",
1358
+ // --- Document conversion ---
1359
+ "pandoc",
1360
+ "weasyprint",
1361
+ "wkhtmltopdf",
1362
+ "wkhtmltoimage",
1363
+ "prince",
1364
+ "mdp",
1365
+ "markdown",
1366
+ "multimarkdown",
1367
+ "cmark",
1368
+ "cmark-gfm",
1369
+ // --- Office / spreadsheet ---
1370
+ "soffice",
1371
+ "libreoffice",
1372
+ "unoconv",
1373
+ "abiword",
1374
+ "gnumeric",
1375
+ // --- Spell / grammar ---
1376
+ "aspell",
1377
+ "hunspell",
1378
+ "enchant",
1379
+ "languagetool",
1380
+ // --- Source-highlight / diff tools ---
1381
+ "delta",
1382
+ "bat",
1383
+ "ccat",
1384
+ "hl",
1385
+ "highlight",
1386
+ "source-highlight",
1387
+ "ansifilter",
1388
+ // --- Job schedulers ---
1389
+ "pueue",
1390
+ "task-spooler",
1391
+ "ts",
1392
+ "at",
1393
+ "atd",
1394
+ "anacron",
1395
+ "fcron",
1396
+ "cronie",
1397
+ "systemd-run",
1398
+ "systemd-cat",
1399
+ // --- Plotting / visualization ---
1400
+ "gnuplot",
1401
+ "gnuplot-nox",
1402
+ "veusz",
1403
+ "scidavis",
1404
+ "grace",
1405
+ "xmgrace",
1406
+ "labplot",
1407
+ // --- Security / recon (network + web) ---
1408
+ "masscan",
1409
+ "zmap",
1410
+ "rustscan",
1411
+ "amass",
1412
+ "subfinder",
1413
+ "httpx",
1414
+ "nuclei",
1415
+ "naabu",
1416
+ "katana",
1417
+ "dnsx",
1418
+ "assetfinder",
1419
+ "findomain",
1420
+ "gau",
1421
+ "waybackurls",
1422
+ "httprobe",
1423
+ "meg",
1424
+ "subjack",
1425
+ "sublert",
1426
+ "chaos"
916
1427
  ]);
917
1428
  var allowedCommands = new Set(DEFAULT_ALLOWED_COMMANDS);
918
1429
  var normalizeCmd = (c) => c.trim();
@@ -1135,17 +1646,18 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId) {
1135
1646
  const spool = createOutputSpool({ tool: `exec-${cmd}`, thresholdBytes: MAX_OUTPUT });
1136
1647
  const resolved = resolveWin32Command(cmd);
1137
1648
  const needsShell = isWin && (resolved.endsWith(".cmd") || resolved.endsWith(".bat"));
1138
- const spawnCmd = needsShell ? cmd : resolved;
1139
- if (needsShell) assertSafeWin32ShellArgs(args);
1649
+ const shim = needsShell ? buildWin32CmdShimInvocation(resolved, args) : null;
1650
+ const spawnCmd = shim?.command ?? resolved;
1651
+ const spawnArgs = shim?.args ?? args;
1140
1652
  let child;
1141
1653
  try {
1142
- child = spawn(spawnCmd, args, {
1654
+ child = spawn(spawnCmd, spawnArgs, {
1143
1655
  cwd,
1144
1656
  env: buildChildEnv(sessionId),
1145
1657
  stdio: ["ignore", "pipe", "pipe"],
1146
1658
  windowsHide: true,
1147
1659
  ...isWin ? {} : { signal },
1148
- ...needsShell ? { shell: true, windowsVerbatimArguments: true } : {}
1660
+ ...shim ? { windowsVerbatimArguments: shim.windowsVerbatimArguments } : {}
1149
1661
  });
1150
1662
  } catch (err) {
1151
1663
  spool.finalize();