# MercadoLibre — HTTP Recon & Bug Bounty Report

**Target:** `mercadolibre.com` / `mercadolivre.com` / `mercadolibre.com.ar` (+ country TLDs)
**Method:** subdomain recon → CT logs → DNS → `httpx` probing → manual curl verification
**Tools:** ctlogs.dev, certspotter, crt.sh, httpx, curl, jq

---

## 1. Executive Summary

| Metric | Count |
|---|---|
| Total targets probed | 80 |
| Live HTTP/HTTPS hosts | 53 |
| Dead / unreachable / internal-only | 27 |
| **High-value findings** | **1 critical, 3 notable** |

---

## 2. 🎯 Key Findings (Bug Bounty Priorities)

### 🔴 CRITICAL — `artifacts.mercadolibre.com`
**Sonatype Nexus Repository Manager — PUBLICLY EXPOSED**

| Probe | Result |
|---|---|
| `/` (UI) | HTTP 200 (Sonatype Nexus Repository title) |
| `/service/rest/v1/repositories` | HTTP **200** — lists all internal repos, **NO AUTH** |
| `/service/rest/v1/search/assets?repository=ios-releases` | HTTP **200** — returns full asset metadata |
| `/repository/ios-releases/AndesUI/3.27.14/AndesUI.zip` | HTTP **200** — actual file downloadable (809 KB) |
| `/service/rest/v1/status/writable` | HTTP 200 (Nexus writable check) |
| `/service/rest/v1/security/users` | HTTP 403 (auth required) |

**Exposed repositories:**
```
ios-releases            raw      hosted   349,443,371 bytes
android-releases        maven2   hosted   1,339,419,938 bytes
android-experimental    maven2   hosted    15,080,460 bytes
extra                   maven2   proxy      4,504,305 bytes
ios-experimental        raw      hosted            0
bintray-android-public  maven2   proxy            0
oss-ios-releases        raw      proxy            0
oss-android-releases    maven2   proxy        6,678
```

**Headers returned on artifact download:**
```
server: nginx/1.29.4
access-control-allow-origin: *
content-security-policy: sandbox allow-forms ...
```

**Why this matters:** internal build artifacts (Android `.apk`/`.jar`, iOS `.zip` framework bundles) are enumerable and downloadable by anyone on the internet. `access-control-allow-origin: *` makes it trivially scriptable. Look for:
- Hardcoded API keys / tokens baked into those artifacts
- Reverse-engineer release binaries for signed-in internal endpoints
- Supply-chain attack surface (can anyone upload? `status/writable=200` suggests possibility)

**Report template:** "Unauthenticated Access to Internal Artifact Repository (Sonatype Nexus) on artifacts.mercadolibre.com allows disclosure of proprietary Android/iOS build binaries."

---

### 🟠 NOTABLE — `fooddeliverywebapp.mercadolibre.com`
**AWS S3 bucket behind CloudFront**

| Probe | Result |
|---|---|
| HTTPS root | HTTP 403, `x-amz-bucket-region: us-east-1`, `x-amz-id-2`, `x-amz-request-id` leaked |
| `/?list-type=2&max-keys=10` | `AccessDenied` (good, no public listing) |
| `Host: fooddeliverywebapp.mercadolibre.com` on HTTP | HTTP 301 → `https://fooddeliverywebapp.mercadolibre.com:443/` |
| httpx (first probe) | HTTP 307 → `http://fooddeliverywebapp.mercadolibre.com:9001` |

The redirect to **port 9001** is anomalous — it suggests an upstream origin server on a non-standard port. Try:
- `https://fooddeliverywebapp.mercadolibre.com:9001/` (probably blocked by LB)
- Probe common paths: `/health`, `/api`, `/status`, `/actuator/health`
- Check S3 bucket naming convention (`fooddeliverywebapp-*`, search public buckets for similar name)

---

