{"id":47599689,"url":"https://github.com/marcvspt/cyberthreat-ai","last_synced_at":"2026-04-01T18:40:46.304Z","repository":{"id":346511056,"uuid":"1189036124","full_name":"marcvspt/cyberthreat-ai","owner":"marcvspt","description":null,"archived":false,"fork":false,"pushed_at":"2026-03-25T06:59:58.000Z","size":700,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-03-25T08:21:04.440Z","etag":null,"topics":["ai","astro","cti","cti-application","cybersecurity","tailwind","tailwindcss"],"latest_commit_sha":null,"homepage":"https://ctai.marcvspt.tech","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marcvspt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-22T22:47:27.000Z","updated_at":"2026-03-25T07:00:04.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/marcvspt/cyberthreat-ai","commit_stats":null,"previous_names":["marcvspt/cyberthreat-ai"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/marcvspt/cyberthreat-ai","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcvspt%2Fcyberthreat-ai","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcvspt%2Fcyberthreat-ai/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcvspt%2Fcyberthreat-ai/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcvspt%2Fcyberthreat-ai/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcvspt","download_url":"https://codeload.github.com/marcvspt/cyberthreat-ai/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcvspt%2Fcyberthreat-ai/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290943,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","astro","cti","cti-application","cybersecurity","tailwind","tailwindcss"],"created_at":"2026-04-01T18:40:44.249Z","updated_at":"2026-04-01T18:40:46.295Z","avatar_url":"https://github.com/marcvspt.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CyberThreat AI\n\n\u003e Proyecto creado para la [Hackaton Midudev + CubePath 2026](https://github.com/midudev/hackaton-cubepath-2026), lee mi propuesta en la [Issue #178](https://github.com/midudev/hackaton-cubepath-2026/issues/178). Puedes probar el proyecto en [https://ctai.marcvspt.tech](https://ctai.marcvspt.tech).\n\nCyberThreat AI analiza indicadores de compromiso (IoC) usando múltiples fuentes de threat intelligence (VirusTotal, AbuseIPDB, PolySwarm y Robtex), y después consulta una IA vía OpenRouter para entregar un veredicto razonado en español.\n\n![alt text](image-2.png)\n![alt text](image-1.png)\n\n***Use un VPS con Dokploy para el despliegue de esta plataforma CyberThreat AI. Desde que conozco Dokploy lo he querido probar más haya de una PoC simple por hobbie, y este Hakaton me dio la oportunidad de usarlo y jugar con esta herramienta***\n\n![alt text](image.png)\n\n## TODO\n\n- [x] Endpoint para envío de IoCs\n- [x] Formulario de envío de IoCs\n- [x] Espacio para respuesta\n- [x] Detección de tipo de IoC con validadores Zod (IPv4, IPv6, dominio, MD5, SHA1, SHA256)\n- [x] Conexión con API de [VirusTotal](https://virustotal.com)\n- [x] Conexión con API de [AbuseIPDB](https://abuseipdb.com)\n- [x] Conexión con API de [PolySwarm](https://polyswarm.network)\n- [x] Conexión con API de [Robtex](https://robtex.com)\n- [x] Conexión con API de [OpenRouter](https://openrouter.ai)\n- [x] Normalización de información\n- [x] Stream de datos de la respuesta de la IA\n- [x] Despliegue de la plataforma\n- [x] Rate limit de consultas a la API\n- [x] Colocar API keys propias de los usuarios para las herramientas utilizadas\n- [x] Permitir a los usuarios usar varios modelos de IA\n- [x] Sistema de advertencias por fuente (API key inválida, sin datos)\n- [x] Errores específicos de OpenRouter (API key inválida, error de modelo, servicio no disponible)\n\n## Características actuales\n\n- Endpoint único de análisis en `/api/ctai`.\n- Orquestación modular del endpoint en `src/scripts/core/ctai.ts` (rate limit, resolución de IoC/modelo, stream SSE y ejecución por tipo).\n- Detección de tipo de IoC con **Zod** (`z.ipv4`, `z.ipv6`, `z.hostname`, `z.hash`) centralizada en `src/scripts/core/iocValidators.ts`.\n- El campo **Tipo** en la UI muestra el subtipo exacto: `IPv4`, `IPv6`, `domain`, `hash/md5`, `hash/sha1`, `hash/sha256`.\n- Arquitectura de proveedores CTI separada en `src/scripts/sources/` (VirusTotal, AbuseIPDB, Robtex, PolySwarm), agnóstica al tipo de IoC.\n- Sistema de **advertencias por fuente**: si una API falla con clave inválida o sin datos, el análisis continúa con las demás fuentes y se informa en la UI sin cortar el flujo.\n- Streaming en tiempo real de la respuesta de IA (SSE).\n- El modelo mostrado en UI corresponde al **modelo ruteado real** por OpenRouter (cuando está disponible).\n- Render de markdown en la UI con `marked` + sanitización con `DOMPurify`.\n- Rate limit por IP en `/api/ctai` (configurable por variables de entorno).\n- Selector de modelo de IA desde UI (lista permitida en `src/scripts/catalog/models.ts`).\n- Modal para configurar API keys del usuario (persistidas en localStorage).\n- Fallback automático a variables de entorno si no se envían keys por cabecera.\n\n## Desplegar para desarrollo\n\n1. Instala dependencias:\n\n```sh\npnpm install\n```\n\n2. Crea un archivo `.env` con las keys (opcionales, recomendadas para fallback backend):\n\n```env\nVIRUSTOTAL_API_KEY=your-virustotal-apikey\nABUSEIPDB_API_KEY=your-abuseipdb-apikey\nPOLYSWARM_API_KEY=your-polyswarm-apikey\nOPENROUTER_API_KEY=your-openrouter-apikey\nRATE_LIMIT_POINTS=5\nRATE_LIMIT_DURATION=60\n```\n\n\u003e Robtex ofrece API pública sin API key para el flujo actual.\n\n3. Inicia el servidor de desarrollo:\n\n```sh\npnpm run dev #http://localhost:4321\n```\n\n## API\n\n### 1) Health\n\n- Ruta: `/api/health`\n- Método: `GET`\n- Respuesta:\n\n```json\n{\n  \"status\": \"ok\"\n}\n```\n\n### 2) Análisis IoC + IA en stream\n\n- Ruta: `/api/ctai?ioc=\u003cvalor\u003e\u0026model=\u003cmodelo\u003e`\n- Método: `GET`\n- Query params:\n  - `ioc` (requerido): indicador IPv4, IPv6, dominio, MD5, SHA1 o SHA256.\n  - `model` (opcional): modelo permitido; si no es válido se usa el default.\n\n- Headers opcionales para keys de usuario:\n  - `X-OpenRouter-Key`\n  - `X-VT-Key`\n  - `X-AbuseIPDB-Key`\n  - `X-Polyswarm-Key`\n\n- Content-Type de salida: `text/event-stream`\n\n- Eventos SSE emitidos:\n\n| Evento  | Payload                                  | Descripción                                       |\n|---------|------------------------------------------|---------------------------------------------------|\n| `meta`  | `{ ioc, type, model, warnings? }`        | Metadatos iniciales; `warnings` si hay fuentes con advertencia |\n| `model` | `{ model }`                              | Modelo ruteado real por OpenRouter                |\n| `chunk` | `{ content }`                            | Fragmento de texto de la respuesta IA             |\n| `done`  | `{ done: true }`                         | Fin del stream                                    |\n| `error` | `{ error, stage, errorType }`            | Error durante el stream                           |\n\n- `errorType` puede ser: `invalid_api_key`, `model_error`, `api_unavailable`, `not_found`, `unknown`.\n\nEjemplo:\n\n```bash\ncurl \"http://localhost:4321/api/ctai?ioc=1.2.3.4\u0026model=openrouter/auto\"\ncurl \"http://localhost:4321/api/ctai?ioc=2001:4860:4860::8888\"\ncurl \"http://localhost:4321/api/ctai?ioc=44d88612fea8a8f36de82e1278abb02f\"\n```\n\nComportamiento de errores:\n\n- Si **todas** las fuentes CTI fallan críticamente, se corta el flujo y no se invoca OpenRouter.\n- Si **algunas** fuentes fallan, el análisis continúa con las disponibles y se emiten advertencias en `meta.warnings`.\n- Los errores de OpenRouter son específicos: clave inválida, error del modelo (p. ej. límite de contexto) o servicio no disponible.\n\nErrores comunes (JSON):\n\n```json\n{ \"error\": \"Falta el parámetro de IoC\" }\n```\n\n```json\n{ \"error\": \"Tipo de IoC desconocido\" }\n```\n\n```json\n{ \"error\": \"No se pudo completar la consulta de fuentes del IoC.\", \"stage\": \"ioc\", \"errorType\": \"unknown\" }\n```\n\n```json\n{ \"error\": \"La API Key de OpenRouter no es válida o no tiene permisos suficientes.\", \"stage\": \"ai\", \"errorType\": \"invalid_api_key\" }\n```\n\n```json\n{ \"error\": \"Too many requests\", \"retryAfterSeconds\": 12 }\n```\n\n## Modelos permitidos\n\nLa fuente única de modelos está en `src/scripts/catalog/models.ts` (`AVAILABLE_MODELS`).\n\nModelos actualmente permitidos:\n\n- `openrouter/auto`\n- `openrouter/free`\n- `liquid/lfm-2.5-1.2b-instruct-20260120:free`\n- `stepfun/step-3.5-flash:free`\n- `google/gemma-3-4b-it:free`\n\n## Estructura del proyecto\n\n```text\nsrc/\n├── assets/\n├── components/\n│   ├── AIResponsePanel.tsx\n│   ├── AlertBox.tsx\n│   ├── ApiKeysModal.tsx\n│   ├── ApiKeysSettingsButton.tsx\n│   ├── App.tsx\n│   ├── Footer.astro\n│   ├── Header.astro\n│   ├── IoCInputField.tsx\n│   ├── IoCSearchForm.tsx\n│   ├── IocTypeChips.tsx\n│   └── ModelSelector.tsx\n├── hooks/\n│   ├── useAnalyzeIoC.ts\n│   ├── useApiKeys.ts\n│   └── useClickOutside.ts\n├── layouts/\n│   └── BaseLayout.astro\n├── pages/\n│   ├── index.astro\n│   └── api/\n│       ├── ctai.ts\n│       └── health.ts\n├── scripts/\n│   ├── core/\n│   │   ├── ctai.ts\n│   │   ├── ctaiClient.ts\n│   │   ├── errors.ts\n│   │   └── iocValidators.ts\n│   ├── catalog/\n│   │   ├── data.ts\n│   │   ├── models.ts\n│   │   ├── statusMessages.ts\n│   │   └── utils.ts\n│   ├── iocs/\n│   │   ├── domain.ts\n│   │   ├── fetcher.ts\n│   │   ├── hash.ts\n│   │   └── ip.ts\n│   ├── sources/\n│   │   ├── abuseipdb.ts\n│   │   ├── polyswarm.ts\n│   │   ├── robtex.ts\n│   │   └── virustotal.ts\n│   └── types.ts\n└── styles/\n    └── global.css\n```\n\n## Roadmap\n\n- [ ] Implementar test\n- [ ] Refactorizar y simplificar código\n- [ ] Documentar la API y todo lo que puede devolver\n- [ ] Enviar multiples IoCs en la misma consulta separandolos por coma, punto y coma, y/o salto de linea.\n- [ ] Enviar IoCs por lotes usando archivos **CSV** o dividos por salto\n- [x] Implementar `zod` para validación de datos\n- [x] Arquitectura modular por proveedor CTI (`sources/`)\n- [ ] Creación de cuentas de usuarios\n- [ ] Guardar historial de busquedas y respuestas\n- [ ] Cache de respuestas de las APIs y de las IAs para IoCs recientes\n- [ ] Implementar más herramientas de información sobre IoCs\n\n## Stack\n\n- [CubePath](https://cubepath.com)\n- [Astro](https://astro.build/)\n- [Preact](https://preactjs.com/)\n- [Tailwind CSS](https://tailwindcss.com/)\n- [Tabler Icons](https://tabler.io/icons)\n- [SVGl](https://svgl.app/)\n- [Heroicons](https://heroicons.com/)\n- [TypeScript](https://www.typescriptlang.org/)\n- [marked](https://github.com/markedjs/marked)\n- [DOMPurify](https://github.com/cure53/DOMPurify)\n- [Zod](https://zod.dev/)\n- [OpenRouter](https://openrouter.ai/)\n- [VirusTotal](https://www.virustotal.com/)\n- [AbuseIPDB](https://www.abuseipdb.com/)\n- [PolySwarm](https://polyswarm.io/)\n- [Robtex](https://www.robtex.com/)\n- [GitHub Copilot](https://github.com/copilot/)\n\n## Licencia\n\nEste proyecto está licenciado bajo los términos de la [GNU General Public License v3.0](https://github.com/marcvspt/cyberthreat-ai/blob/master/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcvspt%2Fcyberthreat-ai","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcvspt%2Fcyberthreat-ai","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcvspt%2Fcyberthreat-ai/lists"}