@obfuscan/core 0.1.0 → 0.2.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # obfuscan
2
2
 
3
- Detect obfuscated code and likely backdoors in pull-request diffs. Multi-language. Embeddable. Diff-aware. Pure TypeScript.
3
+ Detect obfuscated code and likely backdoors in files or text. Multi-language. Embeddable. Diff-aware. Pure TypeScript.
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/@obfuscan/core)](https://www.npmjs.com/package/@obfuscan/core)
6
6
  [![license](https://img.shields.io/npm/l/@obfuscan/core)](./LICENSE)
@@ -1 +1 @@
1
- {"version":3,"file":"high-entropy-literal.d.ts","sourceRoot":"","sources":["../../src/detectors/high-entropy-literal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAwB,MAAM,aAAa,CAAC;AAiClE,eAAO,MAAM,kBAAkB,EAAE,QAiDhC,CAAC"}
1
+ {"version":3,"file":"high-entropy-literal.d.ts","sourceRoot":"","sources":["../../src/detectors/high-entropy-literal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAwB,MAAM,aAAa,CAAC;AAgDlE,eAAO,MAAM,kBAAkB,EAAE,QAkDhC,CAAC"}
@@ -21,6 +21,9 @@ const MIN_LEN = 40;
21
21
  const ENTROPY_THRESHOLD = 4.5; // bits/char
22
22
  const MAX_SOURCE_BYTES = 2_000_000; // skip files larger than 2 MB
23
23
  const MAX_FINDINGS_PER_FILE = 50; // protect the report from minified bundles
24
+ const BASE64ISH_RE = /^[A-Za-z0-9+/=_-]+$/;
25
+ const DATA_URI_BASE64_RE = /^data:[^,]{1,120};base64,[A-Za-z0-9+/=]+$/i;
26
+ const ESCAPED_BYTES_RE = /^(?:\\x[0-9A-Fa-f]{2}|\\u[0-9A-Fa-f]{4}|\\[0-7]{3})+$/;
24
27
  /** Shannon entropy in bits/char. */
25
28
  function shannon(s) {
26
29
  if (s.length === 0)
@@ -35,6 +38,17 @@ function shannon(s) {
35
38
  }
36
39
  return h;
37
40
  }
41
+ function looksEncodedOrPacked(s) {
42
+ if (DATA_URI_BASE64_RE.test(s))
43
+ return true;
44
+ if (ESCAPED_BYTES_RE.test(s))
45
+ return true;
46
+ // Ordinary prose, SQL, and structured log messages often cross the entropy
47
+ // threshold. Packed payloads are typically dense and whitespace-free.
48
+ if (/\s/.test(s))
49
+ return false;
50
+ return BASE64ISH_RE.test(s);
51
+ }
38
52
  /** Convert a 0-based character offset to a 1-based line number. */
39
53
  function lineAt(source, offset) {
40
54
  let line = 1;
@@ -63,6 +77,8 @@ export const highEntropyLiteral = {
63
77
  const body = match[2];
64
78
  if (!body || body.length < MIN_LEN)
65
79
  continue;
80
+ if (!looksEncodedOrPacked(body))
81
+ continue;
66
82
  const entropy = shannon(body);
67
83
  if (entropy < ENTROPY_THRESHOLD)
68
84
  continue;
@@ -1 +1 @@
1
- {"version":3,"file":"high-entropy-literal.js","sourceRoot":"","sources":["../../src/detectors/high-entropy-literal.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"high-entropy-literal.js","sourceRoot":"","sources":["../../src/detectors/high-entropy-literal.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,7 @@ import { suspiciousIoCluster } from "./suspicious-io-cluster.js";
20
20
  import { stringArrayDecoder } from "./string-array-decoder.js";
21
21
  import { shellUntrustedInput } from "./shell-untrusted-input.js";
22
22
  import { libraryLoadNonLiteral } from "./library-load-non-literal.js";
23
+ import { npmC2Dropper } from "./npm-c2-dropper.js";
23
24
  import { manifestInstallScript } from "./manifest-install-script.js";
24
25
  import { pythonSetupSideEffect } from "./python-setup-side-effect.js";
25
26
  import { perlMakefileSideEffect } from "./perl-makefile-side-effect.js";
@@ -27,5 +28,5 @@ import { cargoBuildRsNetwork } from "./cargo-build-rs-network.js";
27
28
  import { ghaCurlPipeShell } from "./gha-curl-pipe-shell.js";
28
29
  import { dockerfileCurlPipeShell } from "./dockerfile-curl-pipe-shell.js";
29
30
  export declare function defaultDetectors(): readonly Detector[];
30
- export { highEntropyLiteral, bidiControlChar, homoglyphIdentifier, longLine, encodedArrayFingerprint, decodeThenExec, dynamicExecNonLiteral, networkThenExec, deserializerUntrusted, suspiciousIoCluster, stringArrayDecoder, shellUntrustedInput, libraryLoadNonLiteral, manifestInstallScript, pythonSetupSideEffect, perlMakefileSideEffect, cargoBuildRsNetwork, ghaCurlPipeShell, dockerfileCurlPipeShell, };
31
+ export { highEntropyLiteral, bidiControlChar, homoglyphIdentifier, longLine, encodedArrayFingerprint, decodeThenExec, dynamicExecNonLiteral, networkThenExec, deserializerUntrusted, suspiciousIoCluster, npmC2Dropper, stringArrayDecoder, shellUntrustedInput, libraryLoadNonLiteral, manifestInstallScript, pythonSetupSideEffect, perlMakefileSideEffect, cargoBuildRsNetwork, ghaCurlPipeShell, dockerfileCurlPipeShell, };
31
32
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/detectors/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAGzE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAGtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,wBAAgB,gBAAgB,IAAI,SAAS,QAAQ,EAAE,CAEtD;AA8BD,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,QAAQ,EACR,uBAAuB,EACvB,cAAc,EACd,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,uBAAuB,GACxB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/detectors/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAGzE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,wBAAgB,gBAAgB,IAAI,SAAS,QAAQ,EAAE,CAEtD;AA+BD,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,QAAQ,EACR,uBAAuB,EACvB,cAAc,EACd,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EACnB,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,uBAAuB,GACxB,CAAC"}
@@ -21,6 +21,7 @@ import { suspiciousIoCluster } from "./suspicious-io-cluster.js";
21
21
  import { stringArrayDecoder } from "./string-array-decoder.js";
22
22
  import { shellUntrustedInput } from "./shell-untrusted-input.js";
23
23
  import { libraryLoadNonLiteral } from "./library-load-non-literal.js";
24
+ import { npmC2Dropper } from "./npm-c2-dropper.js";
24
25
  // Manifest — ecosystem-specific detectors
25
26
  import { manifestInstallScript } from "./manifest-install-script.js";
26
27
  import { pythonSetupSideEffect } from "./python-setup-side-effect.js";
@@ -44,6 +45,7 @@ const DEFAULTS = Object.freeze([
44
45
  dynamicExecNonLiteral,
45
46
  deserializerUntrusted,
46
47
  suspiciousIoCluster,
48
+ npmC2Dropper,
47
49
  stringArrayDecoder,
48
50
  shellUntrustedInput,
49
51
  libraryLoadNonLiteral,
@@ -56,5 +58,5 @@ const DEFAULTS = Object.freeze([
56
58
  dockerfileCurlPipeShell,
57
59
  ]);
58
60
  // Named re-exports for tests and advanced consumers.
59
- export { highEntropyLiteral, bidiControlChar, homoglyphIdentifier, longLine, encodedArrayFingerprint, decodeThenExec, dynamicExecNonLiteral, networkThenExec, deserializerUntrusted, suspiciousIoCluster, stringArrayDecoder, shellUntrustedInput, libraryLoadNonLiteral, manifestInstallScript, pythonSetupSideEffect, perlMakefileSideEffect, cargoBuildRsNetwork, ghaCurlPipeShell, dockerfileCurlPipeShell, };
61
+ export { highEntropyLiteral, bidiControlChar, homoglyphIdentifier, longLine, encodedArrayFingerprint, decodeThenExec, dynamicExecNonLiteral, networkThenExec, deserializerUntrusted, suspiciousIoCluster, npmC2Dropper, stringArrayDecoder, shellUntrustedInput, libraryLoadNonLiteral, manifestInstallScript, pythonSetupSideEffect, perlMakefileSideEffect, cargoBuildRsNetwork, ghaCurlPipeShell, dockerfileCurlPipeShell, };
60
62
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/detectors/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,6CAA6C;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAEzE,6CAA6C;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,0CAA0C;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,MAAM,UAAU,gBAAgB;IAC9B,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,QAAQ,GAAwB,MAAM,CAAC,MAAM,CAAC;IAClD,UAAU;IACV,kBAAkB;IAClB,eAAe;IACf,mBAAmB;IACnB,QAAQ;IACR,uBAAuB;IAEvB,UAAU;IACV,cAAc;IACd,eAAe;IACf,qBAAqB;IACrB,qBAAqB;IACrB,mBAAmB;IACnB,kBAAkB;IAClB,mBAAmB;IACnB,qBAAqB;IAErB,WAAW;IACX,qBAAqB;IACrB,qBAAqB;IACrB,sBAAsB;IACtB,mBAAmB;IACnB,gBAAgB;IAChB,uBAAuB;CACxB,CAAC,CAAC;AAEH,qDAAqD;AACrD,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,QAAQ,EACR,uBAAuB,EACvB,cAAc,EACd,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,uBAAuB,GACxB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/detectors/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,6CAA6C;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAEzE,6CAA6C;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,0CAA0C;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,MAAM,UAAU,gBAAgB;IAC9B,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,QAAQ,GAAwB,MAAM,CAAC,MAAM,CAAC;IAClD,UAAU;IACV,kBAAkB;IAClB,eAAe;IACf,mBAAmB;IACnB,QAAQ;IACR,uBAAuB;IAEvB,UAAU;IACV,cAAc;IACd,eAAe;IACf,qBAAqB;IACrB,qBAAqB;IACrB,mBAAmB;IACnB,YAAY;IACZ,kBAAkB;IAClB,mBAAmB;IACnB,qBAAqB;IAErB,WAAW;IACX,qBAAqB;IACrB,qBAAqB;IACrB,sBAAsB;IACtB,mBAAmB;IACnB,gBAAgB;IAChB,uBAAuB;CACxB,CAAC,CAAC;AAEH,qDAAqD;AACrD,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,QAAQ,EACR,uBAAuB,EACvB,cAAc,EACd,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EACnB,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,uBAAuB,GACxB,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * obf.npm-c2-dropper — Layer B/package malware heuristic.
3
+ *
4
+ * Flags the combined shape used by npm C2 droppers: package code polls a C2
5
+ * API, decrypts staged content, writes it to disk, marks it executable, and
6
+ * launches it with Node or a child process. Each individual API is common;
7
+ * the cluster is the signal.
8
+ */
9
+ import type { Detector } from "../types.js";
10
+ export declare const npmC2Dropper: Detector;
11
+ //# sourceMappingURL=npm-c2-dropper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npm-c2-dropper.d.ts","sourceRoot":"","sources":["../../src/detectors/npm-c2-dropper.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAwB,MAAM,aAAa,CAAC;AAelE,eAAO,MAAM,YAAY,EAAE,QAuD1B,CAAC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * obf.npm-c2-dropper — Layer B/package malware heuristic.
3
+ *
4
+ * Flags the combined shape used by npm C2 droppers: package code polls a C2
5
+ * API, decrypts staged content, writes it to disk, marks it executable, and
6
+ * launches it with Node or a child process. Each individual API is common;
7
+ * the cluster is the signal.
8
+ */
9
+ import { lineAtOffset, MAX_SOURCE_BYTES } from "../internal/patterns.js";
10
+ import { truncateSnippet } from "../internal/text.js";
11
+ const JS_LIKE = new Set(["javascript", "typescript"]);
12
+ const C2_RE = /(?:slack\.com|conversations\.history|auth\.test|\bAuthorization\s*:\s*["']Bearer\s+|\bxox[abprs]-)/;
13
+ const CRYPTO_RE = /(?:AES-GCM|PBKDF2|subtle|\.decrypt\s*\(|deriveKey\s*\(|importKey\s*\()/;
14
+ const WRITE_RE = /\bwriteFileSync\s*\(/;
15
+ const CHMOD_RE = /\bchmodSync\s*\(/;
16
+ const CHILD_PROCESS_RE = /(?:\bspawn\s*[:=,}]|\bexecSync\s*[:=,}]|\bchild_process\b|\bprocess\.execPath\b|\b\.unref\s*\()/;
17
+ const SELF_DELETE_RE = /\bunlinkSync\s*\(\s*__filename\b/;
18
+ export const npmC2Dropper = {
19
+ id: "obf.npm-c2-dropper",
20
+ docsUrl: "https://github.com/bytebardorg/obfuscan/blob/main/docs/detectors.md#obfnpm-c2-dropper",
21
+ applies(ctx) {
22
+ return (ctx.source.length > 0 &&
23
+ ctx.source.length < MAX_SOURCE_BYTES &&
24
+ (ctx.languageId === null || JS_LIKE.has(ctx.languageId)));
25
+ },
26
+ run(ctx) {
27
+ const src = ctx.source;
28
+ const c2 = C2_RE.exec(src);
29
+ if (!c2)
30
+ return [];
31
+ const crypto = CRYPTO_RE.exec(src);
32
+ if (!crypto)
33
+ return [];
34
+ const write = WRITE_RE.exec(src);
35
+ const chmod = CHMOD_RE.exec(src);
36
+ const child = CHILD_PROCESS_RE.exec(src);
37
+ const selfDelete = SELF_DELETE_RE.exec(src);
38
+ if (!write || !chmod || !child)
39
+ return [];
40
+ const offset = Math.min(c2.index, crypto.index, write.index, chmod.index, child.index, selfDelete?.index ?? Number.POSITIVE_INFINITY);
41
+ return [{
42
+ ruleId: npmC2Dropper.id,
43
+ severity: "block",
44
+ score: 10,
45
+ file: ctx.path,
46
+ line: lineAtOffset(src, offset),
47
+ snippet: truncateSnippet(src.slice(offset, offset + 200)),
48
+ reason: `JavaScript package contains C2 polling, decrypt-stage, write/chmod, ` +
49
+ `and child-process launch signals. This matches npm command-and-control dropper behavior.`,
50
+ evidence: {
51
+ c2: c2[0],
52
+ crypto: crypto[0],
53
+ writesFile: true,
54
+ chmodsFile: true,
55
+ launchesChildProcess: true,
56
+ selfDelete: !!selfDelete,
57
+ },
58
+ }];
59
+ },
60
+ };
61
+ //# sourceMappingURL=npm-c2-dropper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npm-c2-dropper.js","sourceRoot":"","sources":["../../src/detectors/npm-c2-dropper.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;AAEtD,MAAM,KAAK,GACT,oGAAoG,CAAC;AACvG,MAAM,SAAS,GAAG,wEAAwE,CAAC;AAC3F,MAAM,QAAQ,GAAG,sBAAsB,CAAC;AACxC,MAAM,QAAQ,GAAG,kBAAkB,CAAC;AACpC,MAAM,gBAAgB,GACpB,iGAAiG,CAAC;AACpG,MAAM,cAAc,GAAG,kCAAkC,CAAC;AAE1D,MAAM,CAAC,MAAM,YAAY,GAAa;IACpC,EAAE,EAAE,oBAAoB;IACxB,OAAO,EAAE,uFAAuF;IAEhG,OAAO,CAAC,GAAgB;QACtB,OAAO,CACL,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;YACrB,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,gBAAgB;YACpC,CAAC,GAAG,CAAC,UAAU,KAAK,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CACzD,CAAC;IACJ,CAAC;IAED,GAAG,CAAC,GAAgB;QAClB,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC;QACvB,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,EAAE;YAAE,OAAO,EAAE,CAAC;QAEnB,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QAEvB,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzC,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5C,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,CAAC;QAE1C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CACrB,EAAE,CAAC,KAAK,EACR,MAAM,CAAC,KAAK,EACZ,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,KAAK,EACX,UAAU,EAAE,KAAK,IAAI,MAAM,CAAC,iBAAiB,CAC9C,CAAC;QAEF,OAAO,CAAC;gBACN,MAAM,EAAE,YAAY,CAAC,EAAE;gBACvB,QAAQ,EAAE,OAAO;gBACjB,KAAK,EAAE,EAAE;gBACT,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,IAAI,EAAE,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC;gBAC/B,OAAO,EAAE,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,CAAC;gBACzD,MAAM,EACJ,sEAAsE;oBACtE,0FAA0F;gBAC5F,QAAQ,EAAE;oBACR,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;oBACT,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;oBACjB,UAAU,EAAE,IAAI;oBAChB,UAAU,EAAE,IAAI;oBAChB,oBAAoB,EAAE,IAAI;oBAC1B,UAAU,EAAE,CAAC,CAAC,UAAU;iBACzB;aACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -24,7 +24,7 @@ function compile(config) {
24
24
  cache.set(config, null);
25
25
  return null;
26
26
  }
27
- const alt = namedCallAlternation(list);
27
+ const alt = namedCallAlternation(list, { allowUnsafeBareTails: true });
28
28
  // Capture sink + the first 80 chars of arguments
29
29
  const re = new RegExp(`(?:^|[^A-Za-z0-9_$])((?:${alt}))\\s*\\(([^)\\n]{0,200})`, "g");
30
30
  cache.set(config, re);
@@ -1 +1 @@
1
- {"version":3,"file":"shell-untrusted-input.js","sourceRoot":"","sources":["../../src/detectors/shell-untrusted-input.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,YAAY,EACZ,yBAAyB,EACzB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,4DAA4D;AAC5D,+CAA+C;AAC/C,mCAAmC;AACnC,kDAAkD;AAClD,8BAA8B;AAC9B,2DAA2D;AAC3D,8CAA8C;AAC9C,MAAM,cAAc,GAClB,mGAAmG,CAAC;AAEtG,MAAM,KAAK,GAAG,IAAI,OAAO,EAAiC,CAAC;AAE3D,SAAS,OAAO,CAAC,MAAsB;IACrC,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;IACxD,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;IACrC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,GAAG,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACvC,iDAAiD;IACjD,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,2BAA2B,GAAG,2BAA2B,EAAE,GAAG,CAAC,CAAC;IACtF,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACtB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAa;IAC3C,EAAE,EAAE,gCAAgC;IACpC,OAAO,EAAE,mGAAmG;IAE5G,OAAO,CAAC,GAAgB;QACtB,OAAO,CACL,GAAG,CAAC,MAAM,KAAK,IAAI;YACnB,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC;YACxC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;YACrB,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,gBAAgB,CACrC,CAAC;IACJ,CAAC;IAED,GAAG,CAAC,GAAgB;QAClB,IAAI,CAAC,GAAG,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC;QACvB,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,EAAE;YAAE,OAAO,EAAE,CAAC;QAEnB,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,CAAyB,CAAC;QAC9B,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC7C,IAAI,QAAQ,CAAC,MAAM,IAAI,yBAAyB;gBAAE,MAAM;YACxD,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,SAAS;YAEzC,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;YACrD,QAAQ,CAAC,IAAI,CAAC;gBACZ,MAAM,EAAE,kCAAkC,GAAG,CAAC,EAAE,EAAE;gBAClD,QAAQ,EAAE,MAAM;gBAChB,KAAK,EAAE,CAAC;gBACR,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,IAAI,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;gBACtC,OAAO,EAAE,eAAe,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;gBAC3C,MAAM,EACJ,qBAAqB,IAAI,8CAA8C;oBACvE,mEAAmE;oBACnE,iBAAiB;gBACnB,QAAQ,EAAE,EAAE,QAAQ,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;aAC3C,CAAC,CAAC;QACL,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"shell-untrusted-input.js","sourceRoot":"","sources":["../../src/detectors/shell-untrusted-input.ts"],"names":[],"mappings":"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"}
@@ -31,7 +31,9 @@ export declare function escapeRegex(s: string): string;
31
31
  *
32
32
  * Returns an inner alternation suitable for inclusion in a larger pattern.
33
33
  */
34
- export declare function namedCallAlternation(names: readonly string[]): string;
34
+ export declare function namedCallAlternation(names: readonly string[], options?: {
35
+ allowUnsafeBareTails?: boolean;
36
+ }): string;
35
37
  /**
36
38
  * 1-based line number for a 0-based character offset.
37
39
  * Used by every detector to report source positions.
@@ -1 +1 @@
1
- {"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../src/internal/patterns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAkCrE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAOnE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE/E;AAED,mEAAmE;AACnE,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAE5C,uDAAuD;AACvD,eAAO,MAAM,gBAAgB,UAAY,CAAC"}
1
+ {"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../src/internal/patterns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7C;AA8CD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,GAAE;IAAE,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/C,MAAM,CAwCR;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAOnE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE/E;AAED,mEAAmE;AACnE,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAE5C,uDAAuD;AACvD,eAAO,MAAM,gBAAgB,UAAY,CAAC"}
@@ -23,6 +23,49 @@
23
23
  export function escapeRegex(s) {
24
24
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
25
25
  }
26
+ const UNSAFE_BARE_TAILS = new Set([
27
+ "call",
28
+ "compile",
29
+ "constructor",
30
+ "decode",
31
+ "do",
32
+ "exec",
33
+ "execute",
34
+ "from",
35
+ "get",
36
+ "import",
37
+ "invoke",
38
+ "load",
39
+ "new",
40
+ "open",
41
+ "parse",
42
+ "post",
43
+ "request",
44
+ "require",
45
+ "run",
46
+ "send",
47
+ "source",
48
+ "spawn",
49
+ "start",
50
+ "system",
51
+ "use",
52
+ ]);
53
+ function isUnsafeBareTail(tail) {
54
+ return UNSAFE_BARE_TAILS.has(tail.toLowerCase());
55
+ }
56
+ function qualifiedSuffix(raw) {
57
+ const parts = raw.split(/(\.|::)/);
58
+ const segments = parts.filter((_, i) => i % 2 === 0 && parts[i] !== "");
59
+ const separators = parts.filter((_, i) => i % 2 === 1);
60
+ if (segments.length < 2 || separators.length < 1)
61
+ return null;
62
+ const a = segments[segments.length - 2];
63
+ const b = segments[segments.length - 1];
64
+ const sep = separators[separators.length - 1];
65
+ if (!a || !b || !sep)
66
+ return null;
67
+ return `${a}${sep}${b}`;
68
+ }
26
69
  /**
27
70
  * Build a regex source matching any of the configured names as a function
28
71
  * call. Accepts qualified names — for `base64.b64decode` the regex matches
@@ -33,7 +76,7 @@ export function escapeRegex(s) {
33
76
  *
34
77
  * Returns an inner alternation suitable for inclusion in a larger pattern.
35
78
  */
36
- export function namedCallAlternation(names) {
79
+ export function namedCallAlternation(names, options = {}) {
37
80
  const alts = [];
38
81
  for (const raw of names) {
39
82
  if (!raw)
@@ -55,7 +98,15 @@ export function namedCallAlternation(names) {
55
98
  const tail = parts[parts.length - 1] ?? raw;
56
99
  alts.push(escapeRegex(raw));
57
100
  if (parts.length > 1 && tail !== raw && tail.length > 0) {
58
- alts.push(escapeRegex(tail));
101
+ if (isUnsafeBareTail(tail) && !options.allowUnsafeBareTails) {
102
+ const suffix = qualifiedSuffix(raw);
103
+ if (suffix && suffix !== raw)
104
+ alts.push(escapeRegex(suffix));
105
+ alts.push(`(?:\\.|::)${escapeRegex(tail)}`);
106
+ }
107
+ else {
108
+ alts.push(escapeRegex(tail));
109
+ }
59
110
  }
60
111
  }
61
112
  // Deduplicate while preserving order
@@ -1 +1 @@
1
- {"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../src/internal/patterns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAwB;IAC3D,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,kDAAkD;QAClD,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5B,SAAS;QACX,CAAC;QACD,oEAAoE;QACpE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5B,SAAS;QACX,CAAC;QACD,uEAAuE;QACvE,uEAAuE;QACvE,sEAAsE;QACtE,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACjC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC;QAC5C,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxD,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IACD,qCAAqC;IACrC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACjB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACZ,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,MAAc;IACzD,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ;YAAE,IAAI,EAAE,CAAC;IACnD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,MAAc,EAAE,KAAa,EAAE,MAAc;IACrE,OAAO,YAAY,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC,CAAC;AAC9C,CAAC;AAED,mEAAmE;AACnE,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAE5C,uDAAuD;AACvD,MAAM,CAAC,MAAM,gBAAgB,GAAG,SAAS,CAAC"}
1
+ {"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../src/internal/patterns.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@obfuscan/core",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Detect obfuscated code and likely backdoors in pull-request diffs. Multi-language. Diff-aware. Pure TypeScript.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/ByteBardOrg/obfuscan",