### 🟠 NOTABLE — SAML/Auth0 `next` parameter on learning portals
**`learning.mercadolibre.com`** and **`learninghub.mercadolibre.com.ar`** both redirect to `/login?next=<path>&tpa_hint=<auth-strategy>`.

```
https://learning.mercadolibre.com/login?next=%2F%3Ftpa_hint%3Dsaml-auth0-saml
https://learninghub.mercadolibre.com.ar/login?next=%2F%3Ftpa_hint%3Doa2-marketplace-id
```

- Direct injection of `next=https://evil.example.com` returned **HTTP 403** (good — SSRF/open-redirect blocked).
- However, the `tpa_hint` parameter names an Auth0 connection strategy. **Try enumerating other tpa_hint values** (`google-oauth2`, `auth0`, `saml`, `passwordless`, etc.) — misconfiguration may allow identity-provider bypass.

---

### 🟡 INTERESTING — `events-ads.mercadolibre.com`
**HTTP 421 Misdirected Request**
```
x-served-by: cache-fra-etou8220121
```
The header `x-served-by` resembles **Fastly** infrastructure. HTTP 421 means the request was sent to the wrong origin/edge node. This could be:
- A routing bug (send a specific Host header to make it work)
- A stale CDN configuration (old production endpoints still cached)
- Try adding different `Host:` headers or probing alternate paths (`/health`, `/status`, `/metrics`).

---

## 3. Full HTTPX Result Table (All 53 Live Hosts)

Legend: 🔴 high-value · 🟠 medium · 🟡 low · ⚪ informational

