---
name: enumerate_username_sites
kind: function
lang: py
domain: cybersecurity
version: "1.0.0"
purity: impure
signature: "def enumerate_username_sites(username: str, timeout_s: float = 8.0, sites: list | None = None) -> list"
description: "Comprueba si un username existe en ~12 sitios publicos (github, twitter/x, instagram, tiktok, reddit, gitlab, keybase, medium, telegram, youtube, pinterest, about.me) consultando la URL de perfil estilo sherlock ligero. Detecta por codigo HTTP (200 existe, 404 no existe). Cada sitio se consulta aislado en try/except con User-Agent de navegador y allow_redirects: un timeout no aborta el resto. OSINT pasivo."
tags: [osint-passive, username, enumeration, recon, identity, sherlock, cybersecurity, python]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [requests]
params:
  - name: username
    desc: "Nombre de usuario a buscar, sin arroba ni URL (ej. 'jdoe')."
  - name: timeout_s
    desc: "Timeout en segundos por peticion HTTP. Default 8.0."
  - name: sites
    desc: "Lista opcional de dicts {'site','url'} donde 'url' lleva el placeholder '{u}'. Si es None usa DEFAULT_SITES (~12 sitios)."
output: "Lista de dicts {'site','url','exists','status'} en el orden de los sitios. 'exists' es True/False/None y 'status' el codigo HTTP (int) o None si la peticion fallo."
tested: true
tests:
  - "test_status_200_es_existe"
  - "test_status_404_es_no_existe"
  - "test_status_otro_es_indeterminado"
  - "test_excepcion_por_sitio_no_aborta_el_resto"
  - "test_estructura_y_url_formateada"
  - "test_lista_por_defecto_tiene_doce_sitios"
test_file_path: "python/functions/cybersecurity/enumerate_username_sites_test.py"
file_path: "python/functions/cybersecurity/enumerate_username_sites.py"
---

## Ejemplo

```python
enumerate_username_sites("torvalds", timeout_s=8.0)
# [{"site": "github",   "url": "https://github.com/torvalds",        "exists": True,  "status": 200},
#  {"site": "twitter",  "url": "https://x.com/torvalds",             "exists": None,  "status": 403},
#  {"site": "instagram","url": "https://www.instagram.com/torvalds/","exists": False, "status": 404},
#  ...]

# Lista propia de sitios:
enumerate_username_sites("jdoe", sites=[{"site": "github", "url": "https://github.com/{u}"}])
```

## Cuando usarla

Usala cuando tengas un username (o alias) y quieras un barrido rapido de presencia en redes/plataformas publicas para mapear la huella digital de un objetivo en una investigacion autorizada. Util tras `guess_email_formats` para pivotar de identidad a perfiles, o como entrada para construir dorks con `build_search_dorks`.

## Gotchas

- **Deja huella**: aunque es recoleccion "pasiva" desde el punto de vista del objetivo, lanza una peticion HTTP real a cada sitio. Esas peticiones quedan en logs del sitio y pueden asociarse a tu IP. Usa proxy/VPN si la investigacion lo requiere.
- **Falsos positivos/negativos por anti-bot**: muchos sitios (instagram, tiktok, x) devuelven 200 con paginas de login/captcha o bloquean por User-Agent, dando exists=True erroneo o status indeterminado. El 200/404 no es garantia; verifica manualmente los hits relevantes.
- **Respeta rate limits**: lanzar muchas comprobaciones seguidas puede activar bloqueos o baneos temporales por IP. Espacia las consultas en barridos grandes.
- **Estados intermedios**: cualquier codigo distinto de 200/404 (301, 403, 429, 5xx) deja `exists=None`; un fallo de red por sitio deja `status=None` y `exists=None` sin abortar el resto.
- **Solo para investigacion autorizada.** No uses esta funcion para acoso, doxing ni vigilancia sin base legal.