| Host | Code | Title | Server/Tech | IP | Notes |
|---|---|---|---|---|---|
| api.mercadolibre.com | 404 | — | CloudFront | 52.222.214.49 | Main public API — expects valid paths |
| **artifacts.mercadolibre.com** 🔴 | 200 | Sonatype Nexus Repository | nginx/1.29.4 | 100.60.82.53 | **Unauthenticated repo listing + download** |
| andes-landings.mercadolibre.com | 200 | Andes Landings | Ruby on Rails | 54.195.237.234 | Landing page framework |
| andes.mercadolibre.com | 200 | Andes Design System | Ruby on Rails | 52.51.23.169 | Design-system docs |
| andesx.mercadolibre.com | 200 | Andes X | Ruby on Rails | 52.51.23.169 | Design-system variant |
| career.mercadolibre.com | 307 → `/es` | — | Tengine/3.1.0 + CloudFront | 52.222.136.23 | Language-based redirect |
| careers-meli.mercadolibre.com | 307 → `/es` | — | Tengine/3.1.0 + CloudFront | 2600:9000:... | Same as career |
| centrodepartners.mercadolibre.com | 200 | Centro de Partners | nginx + Envoy | 99.84.152.3 | Partner portal |
| developers.mercadolibre.com | 200 | — | nginx + Envoy | 99.84.152.115 | Developer docs portal |
| **events-ads.mercadolibre.com** 🟡 | 421 | — | Fastly-like (x-served-by) | 151.101.194.133 | Misdirected request |
| **fooddeliverywebapp.mercadolibre.com** 🟠 | 403/307 | — | AWS S3 us-east-1 | 34.234.14.175 | S3 bucket + :9001 redirect |
| global-selling.mercadolibre.com | 302 → `/summary` | — | nginx + Envoy | 99.84.152.3 | /summary requires auth (403) |
| hp.mercadolibre.com | 200 | — | nginx + Envoy | 99.84.152.115 | Empty body (4 bytes) |
| investor.mercadolibre.com | 200 | Mercado Libre \| Investor Relations | nginx | 99.84.152.3 | Public IR site |
| jobs-test.mercadolibre.com | 307 → `/es` | — | Tengine/3.1.0 + CloudFront | 2600:9000:... | **"test" naming** — possibly staging jobs portal |
| learning.mercadolibre.com | 302 | — | nginx + CloudFront | 99.84.152.18 | Auth0 SAML hint |
| learninghub-int.mercadolibre.com | 403 | — | awselb/2.0 | 35.169.138.84 | Internal learning hub |
| learninghub.mercadolibre.com.ar | 302 | — | — | 35.169.138.84 | Marketplace OAuth hint |
| manualdeestilo.mercadolibre.com | 200 | Manual de estilo | Ruby on Rails | 52.51.23.169 | Style guide |
| mercadolibre.com | 200 | Mercado Libre - Envíos Gratis en el día | nginx | 3.33.182.45 | Main site |
| mercadolibre.com.{bo,co,do,ec,gt,hn,mx,ni,pe,py,pa,sv,uy,ve} | 301 | → www.<tld>/ | nginx + CloudFront | various | Standard country redirects |
| mercadolivre.com | 301 | → mercadolivre.com.br | nginx + CloudFront | 13.32.99.60 | Country redirect |
| news.mercadolivre.com | 301 | → news.mercadolibre.com | nginx + CloudFront | 13.32.99.44 | Language redirect |
| news.mercadolibre.com | 200 | Home \| Mercado Libre | **Drupal 10 + PHP** + CloudFront | 2600:9000:... | **CMS — check for /user/login, update.php** |
| op-scim.mercadolibre.com | 307 → `/app/` | — | — | 98.85.238.48 | SCIM provisioner (Okta?) |
| play.mercadolibre.com | 302 → `/no-disponible` | — | nginx + Envoy | 3.173.161.86 | "Not available" page |
| pppi-stg.mercadolibre.com | 200 | Brand Protection Program | **AmazonS3** | 2600:9000:... | **Staging environment** |
| pppi.mercadolibre.com | 200 | Brand Protection Program | Tengine/3.1.0 | 2600:9000:... | Production version |
| realtime-dev.global-selling.mercadolibre.com | 403 | — | awselb/2.0 | 52.0.61.254 | Dev realtime (ELB) |
| realtime-prod.global-selling.mercadolibre.com | 403 | — | awselb/2.0 | 184.197.193.205 | Prod realtime (ELB) |
| realtime-prod.sellers.mercadolibre.com | 403 | — | awselb/2.0 | 32.194.211.180 | Prod realtime (ELB) |
| sellers.mercadolibre.com | 302 → global-selling/sales-summary | — | nginx + Envoy | 143.204.55.23 | Alias |
| survey.mercadolibre.com | 302 → `/login` | — | — | 2.20.143.90 | Survey portal (Akamai IP?) |
| universidad.mercadolibre.com | 403 | — | CloudFront + React | 52.222.136.128 | Blocked by WAF |
| ux.mercadolibre.com | 200 | Mercado Libre UX | Tengine | 2600:9000:... | UX/brand portal |
| vendedores.mercadolibre.com | 200 | Central de vendedores | nginx + Envoy | 99.84.152.45 | Seller dashboard |
| vendorhub.mercadolibre.com | 302 → `/login` | — | nginx + Envoy | 99.84.152.3 | Vendor login |
| www.mercadolibre.com | 200 | Mercado Libre - Envíos Gratis | awselb/2.0 | 15.197.170.90 | Main prod |
| www.mercadolibre.com.ar | 200 | Mercado Libre Argentina | nginx + Envoy | 15.197.170.90 | Main prod AR |

---

## 4. No-Response Hosts (27)

These are likely internal-only or DNS-only without a public HTTP service:

```
alejandria-int.mercadolibre.com        ← internal
alejandria.mercadolibre.com.ar
bc-jpm-beta-ssl.mercadolibre.com       ← blockchain/jpm?
bc-jpm-beta-transfer.mercadolibre.com
bc-jpm-beta-update.mercadolibre.com
bc-jpm-beta-update.mercadolibre.com.mercadolibre.com  ← malformed (CT log bug)
careers.mercadolibre.com
hom-proxy-urutec.mercadolibre.com      ← Uruguay proxy
homl-proxy-urutec.mercadolibre.com
internal-api.mercadolibre.com          ← 10.54.29.x (PRIVATE IP!)
learninghub-studio-int.mercadolibre.com ← internal
nginx.m-int-dev.mercadolibre.com       ← internal nginx cluster
nginx.m-int-prd.mercadolibre.com
nginx.s1-int-dev.mercadolibre.com
nginx.s1-int-prd.mercadolibre.com
nginx.s1-pub-prd.mercadolibre.com      ← "pub" but no response
nginx.s2-int-prd.mercadolibre.com
nginx.s2-pub-prd.mercadolibre.com
prod-proxy-urutec.mercadolibre.com
prodeng-internal.mercadolibre.com      ← prod engineering
prodeng-playground-internal.mercadolibre.com
realtime-dev.mercadolibre.com.ar
realtime-prod.mercadolibre.com.ar
sdl-agent.mercadolibre.com
soap.mercadolibre.com                  ← SOAP endpoint (maybe non-HTTP)
treasury.mercadolibre.com
voice-agents.tcp.s1-int-prd.mercadolibre.com ← TCP-only
```

**Note:** `internal-api.mercadolibre.com` and `artifacts.mercadolibre.com` are the only hosts that resolved to private IPs (10.54.29.188 and 100.60.82.53). Everything else has public IPs.

---

## 5. Technology Stack Summary

| Tech | Count | Usage |
|---|---|---|
| nginx | ~35 | Most common server |
| Amazon CloudFront | ~25 | CDN for CloudFront routes |
| Amazon Web Services | ~25 | Underlying infra |
| Tengine | 5 | Alternative nginx fork |
| awselb/2.0 | 5 | AWS ALB |
| Ruby on Rails | 4 | Design systems (andes*, manualdeestilo) |
| **Drupal 10 + PHP** | 1 | news.mercadolibre.com |
| Envoy | ~10 | Service mesh proxies |
| Google Cloud | 2 | careers endpoints |

---

## 6. Bug Bounty Hunting Recommendations

### Highest Impact — `artifacts.mercadolibre.com`
1. **Enumerate all artifacts** via `/service/rest/v1/search/assets?repository=ios-releases&sort=version` and `android-releases`
2. **Search for secrets in binaries** — run `strings` / `grep -a` against downloaded artifacts for API keys, client IDs, private endpoints
3. **Look for proxy repositories** (`oss-*`, `bintray-*`) — potential **SSRF** if Nexus allows custom upstream
4. **Check for upload permissions** — POST to `/service/rest/v1/repositories/<name>/...` to see if writable (Nexus default "anonymous upload" is sometimes left on)
5. **Version disclosure** — server header says nginx/1.29.4 (very recent). Nexus itself may have CVEs if version is old

### Medium Impact — Auth flows
1. `learning.mercadolibre.com` — try different `tpa_hint` values to see if unauthorized SAML connections are accepted
2. `learninghub.mercadolibre.com.ar` — same strategy
3. `vendorhub.mercadolibre.com` `/login` — check for default accounts, password reset enumeration
4. `pppi-stg.mercadolibre.com` vs `pppi.mercadolibre.com` — content differs (different md5). Staging may have looser auth or test data

### Low Impact but worth trying
1. `jobs-test.mercadolibre.com` — "test" in the name. Maybe has debug endpoints
2. `events-ads.mercadolibre.com` 421 — send different Host headers or `/health`/`/metrics`
3. `news.mercadolibre.com` — Drupal 10: check `/user/login`, `/update.php`, `/admin`, REST endpoints, CORS
4. `op-scim.mercadolibre.com` → `/app/` — likely Okta SCIM; look for provisioner config leak
5. `bc-jpm-*` — sounds like a "JPMorgan" payment gateway beta; DNS resolves but no HTTP. Maybe non-HTTP protocol or IP-restricted
6. `soap.mercadolibre.com` — legacy SOAP endpoint; try common WSDL paths (`/?wsdl`, `/services/`, `/axis2/`)
7. `survey.mercadolibre.com` — 2.20.143.90 is likely Akamai. Survey portals often have XSS in question metadata

### Wildcard expansion targets
From cert data, these wildcards were found — probe the sub-hosts they cover:
```
*.realtime-dev.global-selling.mercadolibre.com
*.realtime-prod.global-selling.mercadolibre.com
*.realtime-prod.sellers.mercadolibre.com
*.sellers.mercadolibre.com
*.nginx.m-int-dev.mercadolibre.com
*.nginx.m-int-prd.mercadolibre.com
*.nginx.s1-int-dev.mercadolibre.com
*.nginx.s1-int-prd.mercadolibre.com
*.nginx.s1-pub-prd.mercadolibre.com
*.nginx.s2-int-prd.mercadolibre.com
*.nginx.s2-pub-prd.mercadolibre.com
*.prodeng-internal.mercadolibre.com
*.prodeng-playground-internal.mercadolibre.com
*.hom-proxy-urutec.mercadolibre.com
*.homl-proxy-urutec.mercadolibre.com
*.prod-proxy-urutec.mercadolibre.com
```

### Cross-country domains
```
mercadolibre.com.bo  / .com.co / .com.do / .com.ec / .com.gt
mercadolibre.com.hn  / .com.mx / .com.ni / .com.pa / .com.pe
mercadolibre.com.py  / .com.sv / .com.uy / .com.ve
mercadolivre.com (Brazil)
```
Each has the same API/developers subdomain pattern — often weakly tested for country-specific bugs.

---

## 7. Report Template (Ready to Submit)

**Title:** Unauthenticated Access to Sonatype Nexus Repository (artifacts.mercadolibre.com)

**Severity:** Critical / High

**Description:**
The host `artifacts.mercadolibre.com` hosts a Sonatype Nexus Repository Manager. An unauthenticated user can:
1. Enumerate all configured repositories via `GET /service/rest/v1/repositories`
2. Query asset metadata via `GET /service/rest/v1/search/assets?repository=<name>`
3. Download proprietary build artifacts (e.g., iOS framework `.zip`, Android maven2 packages)

**PoC:**
```bash
curl 'https://artifacts.mercadolibre.com/service/rest/v1/repositories' | jq '.[] | .name'
curl 'https://artifacts.mercadolibre.com/service/rest/v1/search/assets?repository=ios-releases'
curl -I 'https://artifacts.mercadolibre.com/repository/ios-releases/AndesUI/3.27.14/AndesUI.zip'
```

**Impact:**
- Proprietary source-level build artifacts publicly available
- Potential secret leakage in build binaries
- CORS `*` on all assets allows scripted exfiltration
- `access-control-allow-origin: *` combined with `sandbox` CSP makes this an attractive vector

**Remediation:**
- Require authentication for all Nexus REST endpoints
- Restrict repository-level anonymous read to specific IPs
- Ensure `status/writable` is not exposed

---

## 8. Files Produced

```
/Users/gashtasb/Desktop/mercadolibre_recon/
├── BUGBOUNTY_REPORT.md        ← this file
├── REPORT.md                  ← CT/DNS recon report
├── cert_finder.py             ← reusable recon script
├── input_domains.txt
├── certs/
│   ├── ctlogs_dev.json
│   ├── certspotter.json
│   └── crt_sh.json
├── subdomains/
│   ├── httpx_results.txt      ← raw httpx output (53 live)
│   ├── subdomains_merged.txt  ← 66 unique subdomains
│   ├── related_domains.txt    ← 14 country TLD variants
│   └── wildcards_found.txt    ← 22 wildcard certs
└── dns/
    ├── dns_resolution.json
    ├── dns_resolution.txt
    └── unique_ips.txt         ← 191 unique IPs
```
