# vetkit > Code assurance for AI-assisted development: repository audits, risk visibility and team remediation workflows. vetkit complements coding agents; it is not a coding agent or a guarantee that code is secure. ## Product and availability - [Platform overview](https://vetkit.dev/en/product/): Repository coverage, team ownership, risk decisions, MCP and reporting. - [Free Security Quick Scan](https://vetkit.dev/en/#pricing): Create an account with Google, GitHub, Apple or email, then connect a GitHub, GitLab.com or Bitbucket Cloud repository. Limited to secrets, known dependency vulnerabilities and basic security posture. No AI usage. There are no plans or tiers: every account gets every feature, and full scans and DAST report uploads use credits. - [Checks and limitations](https://vetkit.dev/en/#checks): Five scored audit suites: security, code quality, sustainability, AI code risks and production readiness, plus opt-in, unscored Privacy & Data Protection (beta) and Git history suites. Expanded checks, AI review and automatic scans run as full scans that use credits; they are not part of Free Quick Scan. - [Programming languages and coverage](https://vetkit.dev/en/#languages): Language-specific code-security rules and complexity/duplication coverage. Coverage varies by language, framework, selected checks and available tools. ## Developer documentation - [Getting started](https://vetkit.dev/en/docs/): Organizations, repositories, audits, findings and reports. - [MCP setup](https://vetkit.dev/en/docs/mcp/): Connect any stdio-capable MCP client with the @vetkit/mcp server, including Cursor, VS Code, Codex and Claude. No remote HTTP/SSE MCP endpoint is provided. - [REST API](https://vetkit.dev/en/docs/api/): API keys, scopes, audit operations and report exports. - [VS Code extension](https://vetkit.dev/en/docs/vscode/): Install the vetkit extension, sign in from the browser and see the latest audit findings for the open repository as diagnostics. Scope-limited API key for reading findings, starting audits and permitted AI fix previews; local source code is never uploaded. ## Product guides (English) - [Connect a repository](https://vetkit.dev/en/docs/connect-repo/): Connect source access and confirm the repository before its first scan. - [Run your first audit](https://vetkit.dev/en/docs/first-audit/): Choose checks, follow execution and read the report for the audited commit. - [Understand scores and grades](https://vetkit.dev/en/docs/scores/): Read weighted scores alongside coverage, critical findings and unscored evidence. - [Work through findings](https://vetkit.dev/en/docs/findings-workflow/): Triage evidence, assign remediation and verify fixes against a newer audit. - [Secure your supply chain](https://vetkit.dev/en/docs/supply-chain/): Create inventories, evaluate policy, record VEX decisions and compare releases. - [Review pull requests](https://vetkit.dev/en/docs/pull-requests/): Configure PR Delta Review for GitHub, GitLab or Bitbucket and understand the separate merge gate. - [DAST and network reports](https://vetkit.dev/en/docs/dast-network/): Connect local tools and interpret their uploaded observations and sharing scope. - [Evaluate AI prompts and models](https://vetkit.dev/en/docs/ai-evaluations/): Move from the local playground to configured targets, graders and evaluation runs. - [Share results](https://vetkit.dev/en/docs/sharing/): Choose public summaries, report exports or repository badges for your audience. - [Set policy and exceptions](https://vetkit.dev/en/docs/policy-exceptions/): Version organization policy, request time-limited exceptions and apply repository overrides. - [Monitor repositories continuously](https://vetkit.dev/en/docs/monitoring/): Set scan schedules and distinguish advisory notifications from fresh audit evidence. - [Bring in your team and tools](https://vetkit.dev/en/docs/team-integrations/): Use team roles, scoped credentials and integrations in the correct workspace. - [Watch AI coding agents with Agent Watch](https://vetkit.dev/en/docs/agent-watch/): Pair the desktop app, read agent alerts and session attestations, and understand what is uploaded. ## Ürün rehberleri (Türkçe) - [Bir depo bağlayın](https://vetkit.dev/tr/docs/connect-repo/): Kaynak erişimini bağlayın ve ilk taramadan önce depoyu doğrulayın. - [İlk denetiminizi çalıştırın](https://vetkit.dev/tr/docs/first-audit/): Kontrolleri seçin, çalışmayı izleyin ve denetlenen commit için raporu okuyun. - [Puanları ve notları anlayın](https://vetkit.dev/tr/docs/scores/): Ağırlıklı puanları kapsam, kritik bulgular ve puanlanmayan kanıtlarla birlikte okuyun. - [Bulguları ele alın](https://vetkit.dev/tr/docs/findings-workflow/): Kanıtları değerlendirin, düzeltme işini atayın ve daha yeni bir denetimle doğrulayın. - [Tedarik zincirinizi güvenceye alın](https://vetkit.dev/tr/docs/supply-chain/): Envanter oluşturun, politikayı değerlendirin, VEX kararlarını kaydedin ve sürümleri karşılaştırın. - [Pull request’leri inceleyin](https://vetkit.dev/tr/docs/pull-requests/): GitHub, GitLab veya Bitbucket için PR Delta Review özelliğini yapılandırın ve ayrı birleştirme koşulunu anlayın. - [DAST ve ağ raporları](https://vetkit.dev/tr/docs/dast-network/): Yerel araçları bağlayın; yüklenen gözlemleri ve paylaşım kapsamını yorumlayın. - [Yapay zekâ istemlerini ve modellerini değerlendirin](https://vetkit.dev/tr/docs/ai-evaluations/): Yerel deneme alanından yapılandırılmış hedeflere, puanlayıcılara ve değerlendirme koşularına geçin. - [Sonuçları paylaşın](https://vetkit.dev/tr/docs/sharing/): Hedef kitleniz için herkese açık özet, rapor dışa aktarımı veya depo rozeti seçin. - [Politika ve istisnaları belirleyin](https://vetkit.dev/tr/docs/policy-exceptions/): Organizasyon politikasını sürümleyin, süreli istisna isteyin ve depo ayarlarını uygulayın. - [Depoları sürekli izleyin](https://vetkit.dev/tr/docs/monitoring/): Tarama zamanlamalarını ayarlayın; güvenlik duyurusu bildirimlerini yeni denetim kanıtlarından ayırın. - [Ekibinizi ve araçlarınızı bağlayın](https://vetkit.dev/tr/docs/team-integrations/): Ekip rollerini, kapsamlı kimlik bilgilerini ve entegrasyonları doğru çalışma alanında kullanın. - [Agent Watch ile yapay zekâ kodlama ajanlarını izleyin](https://vetkit.dev/tr/docs/agent-watch/): Masaüstü uygulamasını eşleyin, ajan uyarılarını ve oturum beyanlarını okuyun, nelerin yüklendiğini anlayın. ## Produktleitfäden (Deutsch) - [Ein Repository verbinden](https://vetkit.dev/de/docs/connect-repo/): Verbinden Sie den Quellzugriff und prüfen Sie das Repository vor seinem ersten Scan. - [Das erste Audit starten](https://vetkit.dev/de/docs/first-audit/): Wählen Sie Prüfungen, verfolgen Sie die Ausführung und lesen Sie den Bericht zum geprüften Commit. - [Punktzahlen und Noten verstehen](https://vetkit.dev/de/docs/scores/): Lesen Sie gewichtete Punktzahlen zusammen mit Abdeckung, kritischen Befunden und unbewerteten Nachweisen. - [Befunde bearbeiten](https://vetkit.dev/de/docs/findings-workflow/): Bewerten Sie Nachweise, weisen Sie Behebungsaufgaben zu und verifizieren Sie Korrekturen mit einem neueren Audit. - [Die Lieferkette absichern](https://vetkit.dev/de/docs/supply-chain/): Erstellen Sie Inventare, bewerten Sie Richtlinien, erfassen Sie VEX-Entscheidungen und vergleichen Sie Versionen. - [Pull Requests prüfen](https://vetkit.dev/de/docs/pull-requests/): Konfigurieren Sie PR Delta Review für GitHub, GitLab oder Bitbucket und verstehen Sie die separate Prüfung vor dem Zusammenführen. - [DAST- und Netzwerkberichte](https://vetkit.dev/de/docs/dast-network/): Verbinden Sie lokale Werkzeuge und interpretieren Sie hochgeladene Beobachtungen und deren Freigabeumfang. - [KI-Prompts und Modelle bewerten](https://vetkit.dev/de/docs/ai-evaluations/): Wechseln Sie vom lokalen Playground zu konfigurierten Zielen, Bewertungsverfahren und Evaluationsläufen. - [Ergebnisse teilen](https://vetkit.dev/de/docs/sharing/): Wählen Sie öffentliche Zusammenfassungen, Berichtexporte oder Repository-Badges für Ihre Zielgruppe. - [Richtlinien und Ausnahmen festlegen](https://vetkit.dev/de/docs/policy-exceptions/): Versionieren Sie Organisationsrichtlinien, beantragen Sie befristete Ausnahmen und wenden Sie Repository-Anpassungen an. - [Repositories kontinuierlich überwachen](https://vetkit.dev/de/docs/monitoring/): Legen Sie Scan-Zeitpläne fest und unterscheiden Sie Sicherheitsmeldungen von aktuellen Audit-Nachweisen. - [Team und Werkzeuge einbinden](https://vetkit.dev/de/docs/team-integrations/): Verwenden Sie Teamrollen, begrenzte Zugangsdaten und Integrationen im richtigen Arbeitsbereich. - [KI-Coding-Agenten mit Agent Watch beobachten](https://vetkit.dev/de/docs/agent-watch/): Koppeln Sie die Desktop-App, lesen Sie Agentenwarnungen und Sitzungsbestätigungen und verstehen Sie, was hochgeladen wird. ## Guías del producto (Español) - [Conectar un repositorio](https://vetkit.dev/es/docs/connect-repo/): Conecte el acceso al código y confirme el repositorio antes de su primer análisis. - [Ejecutar la primera auditoría](https://vetkit.dev/es/docs/first-audit/): Elija comprobaciones, siga la ejecución y lea el informe del commit auditado. - [Entender las puntuaciones y notas](https://vetkit.dev/es/docs/scores/): Lea las puntuaciones ponderadas junto con la cobertura, los hallazgos críticos y las evidencias sin puntuar. - [Gestionar los hallazgos](https://vetkit.dev/es/docs/findings-workflow/): Evalúe evidencias, asigne correcciones y verifique los resultados con una auditoría más reciente. - [Proteger la cadena de suministro](https://vetkit.dev/es/docs/supply-chain/): Cree inventarios, evalúe políticas, registre decisiones VEX y compare versiones. - [Revisar pull requests](https://vetkit.dev/es/docs/pull-requests/): Configure PR Delta Review para GitHub, GitLab o Bitbucket y entienda el control independiente previo a la fusión. - [Informes DAST y de red](https://vetkit.dev/es/docs/dast-network/): Conecte herramientas locales e interprete sus observaciones cargadas y su alcance de uso compartido. - [Evaluar prompts y modelos de IA](https://vetkit.dev/es/docs/ai-evaluations/): Pase del entorno local de pruebas a destinos configurados, evaluadores y ejecuciones de evaluación. - [Compartir resultados](https://vetkit.dev/es/docs/sharing/): Elija resúmenes públicos, exportaciones de informes o insignias de repositorios para sus destinatarios. - [Definir políticas y excepciones](https://vetkit.dev/es/docs/policy-exceptions/): Versione políticas de la organización, solicite excepciones temporales y aplique ajustes por repositorio. - [Supervisar repositorios continuamente](https://vetkit.dev/es/docs/monitoring/): Programe análisis y distinga las notificaciones de avisos de seguridad de las evidencias recientes de auditoría. - [Conectar el equipo y las herramientas](https://vetkit.dev/es/docs/team-integrations/): Use roles de equipo, credenciales de alcance limitado e integraciones en el espacio de trabajo correcto. - [Observe agentes de programación con IA con Agent Watch](https://vetkit.dev/es/docs/agent-watch/): Empareje la app de escritorio, lea alertas de agentes y declaraciones de sesión, y entienda qué se sube. ## Guides produit (Français) - [Connecter un dépôt](https://vetkit.dev/fr/docs/connect-repo/): Connectez l’accès au code source et confirmez le dépôt avant sa première analyse. - [Lancer votre premier audit](https://vetkit.dev/fr/docs/first-audit/): Choisissez les contrôles, suivez l’exécution et lisez le rapport du commit audité. - [Comprendre les scores et les notes](https://vetkit.dev/fr/docs/scores/): Lisez les scores pondérés avec la couverture, les constats critiques et les éléments non notés. - [Traiter les constats](https://vetkit.dev/fr/docs/findings-workflow/): Évaluez les éléments probants, attribuez les corrections et vérifiez-les avec un audit plus récent. - [Sécuriser la chaîne d’approvisionnement](https://vetkit.dev/fr/docs/supply-chain/): Créez des inventaires, évaluez les politiques, enregistrez les décisions VEX et comparez les versions. - [Examiner les pull requests](https://vetkit.dev/fr/docs/pull-requests/): Configurez PR Delta Review pour GitHub, GitLab ou Bitbucket et comprenez le contrôle distinct préalable à la fusion. - [Rapports DAST et réseau](https://vetkit.dev/fr/docs/dast-network/): Connectez les outils locaux et interprétez les observations envoyées et leur périmètre de partage. - [Évaluer les invites et modèles d’IA](https://vetkit.dev/fr/docs/ai-evaluations/): Passez de l’aire d’essai locale aux cibles configurées, aux évaluateurs et aux exécutions d’évaluation. - [Partager les résultats](https://vetkit.dev/fr/docs/sharing/): Choisissez des résumés publics, des exports de rapports ou des badges de dépôt pour vos destinataires. - [Définir les politiques et exceptions](https://vetkit.dev/fr/docs/policy-exceptions/): Versionnez la politique de l’organisation, demandez des exceptions temporaires et appliquez les paramètres du dépôt. - [Surveiller les dépôts en continu](https://vetkit.dev/fr/docs/monitoring/): Planifiez les analyses et distinguez les notifications d’avis de sécurité des éléments d’audit récents. - [Connecter votre équipe et vos outils](https://vetkit.dev/fr/docs/team-integrations/): Utilisez les rôles d’équipe, les identifiants à périmètre limité et les intégrations dans le bon espace de travail. - [Surveiller les agents de codage IA avec Agent Watch](https://vetkit.dev/fr/docs/agent-watch/): Associez l’application de bureau, lisez les alertes d’agents et les attestations de session, et comprenez ce qui est envoyé. ## Guide del prodotto (Italiano) - [Collega un repository](https://vetkit.dev/it/docs/connect-repo/): Collega l’accesso al codice e conferma il repository prima della prima scansione. - [Esegui il primo audit](https://vetkit.dev/it/docs/first-audit/): Scegli i controlli, segui l’esecuzione e leggi il report del commit sottoposto ad audit. - [Comprendi punteggi e voti](https://vetkit.dev/it/docs/scores/): Leggi i punteggi ponderati insieme a copertura, rilievi critici ed evidenze senza punteggio. - [Gestisci i rilievi](https://vetkit.dev/it/docs/findings-workflow/): Valuta le evidenze, assegna le correzioni e verificale con un audit più recente. - [Proteggi la catena di fornitura](https://vetkit.dev/it/docs/supply-chain/): Crea inventari, valuta le policy, registra decisioni VEX e confronta le versioni. - [Esamina le pull request](https://vetkit.dev/it/docs/pull-requests/): Configura PR Delta Review per GitHub, GitLab o Bitbucket e comprendi il controllo separato prima del merge. - [Report DAST e di rete](https://vetkit.dev/it/docs/dast-network/): Collega strumenti locali e interpreta le osservazioni caricate e il relativo ambito di condivisione. - [Valuta prompt e modelli di IA](https://vetkit.dev/it/docs/ai-evaluations/): Passa dall’area di prova locale a destinazioni configurate, valutatori ed esecuzioni di valutazione. - [Condividi i risultati](https://vetkit.dev/it/docs/sharing/): Scegli riepiloghi pubblici, esportazioni dei report o badge del repository per i tuoi destinatari. - [Definisci policy ed eccezioni](https://vetkit.dev/it/docs/policy-exceptions/): Versiona la policy dell’organizzazione, richiedi eccezioni temporanee e applica impostazioni del repository. - [Monitora i repository continuamente](https://vetkit.dev/it/docs/monitoring/): Pianifica le scansioni e distingui le notifiche degli avvisi di sicurezza dalle evidenze recenti degli audit. - [Collega team e strumenti](https://vetkit.dev/it/docs/team-integrations/): Usa ruoli del team, credenziali con ambito limitato e integrazioni nello spazio di lavoro corretto. - [Osserva gli agenti di programmazione IA con Agent Watch](https://vetkit.dev/it/docs/agent-watch/): Associa l’app desktop, leggi gli avvisi degli agenti e le attestazioni di sessione e capisci cosa viene caricato. ## Guias do produto (Português) - [Conectar um repositório](https://vetkit.dev/pt/docs/connect-repo/): Conecte o acesso ao código e confirme o repositório antes da primeira análise. - [Executar a primeira auditoria](https://vetkit.dev/pt/docs/first-audit/): Escolha verificações, acompanhe a execução e leia o relatório do commit auditado. - [Entender pontuações e notas](https://vetkit.dev/pt/docs/scores/): Leia pontuações ponderadas junto com cobertura, achados críticos e evidências sem pontuação. - [Trabalhar com os achados](https://vetkit.dev/pt/docs/findings-workflow/): Avalie evidências, atribua correções e verifique os resultados com uma auditoria mais recente. - [Proteger a cadeia de suprimentos](https://vetkit.dev/pt/docs/supply-chain/): Crie inventários, avalie políticas, registre decisões VEX e compare versões. - [Revisar pull requests](https://vetkit.dev/pt/docs/pull-requests/): Configure PR Delta Review para GitHub, GitLab ou Bitbucket e entenda o controle separado antes do merge. - [Relatórios DAST e de rede](https://vetkit.dev/pt/docs/dast-network/): Conecte ferramentas locais e interprete as observações enviadas e seu escopo de compartilhamento. - [Avaliar prompts e modelos de IA](https://vetkit.dev/pt/docs/ai-evaluations/): Passe do ambiente local de testes a destinos configurados, avaliadores e execuções de avaliação. - [Compartilhar resultados](https://vetkit.dev/pt/docs/sharing/): Escolha resumos públicos, exportações de relatórios ou badges de repositório para seu público. - [Definir políticas e exceções](https://vetkit.dev/pt/docs/policy-exceptions/): Versione a política da organização, solicite exceções temporárias e aplique configurações do repositório. - [Monitorar repositórios continuamente](https://vetkit.dev/pt/docs/monitoring/): Agende análises e diferencie notificações de avisos de segurança de evidências recentes de auditoria. - [Conectar sua equipe e ferramentas](https://vetkit.dev/pt/docs/team-integrations/): Use papéis da equipe, credenciais de escopo limitado e integrações no espaço de trabalho correto. - [Observe agentes de programação com IA com o Agent Watch](https://vetkit.dev/pt/docs/agent-watch/): Pareie o app de desktop, leia alertas de agentes e atestados de sessão e entenda o que é enviado. ## Руководства по продукту (Русский) - [Подключить репозиторий](https://vetkit.dev/ru/docs/connect-repo/): Подключите доступ к коду и проверьте репозиторий перед первым сканированием. - [Запустить первый аудит](https://vetkit.dev/ru/docs/first-audit/): Выберите проверки, следите за выполнением и прочитайте отчёт по проверенному коммиту. - [Понять оценки и уровни](https://vetkit.dev/ru/docs/scores/): Читайте взвешенные оценки вместе с покрытием, критическими находками и неоцениваемыми свидетельствами. - [Работать с находками](https://vetkit.dev/ru/docs/findings-workflow/): Разбирайте свидетельства, назначайте исправления и проверяйте результат по новому аудиту. - [Защитить цепочку поставок](https://vetkit.dev/ru/docs/supply-chain/): Создавайте инвентари, оценивайте политику, фиксируйте решения VEX и сравнивайте релизы. - [Проверять pull request](https://vetkit.dev/ru/docs/pull-requests/): Настройте PR Delta Review для GitHub, GitLab или Bitbucket и разберитесь в отдельном контроле слияния. - [Отчёты DAST и сетевые отчёты](https://vetkit.dev/ru/docs/dast-network/): Подключите локальные инструменты и интерпретируйте загруженные наблюдения и область их публикации. - [Оценивать промпты и модели ИИ](https://vetkit.dev/ru/docs/ai-evaluations/): Перейдите от локальной песочницы к настроенным целям, оценщикам и запускам оценки. - [Делиться результатами](https://vetkit.dev/ru/docs/sharing/): Выбирайте публичные сводки, экспорт отчётов или бейджи репозитория для своей аудитории. - [Задать политику и исключения](https://vetkit.dev/ru/docs/policy-exceptions/): Версионируйте политику организации, запрашивайте временные исключения и применяйте настройки репозитория. - [Непрерывно отслеживать репозитории](https://vetkit.dev/ru/docs/monitoring/): Настройте расписание сканирования и отличайте уведомления о рекомендациях от свежих свидетельств аудита. - [Подключить команду и инструменты](https://vetkit.dev/ru/docs/team-integrations/): Используйте роли команды, ограниченные учётные данные и интеграции в нужном рабочем пространстве. - [Наблюдайте за ИИ-агентами для кода с Agent Watch](https://vetkit.dev/ru/docs/agent-watch/): Свяжите приложение для компьютера, читайте оповещения агентов и подтверждения сеансов и поймите, что передаётся. ## أدلة المنتج (العربية) - [ربط مستودع](https://vetkit.dev/ar/docs/connect-repo/): اربط صلاحية الوصول إلى الكود وتأكد من المستودع قبل أول فحص له. - [تشغيل أول تدقيق](https://vetkit.dev/ar/docs/first-audit/): اختر الفحوصات، وتابع التنفيذ، واقرأ تقرير commit الذي خضع للتدقيق. - [فهم الدرجات والتقييمات](https://vetkit.dev/ar/docs/scores/): اقرأ الدرجات المرجّحة مع التغطية والنتائج الحرجة والأدلة غير المقيّمة. - [التعامل مع النتائج](https://vetkit.dev/ar/docs/findings-workflow/): افرز الأدلة، وعيّن مهام الإصلاح، وتحقق من الإصلاحات مقابل تدقيق أحدث. - [تأمين سلسلة التوريد](https://vetkit.dev/ar/docs/supply-chain/): أنشئ الجرود، وقيّم السياسة، وسجّل قرارات VEX، وقارن الإصدارات. - [مراجعة طلبات السحب](https://vetkit.dev/ar/docs/pull-requests/): اضبط PR Delta Review لـ GitHub أو GitLab أو Bitbucket وافهم بوابة الدمج المنفصلة. - [تقارير DAST والشبكة](https://vetkit.dev/ar/docs/dast-network/): اربط الأدوات المحلية وفسّر ملاحظاتها المرفوعة ونطاق مشاركتها. - [تقييم موجّهات ونماذج الذكاء الاصطناعي](https://vetkit.dev/ar/docs/ai-evaluations/): انتقل من بيئة التجربة المحلية إلى الأهداف المضبوطة والمقيّمين وعمليات التقييم. - [مشاركة النتائج](https://vetkit.dev/ar/docs/sharing/): اختر الملخصات العامة أو تصدير التقارير أو شارات المستودع لجمهورك. - [تحديد السياسة والاستثناءات](https://vetkit.dev/ar/docs/policy-exceptions/): رقّم إصدارات سياسة المؤسسة، واطلب استثناءات محددة المدة، وطبّق تجاوزات المستودع. - [مراقبة المستودعات باستمرار](https://vetkit.dev/ar/docs/monitoring/): حدد جداول الفحص وميّز إشعارات التنبيهات الأمنية عن أدلة التدقيق الحديثة. - [إشراك فريقك وأدواتك](https://vetkit.dev/ar/docs/team-integrations/): استخدم أدوار الفريق وبيانات الاعتماد محدودة النطاق والتكاملات في مساحة العمل الصحيحة. - [راقب وكلاء البرمجة بالذكاء الاصطناعي مع Agent Watch](https://vetkit.dev/ar/docs/agent-watch/): اقرن تطبيق سطح المكتب، واقرأ تنبيهات الوكلاء وإقرارات الجلسات، وافهم ما يُرفع. ## Product updates - [Changelog](https://vetkit.dev/changelog/): Curated release notes with dates and availability details. - [Changelog RSS](https://vetkit.dev/changelog/feed.xml): Subscribe to product updates. ## Trust - [About vetkit](https://vetkit.dev/about/): What vetkit is, how audits and published content are produced, and contact addresses. - [Security](https://vetkit.dev/en/security/): Read-only audit access, code is never executed, temporary checkouts and redacted secrets. - [Privacy](https://vetkit.dev/en/privacy/): Stored finding snippets and explicit data-sharing conditions for optional AI features. - [Terms](https://vetkit.dev/en/terms/): Service conditions and limitations. ## Checks (English) - [Check catalog](https://vetkit.dev/checks/): First-party engine rule definitions, remediation and language scope. External community rules and runtime-only checks are not included. - [Android allowBackup=true exposes app data to backups](https://vetkit.dev/checks/vetkit.android.manifest.allow-backup/) (`vetkit.android.manifest.allow-backup`): The Android app explicitly enables `android:allowBackup`. App data, including tokens stored in SharedPreferences or databases, can be extracted with adb backup or cloud backup. - [Android usesCleartextTraffic=true allows cleartext HTTP](https://vetkit.dev/checks/vetkit.android.manifest.cleartext-traffic/) (`vetkit.android.manifest.cleartext-traffic`): The Android app allows cleartext HTTP traffic for all domains (`android:usesCleartextTraffic="true"`). Data and session tokens can be read or modified on the network. - [Android manifest debuggable=true in release builds](https://vetkit.dev/checks/vetkit.android.manifest.debuggable/) (`vetkit.android.manifest.debuggable`): The Android manifest hard-codes `android:debuggable="true"`. Release builds become debuggable, so anyone with the device can attach a debugger, read app data and run code in the app's process. - [Android exported ContentProvider without permission](https://vetkit.dev/checks/vetkit.android.manifest.exported-provider/) (`vetkit.android.manifest.exported-provider`): An exported Android content provider has no read/write permission. Any installed app can query or modify the data it serves (and use path traversal tricks if it serves files). - [Android exported BroadcastReceiver without permission](https://vetkit.dev/checks/vetkit.android.manifest.exported-receiver/) (`vetkit.android.manifest.exported-receiver`): An exported Android broadcast receiver has no `android:permission`. Any installed app can send it intents, including forged system-like broadcasts. - [Android exported Service without android:permission](https://vetkit.dev/checks/vetkit.android.manifest.exported-service/) (`vetkit.android.manifest.exported-service`): An exported Android service has no `android:permission`. Any installed app can start or bind to it and invoke its functionality. - [Android sharedUserId shares data between apps](https://vetkit.dev/checks/vetkit.android.manifest.shared-user-id/) (`vetkit.android.manifest.shared-user-id`): The Android app declares `android:sharedUserId`. Apps sharing a user ID share data and permissions, so a weakness in one of them exposes the other; the attribute is deprecated. - [Android testOnly=true set in the app manifest](https://vetkit.dev/checks/vetkit.android.manifest.test-only/) (`vetkit.android.manifest.test-only`): The Android manifest sets `android:testOnly="true"`, a flag meant only for test builds that should not be part of a shipped configuration. - [Android custom permission with normal protectionLevel](https://vetkit.dev/checks/vetkit.android.manifest.weak-custom-permission/) (`vetkit.android.manifest.weak-custom-permission`): A custom Android permission uses the `normal` or `dangerous` protection level (or none, which means normal). Any app can obtain it, so it does not protect the components that require it. - [Android network security config cleartextTrafficPermitted](https://vetkit.dev/checks/vetkit.android.network.cleartext-base-config/) (`vetkit.android.network.cleartext-base-config`): The Android network security config permits cleartext HTTP for every domain (``). - [Android network security config trusts user CA certificates](https://vetkit.dev/checks/vetkit.android.network.user-certificates-trusted/) (`vetkit.android.network.user-certificates-trusted`): The Android network security config trusts user-installed CA certificates outside `debug-overrides`. Anyone who can get a user to install a certificate can intercept the app's TLS traffic. - [Apache TraceEnable on exposes HTTP TRACE method](https://vetkit.dev/checks/vetkit.apache.http.trace-enabled/) (`vetkit.apache.http.trace-enabled`): Apache explicitly enables the HTTP TRACE method (`TraceEnable on`), which echoes request headers (including cookies) back to the client. - [Apache Options Indexes enables directory listing](https://vetkit.dev/checks/vetkit.apache.listing.indexes/) (`vetkit.apache.listing.indexes`): Apache directory listing is enabled (`Options Indexes`). Files in the directory that are not linked anywhere, such as backups or configuration files, can be listed and downloaded. - [Apache SSLProtocol enables SSLv3, TLSv1 or TLSv1.1](https://vetkit.dev/checks/vetkit.apache.tls.legacy-protocols/) (`vetkit.apache.tls.legacy-protocols`): Apache enables an obsolete SSL/TLS protocol version (SSLv2, SSLv3, TLSv1 or TLSv1.1) in `SSLProtocol`. These versions are deprecated by RFC 8996. - [Apache SSLCipherSuite enables weak ciphers (RC4, 3DES)](https://vetkit.dev/checks/vetkit.apache.tls.weak-ciphers/) (`vetkit.apache.tls.weak-ciphers`): Apache enables a broken cipher suite (RC4, DES/3DES, NULL, EXPORT, LOW, MD5 or anonymous key exchange) in `SSLCipherSuite`. - [ASP.NET Core DetailedErrors enabled outside Development](https://vetkit.dev/checks/vetkit.aspnet.appsettings.detailed-errors/) (`vetkit.aspnet.appsettings.detailed-errors`): An ASP.NET Core settings file that is not Development-only enables `DetailedErrors`. Blazor and the host then send exception details to the browser. - [ASP.NET customErrors mode=Off shows stack traces](https://vetkit.dev/checks/vetkit.aspnet.config.custom-errors-off/) (`vetkit.aspnet.config.custom-errors-off`): ASP.NET custom errors are switched off (``). Remote users see full exception details and stack traces. - [ASP.NET compilation debug=true in web.config](https://vetkit.dev/checks/vetkit.aspnet.config.debug-compilation/) (`vetkit.aspnet.config.debug-compilation`): ASP.NET compiles the application in debug mode (``). Debug builds disable optimisations and request timeouts and can expose detailed error information. - [IIS directoryBrowse enabled=true lists site files](https://vetkit.dev/checks/vetkit.aspnet.config.directory-browsing/) (`vetkit.aspnet.config.directory-browsing`): IIS directory browsing is enabled (``). Unlinked files in the site directory can be listed and downloaded. - [ASP.NET trace enabled with localOnly=false (trace.axd)](https://vetkit.dev/checks/vetkit.aspnet.config.remote-trace/) (`vetkit.aspnet.config.remote-trace`): ASP.NET tracing is enabled for remote clients (``). trace.axd then shows request details, headers, cookies and session state to anyone. - [ASP.NET validateRequest=false disables request validation](https://vetkit.dev/checks/vetkit.aspnet.config.request-validation-off/) (`vetkit.aspnet.config.request-validation-off`): ASP.NET request validation is disabled for the whole application (`validateRequest="false"`). Script and markup in request input is no longer rejected before it reaches pages. - [ASP.NET enableViewStateMac=false allows ViewState tampering](https://vetkit.dev/checks/vetkit.aspnet.config.viewstate-mac-off/) (`vetkit.aspnet.config.viewstate-mac-off`): ASP.NET ViewState MAC validation is disabled (`enableViewStateMac="false"`). Attackers can tamper with ViewState and, through deserialization, execute code on the server. - [C command injection: program input passed to system()](https://vetkit.dev/checks/vetkit.c.command-injection.input-to-shell/) (`vetkit.c.command-injection.input-to-shell`): A command line built from program arguments, environment variables or received data is run through the shell (command injection). - [C AES ECB mode leaks plaintext patterns](https://vetkit.dev/checks/vetkit.c.crypto.ecb-mode/) (`vetkit.c.crypto.ecb-mode`): AES is used in ECB mode; equal plaintext blocks produce equal ciphertext blocks, which leaks data patterns. - [C rand() or random() used for keys, tokens and nonces](https://vetkit.dev/checks/vetkit.c.crypto.insecure-random/) (`vetkit.c.crypto.insecure-random`): A key, token, salt or nonce is generated with rand() / random() or RAND_pseudo_bytes, which are not cryptographically secure. - [C weak cipher: DES, 3DES, RC4, RC2 or Blowfish](https://vetkit.dev/checks/vetkit.c.crypto.weak-cipher/) (`vetkit.c.crypto.weak-cipher`): DES, 3DES, RC4, RC2 or Blowfish is used; these ciphers are broken or have a 64-bit block size. - [C password hashed with MD5 or SHA-1](https://vetkit.dev/checks/vetkit.c.crypto.weak-password-hash/) (`vetkit.c.crypto.weak-password-hash`): A password or secret is hashed with MD5 / SHA-1, which can be brute-forced quickly. - [C signature or certificate using an MD5 or SHA-1 digest](https://vetkit.dev/checks/vetkit.c.crypto.weak-signature-hash/) (`vetkit.c.crypto.weak-signature-hash`): A signature or certificate is created or verified over an MD5 / SHA-1 digest, which is not collision resistant. - [C format string vulnerability: non-literal printf format](https://vetkit.dev/checks/vetkit.c.format-string.non-literal-format/) (`vetkit.c.format-string.non-literal-format`): A printf-family function receives a non-constant string as its format and no further arguments; `%n` / `%s` in that string read or write arbitrary memory. - [C double free: free() called twice on the same pointer](https://vetkit.dev/checks/vetkit.c.memory.double-free/) (`vetkit.c.memory.double-free`): The same pointer is passed to free() a second time without being reassigned in between (double free). - [C gets() buffer overflow: no input length limit](https://vetkit.dev/checks/vetkit.c.memory.gets/) (`vetkit.c.memory.gets`): gets() reads a line without any length limit; every call can overflow the destination buffer. - [C buffer overflow: argv or getenv copied with strcpy](https://vetkit.dev/checks/vetkit.c.memory.input-into-fixed-buffer/) (`vetkit.c.memory.input-into-fixed-buffer`): A command-line argument or environment variable is copied into a buffer with strcpy / strcat / sprintf, which does not check the destination size. - [C function returns address of a local stack variable](https://vetkit.dev/checks/vetkit.c.memory.return-local-address/) (`vetkit.c.memory.return-local-address`): A function returns the address of one of its own stack variables; the memory is invalid as soon as the function returns. - [C scanf %s without field width causes buffer overflow](https://vetkit.dev/checks/vetkit.c.memory.scanf-unbounded-string/) (`vetkit.c.memory.scanf-unbounded-string`): A scanf-family call reads a string with %s or %[ and no field width, so long input overflows the buffer. - [C strcpy, strcat and sprintf buffer overflow](https://vetkit.dev/checks/vetkit.c.memory.unbounded-string-copy/) (`vetkit.c.memory.unbounded-string-copy`): strcpy / strcat / sprintf("%s") copies a non-constant string without a destination size, a common source of buffer overflows. - [C use after free: pointer used after free()](https://vetkit.dev/checks/vetkit.c.memory.use-after-free/) (`vetkit.c.memory.use-after-free`): A pointer is dereferenced after it was passed to free() and before it is reassigned (use after free). - [C world-writable file or directory permissions](https://vetkit.dev/checks/vetkit.c.permissions.world-writable/) (`vetkit.c.permissions.world-writable`): A file or directory is made writable by every local user (mode with the other-write bit set). - [C chroot() without chdir("/") allows jail escape](https://vetkit.dev/checks/vetkit.c.privilege.chroot-without-chdir/) (`vetkit.c.privilege.chroot-without-chdir`): chroot() is called without a following chdir("/"); the current directory stays outside the jail, so it can be escaped. - [C unchecked setuid, setgid or setgroups return value](https://vetkit.dev/checks/vetkit.c.privilege.unchecked-setuid/) (`vetkit.c.privilege.unchecked-setuid`): The result of setuid / setgid / setgroups is ignored; if the call fails the program keeps running with elevated privileges. - [C access() then open() TOCTOU race condition](https://vetkit.dev/checks/vetkit.c.race.access-then-open/) (`vetkit.c.race.access-then-open`): A file is checked with access() and then opened by name; the file can be swapped (e.g. for a symlink) between the check and the use. - [C insecure temp file: mktemp, tmpnam and tempnam](https://vetkit.dev/checks/vetkit.c.tempfile.insecure-function/) (`vetkit.c.tempfile.insecure-function`): mktemp / tmpnam / tempnam only return a name; another process can create that file before it is opened (insecure temporary file). - [C libcurl SSL peer and host verification disabled](https://vetkit.dev/checks/vetkit.c.tls.curl-verification-disabled/) (`vetkit.c.tls.curl-verification-disabled`): libcurl peer or host verification is switched off, so the TLS connection can be intercepted (man-in-the-middle). - [C OpenSSL SSL_VERIFY_NONE skips certificate checks](https://vetkit.dev/checks/vetkit.c.tls.openssl-client-verify-none/) (`vetkit.c.tls.openssl-client-verify-none`): A TLS client context is set to SSL_VERIFY_NONE, so the server certificate is not checked (man-in-the-middle). - [Capacitor server.cleartext: true allows cleartext HTTP](https://vetkit.dev/checks/vetkit.capacitor.config.cleartext/) (`vetkit.capacitor.config.cleartext`): The Capacitor config allows cleartext HTTP on Android (`server.cleartext: true`), an option intended for live-reload development. - [Docker Compose cap_add SYS_ADMIN or ALL container escape](https://vetkit.dev/checks/vetkit.compose.container.dangerous-capability/) (`vetkit.compose.container.dangerous-capability`): A Compose service adds a kernel capability that allows escaping the container (ALL, SYS_ADMIN, SYS_MODULE, SYS_PTRACE, SYS_RAWIO, DAC_READ_SEARCH or BPF). - [Docker Compose mounts docker.sock into a container](https://vetkit.dev/checks/vetkit.compose.container.docker-socket/) (`vetkit.compose.container.docker-socket`): A Compose service mounts the Docker daemon socket. Whoever controls this container can drive the Docker API and start a privileged container, which is equivalent to root on the host (a read-only mount does not prevent this). - [Docker Compose shares host PID or IPC namespace](https://vetkit.dev/checks/vetkit.compose.container.host-namespace/) (`vetkit.compose.container.host-namespace`): A Compose service shares the host's PID, IPC or user namespace. The container can see and signal host processes or read host shared memory, which removes an important isolation layer. - [Docker Compose network_mode: host exposes host network](https://vetkit.dev/checks/vetkit.compose.container.host-network/) (`vetkit.compose.container.host-network`): A Compose service uses the host network stack (`network_mode: host`). Every port it opens is exposed directly on the host interfaces and it can reach services bound to the host's loopback address. - [Docker Compose privileged: true container](https://vetkit.dev/checks/vetkit.compose.container.privileged/) (`vetkit.compose.container.privileged`): A Compose service runs a privileged container. `privileged: true` gives the container every kernel capability and access to all host devices, so a compromise of that service is a compromise of the host. - [Docker Compose service runs as user root](https://vetkit.dev/checks/vetkit.compose.container.root-user/) (`vetkit.compose.container.root-user`): A Compose service explicitly runs its process as root (`user: root` / `user: "0"`). A process escape or a writable mount then acts with root privileges. - [Docker Compose writable mount of sensitive host paths](https://vetkit.dev/checks/vetkit.compose.container.sensitive-host-mount/) (`vetkit.compose.container.sensitive-host-mount`): A Compose service mounts a sensitive host directory (/, /etc, /root, /proc, /sys, /dev, /boot, /var/lib/docker…) writable into the container. Writing there lets the container change host configuration or credentials. - [Docker Compose seccomp or AppArmor unconfined profile](https://vetkit.dev/checks/vetkit.compose.container.unconfined-security-profile/) (`vetkit.compose.container.unconfined-security-profile`): A Compose service disables its seccomp, AppArmor or SELinux confinement (`unconfined` / `label:disable`). The container can then use system calls and resources that the default profile blocks to protect the host kernel. - [Docker Compose database or Redis port exposed on host](https://vetkit.dev/checks/vetkit.compose.service.datastore-port-exposed/) (`vetkit.compose.service.datastore-port-exposed`): A Compose service publishes a database or cache port on all host interfaces. Anyone who can reach the machine can talk to the data store directly; this is fine on a developer laptop but dangerous on a server. - [Cordova access origin="*" allows requests to any origin](https://vetkit.dev/checks/vetkit.cordova.config.access-any-origin/) (`vetkit.cordova.config.access-any-origin`): The Cordova network allow-list permits requests to any origin (``). Code injected into the web view can send data anywhere and load scripts from any host. - [Cordova allow-navigation href="*" allows any URL](https://vetkit.dev/checks/vetkit.cordova.config.navigation-any/) (`vetkit.cordova.config.navigation-any`): The Cordova app lets its web view navigate to any URL (``). A malicious page loaded in the app gets access to the native plugin bridge. - [C# Dynamic LINQ injection from request input](https://vetkit.dev/checks/vetkit.csharp.code-injection.dynamic-linq/) (`vetkit.csharp.code-injection.dynamic-linq`): A System.Linq.Dynamic expression string is built from request input. Dynamic LINQ parses and compiles the string, so an attacker can change the query or, on older library versions, invoke arbitrary methods. - [C# command injection via cmd.exe /c, powershell or sh -c](https://vetkit.dev/checks/vetkit.csharp.command-injection.shell-wrapper/) (`vetkit.csharp.command-injection.shell-wrapper`): A shell (cmd.exe /c, powershell -Command, sh -c) is started with a command line built from non-constant values. Shell metacharacters in any of those values run arbitrary commands. - [C# OS command injection: request input in Process.Start](https://vetkit.dev/checks/vetkit.csharp.command-injection.tainted-process/) (`vetkit.csharp.command-injection.tainted-process`): Request input is used as the executable or the argument string of a new process. An attacker can run other programs or inject extra arguments (OS command injection). - [C# cookie HttpOnly = false exposes it to XSS](https://vetkit.dev/checks/vetkit.csharp.cookies.httponly-disabled/) (`vetkit.csharp.cookies.httponly-disabled`): A cookie is explicitly made readable from JavaScript (HttpOnly = false). Any XSS on the site can then steal it. - [C# cookie Secure = false sent over plain HTTP](https://vetkit.dev/checks/vetkit.csharp.cookies.secure-flag-disabled/) (`vetkit.csharp.cookies.secure-flag-disabled`): A cookie is explicitly allowed to be sent over plain HTTP (Secure = false or CookieSecurePolicy.None). Network attackers can read or inject it. - [C# CORS AllowAnyOrigin with AllowCredentials](https://vetkit.dev/checks/vetkit.csharp.cors.any-origin-with-credentials/) (`vetkit.csharp.cors.any-origin-with-credentials`): The CORS policy accepts every origin while allowing credentials. Any website can make authenticated cross-origin requests and read the responses. - [C# block cipher in ECB mode leaks data structure](https://vetkit.dev/checks/vetkit.csharp.crypto.ecb-mode/) (`vetkit.csharp.crypto.ecb-mode`): A block cipher is used in ECB mode. Identical plaintext blocks produce identical ciphertext blocks, which leaks the structure of the data. - [C# hardcoded encryption key in source code](https://vetkit.dev/checks/vetkit.csharp.crypto.hardcoded-key/) (`vetkit.csharp.crypto.hardcoded-key`): A symmetric encryption key is a constant in source code. Anyone who can read the code or the compiled assembly can decrypt the data. - [C# System.Random used to generate tokens and secrets](https://vetkit.dev/checks/vetkit.csharp.crypto.insecure-random-secret/) (`vetkit.csharp.crypto.insecure-random-secret`): System.Random is used to generate a token, password, OTP, salt or key. Its output is predictable, so an attacker can guess the generated secret. - [C# static or zero IV in AES encryption](https://vetkit.dev/checks/vetkit.csharp.crypto.static-iv/) (`vetkit.csharp.crypto.static-iv`): An encryption IV is a constant or all-zero array. Reusing the same IV with the same key makes CBC/CTR/GCM ciphertext predictable or, for GCM/CTR, lets an attacker recover plaintext. - [C# weak cipher: DES, 3DES or RC2](https://vetkit.dev/checks/vetkit.csharp.crypto.weak-cipher/) (`vetkit.csharp.crypto.weak-cipher`): A broken or legacy block cipher (DES, 3DES or RC2) is used. Its small key or block size makes the ciphertext practical to brute-force or attack. - [C# weak hash algorithm: MD5 or SHA-1 for integrity](https://vetkit.dev/checks/vetkit.csharp.crypto.weak-hash/) (`vetkit.csharp.crypto.weak-hash`): MD5 or SHA-1 is used. Both are broken for collision resistance and must not protect integrity, signatures or passwords. - [C# password hashing with MD5, SHA-1 or SHA-2](https://vetkit.dev/checks/vetkit.csharp.crypto.weak-password-hash/) (`vetkit.csharp.crypto.weak-password-hash`): A password is hashed with a single fast hash (MD5, SHA-1 or SHA-2). Fast unsalted hashes are cracked offline at billions of guesses per second. - [C# Rfc2898DeriveBytes PBKDF2 with too few iterations](https://vetkit.dev/checks/vetkit.csharp.crypto.weak-pbkdf2-iterations/) (`vetkit.csharp.crypto.weak-pbkdf2-iterations`): PBKDF2 (Rfc2898DeriveBytes) is used with fewer than 100,000 iterations (the two-argument constructors default to 1,000 iterations of SHA-1). Derived keys and password hashes are cheap to brute-force. - [C# RSA or DSA key smaller than 2048 bits](https://vetkit.dev/checks/vetkit.csharp.crypto.weak-rsa-key/) (`vetkit.csharp.crypto.weak-rsa-key`): An RSA or DSA key smaller than 2048 bits is generated. Such keys are below current minimums and within reach of well-funded factoring attacks. - [C# CSRF: anti-forgery token validation disabled in MVC](https://vetkit.dev/checks/vetkit.csharp.csrf.antiforgery-disabled/) (`vetkit.csharp.csrf.antiforgery-disabled`): Anti-forgery token validation is explicitly disabled for an MVC/Razor endpoint. If the endpoint changes state for a cookie-authenticated user, only the cookie's SameSite setting still stands between it and cross-site request forgery (CSRF). - [C# insecure deserialization with BinaryFormatter](https://vetkit.dev/checks/vetkit.csharp.deserialization.binary-formatter/) (`vetkit.csharp.deserialization.binary-formatter`): Data is deserialized with BinaryFormatter, SoapFormatter, NetDataContractSerializer, LosFormatter or ObjectStateFormatter. These formatters instantiate attacker-chosen types and lead to remote code execution on untrusted input; Microsoft states they cannot be made safe. - [C# XmlSerializer with runtime type name deserialization](https://vetkit.dev/checks/vetkit.csharp.deserialization.dynamic-serializer-type/) (`vetkit.csharp.deserialization.dynamic-serializer-type`): An XmlSerializer / DataContractSerializer is created for a type whose name is resolved at runtime from a non-constant string. If the name comes from the payload or the request, an attacker chooses which type is instantiated (unsafe deserialization). - [C# JavaScriptSerializer SimpleTypeResolver deserialization](https://vetkit.dev/checks/vetkit.csharp.deserialization.javascript-serializer-type-resolver/) (`vetkit.csharp.deserialization.javascript-serializer-type-resolver`): JavaScriptSerializer is created with SimpleTypeResolver, which lets the JSON choose the .NET type to instantiate. Untrusted input leads to remote code execution. - [C# Json.NET TypeNameHandling insecure deserialization](https://vetkit.dev/checks/vetkit.csharp.deserialization.json-type-name-handling/) (`vetkit.csharp.deserialization.json-type-name-handling`): Json.NET TypeNameHandling is enabled without a SerializationBinder. The JSON can then name the .NET type to create, which allows remote code execution through known gadget types when the input is untrusted. - [ASP.NET Core UseDeveloperExceptionPage in production](https://vetkit.dev/checks/vetkit.csharp.info-disclosure.developer-exception-page/) (`vetkit.csharp.info-disclosure.developer-exception-page`): The developer exception page is enabled without an IsDevelopment() check. In production it exposes stack traces, source snippets and configuration details. - [C# JWT hardcoded signing key in source code](https://vetkit.dev/checks/vetkit.csharp.jwt.hardcoded-signing-key/) (`vetkit.csharp.jwt.hardcoded-signing-key`): A JWT signing key is created from a string literal in source code. Anyone with access to the code (or a decompiled binary) can mint valid tokens. - [C# JWT RequireHttpsMetadata = false](https://vetkit.dev/checks/vetkit.csharp.jwt.https-metadata-disabled/) (`vetkit.csharp.jwt.https-metadata-disabled`): JWT/OpenID Connect authentication allows its metadata and signing keys to be fetched over plain HTTP (RequireHttpsMetadata = false) outside a development-only branch. - [C# JWT ValidateIssuer or ValidateAudience disabled](https://vetkit.dev/checks/vetkit.csharp.jwt.issuer-audience-validation-disabled/) (`vetkit.csharp.jwt.issuer-audience-validation-disabled`): JWT issuer or audience validation is disabled. Tokens issued for another application or by another tenant of the same identity provider will be accepted. - [C# JWT ValidateLifetime = false accepts expired tokens](https://vetkit.dev/checks/vetkit.csharp.jwt.lifetime-validation-disabled/) (`vetkit.csharp.jwt.lifetime-validation-disabled`): JWT lifetime validation is disabled (ValidateLifetime = false or RequireExpirationTime = false). Expired or never-expiring tokens are accepted, so a leaked token stays valid forever. - [C# JWT RequireSignedTokens = false accepts forged tokens](https://vetkit.dev/checks/vetkit.csharp.jwt.unsigned-tokens-accepted/) (`vetkit.csharp.jwt.unsigned-tokens-accepted`): JWT validation accepts tokens without a verified signature (RequireSignedTokens = false or a SignatureValidator that returns the token unchecked). Anyone can forge a token. - [C# LDAP injection: request input in a search filter](https://vetkit.dev/checks/vetkit.csharp.ldap-injection.tainted-filter/) (`vetkit.csharp.ldap-injection.tainted-filter`): Request input is placed into an LDAP search filter without escaping. Characters such as `*`, `(` and `)` let an attacker rewrite the filter (LDAP injection). - [C# open redirect: unvalidated redirect URL from request](https://vetkit.dev/checks/vetkit.csharp.open-redirect.tainted-redirect/) (`vetkit.csharp.open-redirect.tainted-redirect`): A redirect target is taken from request input without checking that it is a local URL. An attacker can send users to a phishing site from a link on this domain (open redirect). - [C# path traversal: request input in a file path](https://vetkit.dev/checks/vetkit.csharp.path-traversal.tainted-file-path/) (`vetkit.csharp.path-traversal.tainted-file-path`): A file system path is built from request input (or an uploaded file's client-supplied name). Sequences such as `../` or an absolute path let an attacker read, overwrite or delete files outside the intended directory. - [C# zip slip: archive entry FullName used in extraction path](https://vetkit.dev/checks/vetkit.csharp.path-traversal.zip-slip/) (`vetkit.csharp.path-traversal.zip-slip`): An archive entry's FullName is used to build an extraction path without checking that the result stays inside the target directory (zip slip). A crafted archive can overwrite arbitrary files. - [C# ReDoS: Regex pattern from request without timeout](https://vetkit.dev/checks/vetkit.csharp.redos.tainted-pattern/) (`vetkit.csharp.redos.tainted-pattern`): A regular expression pattern is built from request input and evaluated without a match timeout. A crafted pattern can backtrack catastrophically and exhaust CPU (ReDoS), or change what the expression matches. - [C# hardcoded OAuth client secret (ClientSecret)](https://vetkit.dev/checks/vetkit.csharp.secrets.hardcoded-oauth-client-secret/) (`vetkit.csharp.secrets.hardcoded-oauth-client-secret`): An OAuth / OpenID Connect client secret is a string literal in source code (IdentityServer `new Secret("...".Sha256())` or `ClientSecret = "..."`). Anyone with the code can authenticate as this client, and copies of the sample value tend to reach production. - [C# EF Core FromSqlRaw SQL injection via string building](https://vetkit.dev/checks/vetkit.csharp.sql-injection.ef-raw-sql-string-building/) (`vetkit.csharp.sql-injection.ef-raw-sql-string-building`): The SQL text passed to an EF Core Raw API (FromSqlRaw, ExecuteSqlRaw, SqlQueryRaw) is built with string interpolation, concatenation or string.Format. The Raw APIs run the text as-is, so any value spliced in changes the query (SQL injection); the interpolated overloads exist for exactly this case. - [C# SQL injection: value spliced into quoted SQL literal](https://vetkit.dev/checks/vetkit.csharp.sql-injection.quoted-value-splice/) (`vetkit.csharp.sql-injection.quoted-value-splice`): A SQL statement embeds a value inside quotes through string interpolation, concatenation or string.Format before it is executed. Any quote in the value breaks out of the literal, which is SQL injection. - [C# SQL injection: request input in ADO.NET or Dapper query](https://vetkit.dev/checks/vetkit.csharp.sql-injection.tainted-query/) (`vetkit.csharp.sql-injection.tainted-query`): Request input flows into the text of a SQL command (ADO.NET, EF raw SQL or Dapper). An attacker can change the structure of the query, which is SQL injection. - [C# SSRF: HTTP request to a URL built from request input](https://vetkit.dev/checks/vetkit.csharp.ssrf.tainted-url/) (`vetkit.csharp.ssrf.tainted-url`): An outbound HTTP request is sent to a URL built from request input. An attacker can make the server call internal services or cloud metadata endpoints (server-side request forgery). - [C# TLS certificate validation disabled, callback returns true](https://vetkit.dev/checks/vetkit.csharp.tls.certificate-validation-disabled/) (`vetkit.csharp.tls.certificate-validation-disabled`): TLS server certificate validation is disabled with a callback that always returns true (or DangerousAcceptAnyServerCertificateValidator). Any machine-in-the-middle can impersonate the server. - [C# SSL 3.0, TLS 1.0 or TLS 1.1 enabled](https://vetkit.dev/checks/vetkit.csharp.tls.legacy-protocol/) (`vetkit.csharp.tls.legacy-protocol`): SSL 3.0, TLS 1.0 or TLS 1.1 is explicitly enabled. These protocol versions are deprecated (RFC 8996) and vulnerable to downgrade and padding-oracle attacks. - [C# unsafe reflection: type or assembly from request input](https://vetkit.dev/checks/vetkit.csharp.unsafe-reflection.tainted-type-or-assembly/) (`vetkit.csharp.unsafe-reflection.tainted-type-or-assembly`): A type name or assembly is loaded from request input. An attacker can instantiate arbitrary types (deserialization-style gadgets) or load attacker-supplied code. - [C# XPath injection: request input in an XPath expression](https://vetkit.dev/checks/vetkit.csharp.xpath-injection.tainted-expression/) (`vetkit.csharp.xpath-injection.tainted-expression`): An XPath expression is built from request input or by splicing a value into a quoted literal. An attacker can change the query and read or bypass checks on other parts of the XML document (XPath injection). - [ASP.NET MVC [ValidateInput(false)] disables validation (XSS)](https://vetkit.dev/checks/vetkit.csharp.xss.request-validation-disabled/) (`vetkit.csharp.xss.request-validation-disabled`): ASP.NET request validation is disabled with [ValidateInput(false)]. Markup in form and query values reaches the action unfiltered, so every output path must encode it correctly. - [C# XSS: request input in Html.Raw or Response.Write](https://vetkit.dev/checks/vetkit.csharp.xss.tainted-html-output/) (`vetkit.csharp.xss.tainted-html-output`): Request input is written to the response as raw HTML (Html.Raw, HtmlString, MarkupString, Response.Write or text/html content) without encoding. This is cross-site scripting. - [C# XXE: XML reader with DTD processing enabled](https://vetkit.dev/checks/vetkit.csharp.xxe.dtd-processing-enabled/) (`vetkit.csharp.xxe.dtd-processing-enabled`): DTD processing is explicitly enabled for an XML reader. Parsing untrusted XML with DTDs enabled allows entity-expansion denial of service and, together with a resolver, XML external entity (XXE) attacks. - [C# XXE: XmlUrlResolver attached to an XML parser](https://vetkit.dev/checks/vetkit.csharp.xxe.url-resolver-enabled/) (`vetkit.csharp.xxe.url-resolver-enabled`): An XmlUrlResolver is attached to an XML parser. With DTD processing on (the default for XmlDocument on .NET Framework before 4.5.2), external entities can read local files or make network requests (XXE). - [C# XSLT enableScript or document() enabled (XXE)](https://vetkit.dev/checks/vetkit.csharp.xxe.xslt-script-or-document-enabled/) (`vetkit.csharp.xxe.xslt-script-or-document-enabled`): XSLT embedded scripts or the document() function are enabled. A malicious stylesheet can then run code or read arbitrary files and URLs. - [Sequelize sync force:true and TypeORM dropSchema drop tables](https://vetkit.dev/checks/vetkit.data-access.destructive-schema-sync/) (`vetkit.data-access.destructive-schema-sync`): The application drops and recreates database tables when it starts: Sequelize `sync({ force: true })` runs DROP TABLE for every model, and TypeORM `dropSchema: true` drops the schema on each connection. A restart or deploy in production deletes all data. The application drops all tables (SQLAlchemy `metadata.drop_all` / Flask-SQLAlchemy `db.drop_all()`) in application code. When this runs on start-up or from a request, a restart or deploy in production deletes all data. - [Sequelize sync({ alter: true }) alters tables on startup](https://vetkit.dev/checks/vetkit.data-access.destructive-schema-sync.alter/) (`vetkit.data-access.destructive-schema-sync.alter`): The application alters database tables to match its models every time it starts (Sequelize `sync({ alter: true })`). Schema changes made this way are not reviewed or versioned and can drop or rewrite columns and data when a model changes; on a large table the ALTER also locks it during a deploy. - [TypeORM synchronize: true changes the schema on startup](https://vetkit.dev/checks/vetkit.data-access.destructive-schema-sync.typeorm/) (`vetkit.data-access.destructive-schema-sync.typeorm`): TypeORM `synchronize: true` is set unconditionally, so every application start changes the database schema to match the entities. Renaming or removing a property drops the column and its data in production, without a reviewed migration. - [N+1 query: database query inside a loop](https://vetkit.dev/checks/vetkit.data-access.query-in-loop/) (`vetkit.data-access.query-in-loop`): A database query runs inside a loop, once per item (the N+1 query pattern). The number of round trips grows with the data, so code that is fast on a development database becomes slow and holds connections for longer once real tables and lists grow. - [N+1 query: Promise.all(items.map(...)) database reads](https://vetkit.dev/checks/vetkit.data-access.query-in-loop.concurrent/) (`vetkit.data-access.query-in-loop.concurrent`): One database read is started per item with Promise.all(items.map(...)) (the N+1 query pattern, run concurrently). The page is not slower for short lists, but a long list opens as many queries at once: they queue for the connection pool and add database load proportional to the list size. - [N+1 query: model query inside a loop in JS and TypeScript](https://vetkit.dev/checks/vetkit.data-access.query-in-loop.model/) (`vetkit.data-access.query-in-loop.model`): A database query runs inside a loop, once per item (the N+1 query pattern). The number of round trips grows with the data, so code that is fast on a development database becomes slow and holds connections for longer once real collections and lists grow. - [N+1 query: database query inside a while loop](https://vetkit.dev/checks/vetkit.data-access.query-in-loop.while/) (`vetkit.data-access.query-in-loop.while`): A database query runs inside a loop, once per iteration (the N+1 query pattern). The number of round trips grows with the data, so code that is fast on a development database becomes slow and holds connections for longer once real tables and lists grow. - [Unpaginated list endpoint: GET query without a row limit](https://vetkit.dev/checks/vetkit.data-access.unpaginated-list-endpoint/) (`vetkit.data-access.unpaginated-list-endpoint`): A GET endpoint returns the result of a list query that has no row limit. Every request loads and serialises the whole table (or everything matching the filter), so response time, memory use and database load grow without bound as the data grows, and one request can be enough to slow the service down. - [Unpaginated GET endpoint: model list query without limit](https://vetkit.dev/checks/vetkit.data-access.unpaginated-list-endpoint.model/) (`vetkit.data-access.unpaginated-list-endpoint.model`): A GET endpoint returns the result of a list query that has no row limit. Every request loads and serialises the whole collection (or everything matching the filter), so response time, memory use and database load grow without bound as the data grows, and one request can be enough to slow the service down. - [Elasticsearch xpack.security.enabled: false](https://vetkit.dev/checks/vetkit.elasticsearch.security.disabled/) (`vetkit.elasticsearch.security.disabled`): Elasticsearch security is turned off (`xpack.security.enabled: false`). The cluster accepts requests without authentication or TLS, so anyone who can reach it can read, change or delete all indices. - [Expo usesCleartextTraffic allows cleartext HTTP on Android](https://vetkit.dev/checks/vetkit.expo.config.android-cleartext/) (`vetkit.expo.config.android-cleartext`): The Expo app config enables cleartext HTTP on Android (`usesCleartextTraffic: true`), so the release app may talk to servers over unencrypted connections. - [Expo NSAllowsArbitraryLoads disables iOS ATS for HTTP](https://vetkit.dev/checks/vetkit.expo.config.ios-arbitrary-loads/) (`vetkit.expo.config.ios-arbitrary-loads`): The Expo app config disables App Transport Security on iOS (`NSAllowsArbitraryLoads: true` in `infoPlist`), so the app may load content over plain HTTP. - [Firebase Realtime Database .read true exposes whole database](https://vetkit.dev/checks/vetkit.firebase.database.public-read-root/) (`vetkit.firebase.database.public-read-root`): A Firebase Realtime Database rule sets `.read` to true at the database root. Anyone with the public database URL can download the entire database. - [Firebase Realtime Database .write true allows public writes](https://vetkit.dev/checks/vetkit.firebase.database.public-write/) (`vetkit.firebase.database.public-write`): A Firebase Realtime Database rule sets `.write` to true. Anyone with the public database URL can write, overwrite or delete this part of the database. - [Firebase rules: request.auth != null grants full access](https://vetkit.dev/checks/vetkit.firebase.rules.any-user-full-access/) (`vetkit.firebase.rules.any-user-full-access`): A Firestore / Cloud Storage security rule gives every signed-in user write access to all data under a recursive wildcard match (`if request.auth != null`). With anonymous or open sign-up, anyone can read and overwrite other users' data. - [Firebase Firestore and Storage rules allow public read of all](https://vetkit.dev/checks/vetkit.firebase.rules.public-read-all/) (`vetkit.firebase.rules.public-read-all`): A Firestore / Cloud Storage rule lets anyone read everything under a recursive wildcard match (`{document=**}` / `{allPaths=**}`) without a condition. - [Firebase Firestore and Storage rules allow public write](https://vetkit.dev/checks/vetkit.firebase.rules.public-write/) (`vetkit.firebase.rules.public-write`): A Firestore / Cloud Storage security rule allows writes without any condition (`if true` or no condition). Anyone on the internet can create, modify or delete this data with the public Firebase config. - [Firebase security rules left in test mode (request.time)](https://vetkit.dev/checks/vetkit.firebase.rules.test-mode/) (`vetkit.firebase.rules.test-mode`): A Firestore / Cloud Storage security rule only checks the current date (`request.time < timestamp.date(...)`), the console's "test mode". Until that date anyone can read and write the data; after it, the app stops working. - [Go command injection: request input picks the program](https://vetkit.dev/checks/vetkit.go.command-injection.request-input/) (`vetkit.go.command-injection.request-input`): The program to execute is chosen by request input, letting a client run arbitrary commands. - [Go command injection via sh -c or bash -c exec.Command](https://vetkit.dev/checks/vetkit.go.command-injection.shell/) (`vetkit.go.command-injection.shell`): A shell (`sh -c` / `bash -c`) executes a dynamically built command string (command injection). - [Go cookie with HttpOnly set to false readable by scripts](https://vetkit.dev/checks/vetkit.go.cookie.httponly-disabled/) (`vetkit.go.cookie.httponly-disabled`): A cookie is created with HttpOnly explicitly off, so page scripts (and any XSS payload) can read it. - [Go cookie with Secure flag disabled sent over plain HTTP](https://vetkit.dev/checks/vetkit.go.cookie.secure-disabled/) (`vetkit.go.cookie.secure-disabled`): A cookie is created with the Secure flag explicitly off, so browsers also send it over plain HTTP. - [Go CORS allows all origins with credentials enabled](https://vetkit.dev/checks/vetkit.go.cors.permissive-with-credentials/) (`vetkit.go.cors.permissive-with-credentials`): CORS allows every origin together with credentials. Any website can then make authenticated requests on behalf of a signed-in user and read the responses. - [Go block cipher in ECB mode leaks plaintext structure](https://vetkit.dev/checks/vetkit.go.crypto.ecb-mode/) (`vetkit.go.crypto.ecb-mode`): A block cipher encrypts data block by block in a loop (ECB mode). Equal plaintext blocks produce equal ciphertext blocks, which leaks the structure of the data. - [Go hardcoded cipher, MAC or session cookie key](https://vetkit.dev/checks/vetkit.go.crypto.hardcoded-key/) (`vetkit.go.crypto.hardcoded-key`): A cipher, MAC or session-cookie key is a string literal compiled into the program. - [Go math/rand used for security-sensitive tokens](https://vetkit.dev/checks/vetkit.go.crypto.insecure-random-token/) (`vetkit.go.crypto.insecure-random-token`): math/rand is used to produce a security-sensitive value; it is predictable. - [Go static or zero IV and nonce reuse in encryption](https://vetkit.dev/checks/vetkit.go.crypto.static-iv/) (`vetkit.go.crypto.static-iv`): A cipher is initialised with a constant or all-zero IV / nonce. Reusing an IV under one key reveals plaintext relationships and, for GCM and CTR, breaks confidentiality and authenticity. - [Go timing attack: MAC compared with == or bytes.Equal](https://vetkit.dev/checks/vetkit.go.crypto.timing-unsafe-compare/) (`vetkit.go.crypto.timing-unsafe-compare`): A MAC or signature is compared with == / bytes.Equal, which returns as soon as a byte differs. Response-time differences let a client guess the value byte by byte. - [Go weak cipher: DES, 3DES or RC4 encryption](https://vetkit.dev/checks/vetkit.go.crypto.weak-cipher/) (`vetkit.go.crypto.weak-cipher`): DES, 3DES or RC4 is used for encryption; these ciphers are broken or have a 64-bit block size. - [Go weak bcrypt cost or PBKDF2 iteration count](https://vetkit.dev/checks/vetkit.go.crypto.weak-kdf-cost/) (`vetkit.go.crypto.weak-kdf-cost`): A password hash is computed with a work factor below the accepted minimum (bcrypt cost under 10 or PBKDF2 under 10000 iterations). - [Go weak password hashing with MD5 or SHA-1](https://vetkit.dev/checks/vetkit.go.crypto.weak-password-hash/) (`vetkit.go.crypto.weak-password-hash`): A password or secret is hashed with MD5/SHA-1. - [Go RSA key shorter than 2048 bits](https://vetkit.dev/checks/vetkit.go.crypto.weak-rsa-key/) (`vetkit.go.crypto.weak-rsa-key`): An RSA key shorter than 2048 bits is generated; such keys can be factored with modest resources. - [Go signature over an MD5 or SHA-1 digest](https://vetkit.dev/checks/vetkit.go.crypto.weak-signature-hash/) (`vetkit.go.crypto.weak-signature-hash`): A signature is created or verified over an MD5 / SHA-1 digest, which is not collision resistant. - [Go net/http/pprof exposed on DefaultServeMux](https://vetkit.dev/checks/vetkit.go.debug.pprof-exposed/) (`vetkit.go.debug.pprof-exposed`): net/http/pprof is blank-imported, which registers the /debug/pprof handlers on http.DefaultServeMux. If that mux is served publicly, anyone can dump goroutines, heap contents and CPU profiles. - [Go HTTP server without timeouts: Slowloris denial of service](https://vetkit.dev/checks/vetkit.go.http.server-without-timeouts/) (`vetkit.go.http.server-without-timeouts`): An HTTP server is started without read timeouts, so slow clients can hold connections open indefinitely (Slowloris denial of service). - [Go integer overflow from truncating conversion after parse](https://vetkit.dev/checks/vetkit.go.integer.truncating-conversion/) (`vetkit.go.integer.truncating-conversion`): A number parsed from a string as a full-width integer is converted to a narrower type without a range check. Out-of-range input silently wraps around, which can bypass size or bounds checks. - [Go JWT signed with a hardcoded secret key](https://vetkit.dev/checks/vetkit.go.jwt.hardcoded-secret/) (`vetkit.go.jwt.hardcoded-secret`): A JWT is signed with a hard-coded key. - [Go JWT none algorithm accepts unsigned tokens](https://vetkit.dev/checks/vetkit.go.jwt.none-algorithm/) (`vetkit.go.jwt.none-algorithm`): The JWT "none" algorithm is used, producing or accepting tokens without a signature. - [Go JWT ParseUnverified skips signature validation](https://vetkit.dev/checks/vetkit.go.jwt.parse-unverified/) (`vetkit.go.jwt.parse-unverified`): A JWT is decoded with ParseUnverified, which skips signature validation. - [Go open redirect: redirect target from request input](https://vetkit.dev/checks/vetkit.go.open-redirect.request-input/) (`vetkit.go.open-redirect.request-input`): Redirect target comes from request input (open redirect). - [Go Zip Slip path traversal in archive extraction](https://vetkit.dev/checks/vetkit.go.path-traversal.archive-extraction/) (`vetkit.go.path-traversal.archive-extraction`): An archive entry name is joined into the extraction path without checking that the result stays inside the destination (Zip Slip). An entry named `../../x` is written outside the target directory. - [Go path traversal: file path built from request input](https://vetkit.dev/checks/vetkit.go.path-traversal.request-input/) (`vetkit.go.path-traversal.request-input`): A filesystem path is built from request input without confining it to a base directory (path traversal). `../` segments let a client read or overwrite files outside the intended folder. - [Go world-writable file permissions with chmod or WriteFile](https://vetkit.dev/checks/vetkit.go.permissions.world-writable-chmod/) (`vetkit.go.permissions.world-writable-chmod`): A file or directory is made writable by every local user (mode with the other-write bit set). - [Go defer inside a loop delays cleanup until function returns](https://vetkit.dev/checks/vetkit.go.quality.defer-in-loop/) (`vetkit.go.quality.defer-in-loop`): defer inside a loop runs only when the surrounding function returns, not at the end of each iteration. Resources such as files or locks pile up until then. - [Go empty if err != nil block silently ignores error](https://vetkit.dev/checks/vetkit.go.quality.empty-error-check/) (`vetkit.go.quality.empty-error-check`): The error is checked but the branch is empty, so the failure is silently ignored. - [Go errors.New(fmt.Sprintf(...)) instead of fmt.Errorf](https://vetkit.dev/checks/vetkit.go.quality.errors-new-sprintf/) (`vetkit.go.quality.errors-new-sprintf`): errors.New(fmt.Sprintf(...)) is a roundabout fmt.Errorf(...) and cannot wrap errors with %w. - [Go expression with identical operands on both sides](https://vetkit.dev/checks/vetkit.go.quality.identical-operands/) (`vetkit.go.quality.identical-operands`): Both operands are identical, so the expression is constant. This is almost always a copy-paste mistake. - [Go variable assigned to itself (self-assignment)](https://vetkit.dev/checks/vetkit.go.quality.self-assignment/) (`vetkit.go.quality.self-assignment`): A variable is assigned to itself. This has no effect and usually indicates a typo. - [Go ORM SQL injection in Where, Order, Group or Joins](https://vetkit.dev/checks/vetkit.go.sql-injection.orm-request-input/) (`vetkit.go.sql-injection.orm-request-input`): Request input is placed into the SQL text of an ORM query fragment instead of being bound as a parameter (SQL injection). Affected methods include Where, Order, Group, Joins and Having. - [Go SQL injection from fmt.Sprintf or string concatenation](https://vetkit.dev/checks/vetkit.go.sql-injection.string-building/) (`vetkit.go.sql-injection.string-building`): SQL query text is built with fmt.Sprintf or string concatenation, enabling SQL injection. - [Go SSH InsecureIgnoreHostKey allows man-in-the-middle](https://vetkit.dev/checks/vetkit.go.ssh.insecure-ignore-host-key/) (`vetkit.go.ssh.insecure-ignore-host-key`): The SSH client accepts any host key, so the connection can be intercepted (man-in-the-middle). - [Go SSRF: outbound HTTP request URL from request input](https://vetkit.dev/checks/vetkit.go.ssrf.request-input/) (`vetkit.go.ssrf.request-input`): An outbound HTTP request URL is taken from request input (server-side request forgery). - [Go predictable temp file path in shared temp directory](https://vetkit.dev/checks/vetkit.go.tempfile.predictable-path/) (`vetkit.go.tempfile.predictable-path`): A file with a fixed name is created in the shared temp directory. Another local user can pre-create it or plant a symlink there to hijack or corrupt the write. - [Go server-side template injection from request input](https://vetkit.dev/checks/vetkit.go.template-injection.request-input/) (`vetkit.go.template-injection.request-input`): Request input is parsed as template source (server-side template injection). A client can read any field and call any exported method of the data passed to Execute. - [Go tls.Config InsecureSkipVerify disables certificate checks](https://vetkit.dev/checks/vetkit.go.tls.insecure-skip-verify/) (`vetkit.go.tls.insecure-skip-verify`): tls.Config sets InsecureSkipVerify, disabling certificate validation. - [Go TLS weak cipher suites: RC4, 3DES, NULL or export](https://vetkit.dev/checks/vetkit.go.tls.weak-cipher-suite/) (`vetkit.go.tls.weak-cipher-suite`): The TLS cipher suite list enables RC4, 3DES, NULL or export-grade suites. - [Go tls.Config allows SSL 3.0, TLS 1.0 and TLS 1.1](https://vetkit.dev/checks/vetkit.go.tls.weak-min-version/) (`vetkit.go.tls.weak-min-version`): tls.Config allows SSL 3.0 / TLS 1.0 / TLS 1.1, protocol versions with known attacks (POODLE, BEAST). - [Go WebSocket upgrader CheckOrigin accepts any origin](https://vetkit.dev/checks/vetkit.go.websocket.permissive-origin-check/) (`vetkit.go.websocket.permissive-origin-check`): The WebSocket upgrader accepts connections from any origin, so a page on any website can open an authenticated socket with the visitor's cookies (cross-site WebSocket hijacking). - [Go reflected XSS: request input in HTML response](https://vetkit.dev/checks/vetkit.go.xss.reflected-response/) (`vetkit.go.xss.reflected-response`): Request input is written into an HTML response without escaping (reflected cross-site scripting). - [Go XSS: request input cast to template.HTML](https://vetkit.dev/checks/vetkit.go.xss.template-html/) (`vetkit.go.xss.template-html`): Request input is converted to template.HTML, bypassing html/template escaping (cross-site scripting). - [Go XSS: request input cast to template.JS, URL or CSS](https://vetkit.dev/checks/vetkit.go.xss.template-trusted-type/) (`vetkit.go.xss.template-trusted-type`): Request input is cast to a trusted html/template type, which switches off contextual escaping for it (cross-site scripting). Affected types are template.JS, URL, HTMLAttr, CSS, JSStr and Srcset. - [Go XSS: HTML rendered with text/template, no escaping](https://vetkit.dev/checks/vetkit.go.xss.text-template-html/) (`vetkit.go.xss.text-template-html`): An HTML page is rendered with text/template, which performs no escaping (cross-site scripting). - [Grafana anonymous access enabled with Admin or Editor role](https://vetkit.dev/checks/vetkit.grafana.auth.anonymous-privileged/) (`vetkit.grafana.auth.anonymous-privileged`): Grafana anonymous access is enabled with the Admin or Editor role. Anyone who can reach Grafana can change dashboards and data sources and query every connected database. - [Grafana default admin password left as admin](https://vetkit.dev/checks/vetkit.grafana.auth.default-admin-password/) (`vetkit.grafana.auth.default-admin-password`): Grafana's admin password is set to the well-known default `admin`. Unless it is changed on first login, anyone can sign in as administrator. - [iOS NSAllowsArbitraryLoads disables App Transport Security](https://vetkit.dev/checks/vetkit.ios.ats.arbitrary-loads/) (`vetkit.ios.ats.arbitrary-loads`): App Transport Security is disabled for all connections (`NSAllowsArbitraryLoads` = true). The app may load content over plain HTTP or weak TLS, exposing data to network attackers. - [iOS NSAllowsArbitraryLoadsInWebContent and ForMedia enabled](https://vetkit.dev/checks/vetkit.ios.ats.arbitrary-loads-web-media/) (`vetkit.ios.ats.arbitrary-loads-web-media`): App Transport Security is disabled for web views or media content. With `NSAllowsArbitraryLoadsInWebContent` / `NSAllowsArbitraryLoadsForMedia` that content may be loaded over plain HTTP. - [iOS NSExceptionAllowsInsecureHTTPLoads allows plain HTTP](https://vetkit.dev/checks/vetkit.ios.ats.insecure-http-exception/) (`vetkit.ios.ats.insecure-http-exception`): An App Transport Security domain exception allows plain HTTP (`NSExceptionAllowsInsecureHTTPLoads` = true) for that host. - [iOS ATS exception allows legacy TLS 1.0 or 1.1](https://vetkit.dev/checks/vetkit.ios.ats.legacy-tls/) (`vetkit.ios.ats.legacy-tls`): An App Transport Security exception lowers the minimum TLS version to 1.0 or 1.1 for a host. These versions are deprecated (RFC 8996) and weaken the connection. - [iOS get-task-allow entitlement in a release build](https://vetkit.dev/checks/vetkit.ios.entitlements.get-task-allow/) (`vetkit.ios.entitlements.get-task-allow`): A non-debug entitlements file grants `get-task-allow`. Builds signed with it let other processes attach a debugger and read or modify the app's memory. - [Android WebView setAllowFileAccess(true) enabled](https://vetkit.dev/checks/vetkit.java.android.webview-file-access/) (`vetkit.java.android.webview-file-access`): A WebView explicitly enables access to the local file system. - [Android WebView onReceivedSslError calls proceed()](https://vetkit.dev/checks/vetkit.java.android.webview-ignores-ssl-errors/) (`vetkit.java.android.webview-ignores-ssl-errors`): A WebView proceeds past TLS certificate errors (onReceivedSslError calls proceed()). - [Android WebView addJavascriptInterface with JavaScript on](https://vetkit.dev/checks/vetkit.java.android.webview-javascript-interface/) (`vetkit.java.android.webview-javascript-interface`): A JavaScript bridge is added to a WebView with JavaScript enabled; any page it loads can call the exposed Java methods. - [Android WebView setAllowUniversalAccessFromFileURLs enabled](https://vetkit.dev/checks/vetkit.java.android.webview-universal-file-access/) (`vetkit.java.android.webview-universal-file-access`): A WebView lets file:// pages read other files or any origin (setAllowUniversalAccessFromFileURLs/setAllowFileAccessFromFileURLs). - [Android MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE files](https://vetkit.dev/checks/vetkit.java.android.world-accessible-mode/) (`vetkit.java.android.world-accessible-mode`): A file, database or SharedPreferences is created world-readable or world-writable. - [Java expression injection: SpEL, OGNL, MVEL, JEXL or EL](https://vetkit.dev/checks/vetkit.java.code-injection.expression-language/) (`vetkit.java.code-injection.expression-language`): Request data is evaluated as an expression (SpEL/OGNL/MVEL/JEXL/EL), which allows remote code execution. - [Java code injection: request data in ScriptEngine or Groovy](https://vetkit.dev/checks/vetkit.java.code-injection.script-engine/) (`vetkit.java.code-injection.script-engine`): Request data is executed as a script (ScriptEngine/Groovy), which allows remote code execution. - [Java ProcessBuilder command injection from request data](https://vetkit.dev/checks/vetkit.java.command-injection.process-builder/) (`vetkit.java.command-injection.process-builder`): The program or the argument list of a started process comes from request data (command injection). - [Java Runtime.exec command injection from dynamic string](https://vetkit.dev/checks/vetkit.java.command-injection.runtime-exec/) (`vetkit.java.command-injection.runtime-exec`): An OS command is executed from a dynamically built string or through a shell (command injection). - [Java cookie with Secure or HttpOnly flag disabled](https://vetkit.dev/checks/vetkit.java.cookie.insecure-flags/) (`vetkit.java.cookie.insecure-flags`): A cookie explicitly disables its Secure or HttpOnly flag. - [Java session cookie missing the HttpOnly flag](https://vetkit.dev/checks/vetkit.java.cookie.missing-httponly/) (`vetkit.java.cookie.missing-httponly`): A session or authentication cookie is sent without the HttpOnly flag, so script injected into the page can read it. - [Java CORS reflects Origin header with credentials allowed](https://vetkit.dev/checks/vetkit.java.cors.reflected-origin/) (`vetkit.java.cors.reflected-origin`): The request's Origin header is reflected into Access-Control-Allow-Origin while Access-Control-Allow-Credentials is true, so any website can make credentialed cross-origin requests and read the responses. - [Java AES ECB mode (default Cipher AES) leaks patterns](https://vetkit.dev/checks/vetkit.java.crypto.ecb-mode/) (`vetkit.java.crypto.ecb-mode`): A block cipher is used in ECB mode (explicitly or as the `"AES"` default), which leaks plaintext patterns. - [Java hardcoded cryptographic key in source code](https://vetkit.dev/checks/vetkit.java.crypto.hardcoded-key/) (`vetkit.java.crypto.hardcoded-key`): A cryptographic key is hard-coded in the source code. - [Java insecure random for tokens, passwords and session IDs](https://vetkit.dev/checks/vetkit.java.crypto.insecure-random-token/) (`vetkit.java.crypto.insecure-random-token`): A security-sensitive value (token, password, session id, nonce, salt) is generated with a predictable random number generator. - [Java SecureRandom seeded with a constant value](https://vetkit.dev/checks/vetkit.java.crypto.predictable-secure-random-seed/) (`vetkit.java.crypto.predictable-secure-random-seed`): SecureRandom is seeded with a constant value, which can make its output predictable. - [Java RSA encryption without OAEP padding (PKCS#1 v1.5)](https://vetkit.dev/checks/vetkit.java.crypto.rsa-without-oaep/) (`vetkit.java.crypto.rsa-without-oaep`): RSA encryption uses PKCS#1 v1.5 or no padding instead of OAEP. - [Java static IV or nonce used for encryption](https://vetkit.dev/checks/vetkit.java.crypto.static-iv/) (`vetkit.java.crypto.static-iv`): A constant initialization vector/nonce is used for encryption. - [Java weak cipher: DES, 3DES, RC2, RC4 or Blowfish](https://vetkit.dev/checks/vetkit.java.crypto.weak-cipher/) (`vetkit.java.crypto.weak-cipher`): A broken or weak cipher (DES, 3DES, RC2, RC4, Blowfish) is used. - [Java weak hash: MD5 or SHA-1 MessageDigest](https://vetkit.dev/checks/vetkit.java.crypto.weak-hash/) (`vetkit.java.crypto.weak-hash`): MD5/SHA-1 is cryptographically broken; do not use it for signatures, integrity or passwords. - [Java password hashed with MD5 or SHA instead of bcrypt](https://vetkit.dev/checks/vetkit.java.crypto.weak-password-hash/) (`vetkit.java.crypto.weak-password-hash`): A password is hashed with a fast general-purpose digest (MD5/SHA family) instead of a password hashing function. - [Java PBKDF2 with fewer than 10,000 iterations](https://vetkit.dev/checks/vetkit.java.crypto.weak-pbkdf2-iterations/) (`vetkit.java.crypto.weak-pbkdf2-iterations`): A password-based key derivation uses fewer than 10,000 iterations. - [Java RSA, DSA or DH key under 2048 bits](https://vetkit.dev/checks/vetkit.java.crypto.weak-rsa-key/) (`vetkit.java.crypto.weak-rsa-key`): An RSA/DSA/DH key pair is generated with fewer than 2048 bits. - [Java Jackson default typing: unsafe deserialization](https://vetkit.dev/checks/vetkit.java.deserialization.jackson-default-typing/) (`vetkit.java.deserialization.jackson-default-typing`): Jackson polymorphic typing accepts arbitrary class names from JSON input (unsafe deserialization). - [Java Kryo setRegistrationRequired(false) deserialization](https://vetkit.dev/checks/vetkit.java.deserialization.kryo-unregistered/) (`vetkit.java.deserialization.kryo-unregistered`): Kryo class registration is disabled, so serialized input can instantiate arbitrary classes. - [Java insecure deserialization with ObjectInputStream](https://vetkit.dev/checks/vetkit.java.deserialization.object-input-stream/) (`vetkit.java.deserialization.object-input-stream`): Java native deserialization (ObjectInputStream/XMLDecoder) of untrusted data can lead to remote code execution. - [Java SnakeYAML unsafe load of request data](https://vetkit.dev/checks/vetkit.java.deserialization.snakeyaml-unsafe-load/) (`vetkit.java.deserialization.snakeyaml-unsafe-load`): Request data is loaded with a default SnakeYAML constructor, which instantiates arbitrary classes in SnakeYAML 1.x. - [Java XStream deserialization without a type allow-list](https://vetkit.dev/checks/vetkit.java.deserialization.xstream-no-allowlist/) (`vetkit.java.deserialization.xstream-no-allowlist`): XStream deserializes XML without a type allow-list, which can lead to remote code execution. - [Java JNDI injection: lookup name from request data](https://vetkit.dev/checks/vetkit.java.jndi-injection.context-lookup/) (`vetkit.java.jndi-injection.context-lookup`): A JNDI lookup name comes from request data (JNDI injection, can load remote classes). - [Java JWT signed or verified with a hardcoded secret](https://vetkit.dev/checks/vetkit.java.jwt.hardcoded-secret/) (`vetkit.java.jwt.hardcoded-secret`): A JWT is signed or verified with a hard-coded secret. - [Java jjwt parse() accepts unsigned JWT tokens](https://vetkit.dev/checks/vetkit.java.jwt.parse-accepts-unsigned/) (`vetkit.java.jwt.parse-accepts-unsigned`): A JWT is parsed with jjwt's generic `parse()`, which in jjwt < 0.12 also accepts unsigned tokens. - [Java JWT accepted without signature verification](https://vetkit.dev/checks/vetkit.java.jwt.signature-not-verified/) (`vetkit.java.jwt.signature-not-verified`): A JWT is accepted without signature verification (unsigned/`none` algorithm tokens). - [Java LDAP injection in search filter from request data](https://vetkit.dev/checks/vetkit.java.ldap-injection.search-filter/) (`vetkit.java.ldap-injection.search-filter`): An LDAP search filter is built from request data (LDAP injection). - [Java Spring open redirect from request data](https://vetkit.dev/checks/vetkit.java.open-redirect.spring/) (`vetkit.java.open-redirect.spring`): A redirect target is built from request data (open redirect). - [Java servlet unvalidated forward exposes WEB-INF resources](https://vetkit.dev/checks/vetkit.java.open-redirect.unvalidated-forward/) (`vetkit.java.open-redirect.unvalidated-forward`): A servlet forward/include target is built from request data (unvalidated forward); it can reach any resource in the web application, including `/WEB-INF/`. - [Java path traversal: file path built from request data](https://vetkit.dev/checks/vetkit.java.path-traversal.request-file-path/) (`vetkit.java.path-traversal.request-file-path`): A file system path is built from request data, allowing path traversal (`../`) outside the intended directory. - [Java Zip Slip path traversal in archive extraction](https://vetkit.dev/checks/vetkit.java.path-traversal.zip-slip/) (`vetkit.java.path-traversal.zip-slip`): An archive entry name is used as an output path without checking that it stays inside the target directory (zip slip). - [Java catch Throwable or Error swallows OutOfMemoryError](https://vetkit.dev/checks/vetkit.java.quality.catch-throwable/) (`vetkit.java.quality.catch-throwable`): Catching Throwable or Error also catches OutOfMemoryError, StackOverflowError and other conditions the application cannot recover from. - [Java empty catch block silently discards exceptions](https://vetkit.dev/checks/vetkit.java.quality.empty-catch/) (`vetkit.java.quality.empty-catch`): Empty catch block. The exception is silently discarded, which hides failures and makes bugs hard to diagnose. - [Java printStackTrace() bypasses the logging framework](https://vetkit.dev/checks/vetkit.java.quality.print-stack-trace/) (`vetkit.java.quality.print-stack-trace`): printStackTrace() writes to stderr and bypasses the logging framework; it may also leak internals. - [Java variable assigned to itself, missing this prefix](https://vetkit.dev/checks/vetkit.java.quality.self-assignment/) (`vetkit.java.quality.self-assignment`): A variable is assigned to itself. This has no effect and usually indicates a missing `this.`. - [Java string comparison with == instead of equals](https://vetkit.dev/checks/vetkit.java.quality.string-reference-equality/) (`vetkit.java.quality.string-reference-equality`): Strings are compared with == / !=, which compares object identity instead of content. The result depends on interning and is usually wrong. - [Spring Security CORS allows any origin with credentials](https://vetkit.dev/checks/vetkit.java.spring-security.cors-any-origin-credentials/) (`vetkit.java.spring-security.cors-any-origin-credentials`): CORS allows any origin together with credentials, so any website can make authenticated requests and read the responses. - [Spring Security csrf().disable() turns off CSRF protection](https://vetkit.dev/checks/vetkit.java.spring-security.csrf-disabled/) (`vetkit.java.spring-security.csrf-disabled`): Spring Security CSRF protection is disabled. - [Java Spring Security X-Frame-Options disabled: clickjacking](https://vetkit.dev/checks/vetkit.java.spring-security.frame-options-disabled/) (`vetkit.java.spring-security.frame-options-disabled`): The X-Frame-Options header is disabled, so pages can be framed by other sites (clickjacking). - [Spring Security NoOp or MD5 password encoder](https://vetkit.dev/checks/vetkit.java.spring-security.insecure-password-encoder/) (`vetkit.java.spring-security.insecure-password-encoder`): Passwords are stored in plain text or with a fast, unsalted digest (NoOp/MD5/SHA password encoder). - [Spring Security anyRequest().permitAll() allows all requests](https://vetkit.dev/checks/vetkit.java.spring-security.permit-all-requests/) (`vetkit.java.spring-security.permit-all-requests`): Spring Security permits every request that is not matched by an earlier rule (`anyRequest().permitAll()` or `web.ignoring()` on `/**`). - [Spring Security permitAll on /admin or /actuator paths](https://vetkit.dev/checks/vetkit.java.spring-security.permit-all-sensitive-path/) (`vetkit.java.spring-security.permit-all-sensitive-path`): Spring Security permits unauthenticated access to an administrative or management path (`/admin/**`, `/actuator/**`, `/internal/**` or `EndpointRequest.toAnyEndpoint()`). - [MyBatis ${} interpolation causes SQL injection](https://vetkit.dev/checks/vetkit.java.sql-injection.mybatis-dollar-interpolation/) (`vetkit.java.sql-injection.mybatis-dollar-interpolation`): A MyBatis mapper splices a parameter into SQL with `${...}` (SQL injection). Unlike `#{...}`, `${...}` is pasted into the statement text unescaped, so a caller-controlled value can change the query. - [Java SQL injection from string concatenation or String.format](https://vetkit.dev/checks/vetkit.java.sql-injection.string-building/) (`vetkit.java.sql-injection.string-building`): SQL/JPQL query text is built with string concatenation or String.format (SQL injection). - [Java SSRF: outbound HTTP request to URL from request data](https://vetkit.dev/checks/vetkit.java.ssrf.request-url/) (`vetkit.java.ssrf.request-url`): An outbound HTTP request is sent to a URL taken from request data (server-side request forgery). - [Spring MVC view name from request data: template injection](https://vetkit.dev/checks/vetkit.java.template-injection.spring-view-name/) (`vetkit.java.template-injection.spring-view-name`): A Spring MVC view name is built from request data, which can lead to template expression injection. - [Java server-side template injection from request data](https://vetkit.dev/checks/vetkit.java.template-injection.template-source/) (`vetkit.java.template-injection.template-source`): Request data is used as template source code (server-side template injection). - [Java TrustManager and HostnameVerifier accept all certs](https://vetkit.dev/checks/vetkit.java.tls.trust-all/) (`vetkit.java.tls.trust-all`): A TrustManager or HostnameVerifier accepts every certificate/host, disabling TLS validation. - [Java SSLv3, TLS 1.0 or TLS 1.1 protocol requested](https://vetkit.dev/checks/vetkit.java.tls.weak-protocol/) (`vetkit.java.tls.weak-protocol`): A deprecated SSL/TLS protocol version (SSLv3, TLS 1.0 or TLS 1.1) is requested. - [Java XPath injection: expression built from request data](https://vetkit.dev/checks/vetkit.java.xpath-injection.expression/) (`vetkit.java.xpath-injection.expression`): An XPath expression is built from request data (XPath injection). - [Java JAX-RS text/html response XSS from request data](https://vetkit.dev/checks/vetkit.java.xss.jaxrs-html-response/) (`vetkit.java.xss.jaxrs-html-response`): A JAX-RS/Micronaut endpoint that produces text/html returns request data without HTML encoding (cross-site scripting). - [Java servlet XSS: request data written to the response](https://vetkit.dev/checks/vetkit.java.xss.servlet-response-writer/) (`vetkit.java.xss.servlet-response-writer`): Request data is written to the HTTP response without HTML encoding (cross-site scripting). - [Java XXE: XML parser without DTD and entity disabling](https://vetkit.dev/checks/vetkit.java.xxe.unhardened-parser/) (`vetkit.java.xxe.unhardened-parser`): An XML parser is created and used without disabling DTDs/external entities (XXE). - [NextAuth allowDangerousEmailAccountLinking enabled](https://vetkit.dev/checks/vetkit.js.auth.dangerous-email-account-linking/) (`vetkit.js.auth.dangerous-email-account-linking`): An Auth.js / NextAuth provider is configured with `allowDangerousEmailAccountLinking: true`. Any account from that provider whose email matches an existing user is linked to that user, so an attacker who registers an account with the victim's email at a provider that does not verify emails signs in as the victim. - [NextAuth Auth.js debug: true logs tokens in production](https://vetkit.dev/checks/vetkit.js.auth.debug-enabled/) (`vetkit.js.auth.debug-enabled`): The Auth.js / NextAuth config sets `debug: true` unconditionally. Debug mode logs provider tokens, session payloads and callback data to the server console in production. - [NextAuth Auth.js hardcoded secret in source code](https://vetkit.dev/checks/vetkit.js.auth.hardcoded-auth-secret/) (`vetkit.js.auth.hardcoded-auth-secret`): The NextAuth / Auth.js / Better Auth secret is a string literal in the source code. It signs and encrypts session cookies and JWTs, so anyone who can read the code can forge a session for any user. - [JavaScript eval() with a dynamic argument: code injection](https://vetkit.dev/checks/vetkit.js.code-injection.eval/) (`vetkit.js.code-injection.eval`): Dynamic code evaluation with a non-literal argument. If any part of the value is attacker-controlled this is arbitrary code execution. - [Node.js code injection: request input loads a module](https://vetkit.dev/checks/vetkit.js.code-injection.request-module-load/) (`vetkit.js.code-injection.request-module-load`): Request input decides which module or script is loaded or compiled (require/import/vm.Script). An attacker can load arbitrary files as code. - [Node.js child_process command injection from user input](https://vetkit.dev/checks/vetkit.js.command-injection.child-process/) (`vetkit.js.command-injection.child-process`): Untrusted input (request data, command-line arguments or environment variables) reaches a command that child_process runs through a shell. Shell metacharacters in the value run arbitrary commands on the server. - [Node.js child_process exec with a dynamic command string](https://vetkit.dev/checks/vetkit.js.command-injection.child-process-dynamic/) (`vetkit.js.command-injection.child-process-dynamic`): child_process.exec/execSync runs a command built from a dynamic value through a shell. No untrusted source was traced to it, but if any part of the value can be influenced from outside (request data, CLI arguments, environment, files) this is shell command injection. - [Node.js spawn shell: true command injection](https://vetkit.dev/checks/vetkit.js.command-injection.spawn-shell/) (`vetkit.js.command-injection.spawn-shell`): spawn/execFile invoked with `shell: true` and a non-literal command. The command is interpreted by a shell, which enables command injection. - [CORS reflected Origin with credentials in JavaScript](https://vetkit.dev/checks/vetkit.js.cors.reflected-origin-credentials/) (`vetkit.js.cors.reflected-origin-credentials`): CORS reflects any request Origin while allowing credentials. Any website can make authenticated requests as the visiting user and read the responses. - [Node.js bcrypt cost factor below 10 is too low](https://vetkit.dev/checks/vetkit.js.crypto.bcrypt-low-cost/) (`vetkit.js.crypto.bcrypt-low-cost`): bcrypt is used with a cost factor below 10. Stolen password hashes are then much cheaper to crack. - [Node.js crypto.createCipher is deprecated and insecure](https://vetkit.dev/checks/vetkit.js.crypto.deprecated-create-cipher/) (`vetkit.js.crypto.deprecated-create-cipher`): The deprecated crypto.createCipher/createDecipher API is used. It derives the key from a password with a single MD5 round and no salt, reuses the same IV for every message and is removed in Node.js 22. - [Node.js crypto cipher in ECB mode leaks data patterns](https://vetkit.dev/checks/vetkit.js.crypto.ecb-mode/) (`vetkit.js.crypto.ecb-mode`): A block cipher is used in ECB mode. ECB encrypts identical plaintext blocks to identical ciphertext blocks and leaks the structure of the data. - [JavaScript hardcoded encryption or HMAC key in source](https://vetkit.dev/checks/vetkit.js.crypto.hardcoded-key/) (`vetkit.js.crypto.hardcoded-key`): An encryption or HMAC key is a constant in the source code. Anyone with access to the code (or a leaked build) can decrypt the data or forge MACs. - [JavaScript Math.random() used for tokens and secrets](https://vetkit.dev/checks/vetkit.js.crypto.insecure-random-token/) (`vetkit.js.crypto.insecure-random-token`): Math.random() is used to generate a security-sensitive value (token, password, nonce...). It is predictable and not suitable for secrets. - [Node.js PBKDF2 with fewer than 10,000 iterations](https://vetkit.dev/checks/vetkit.js.crypto.pbkdf2-low-iterations/) (`vetkit.js.crypto.pbkdf2-low-iterations`): PBKDF2 runs with fewer than 10,000 iterations. Offline brute-forcing of the derived keys or password hashes is cheap. - [Node.js createCipheriv with a static IV](https://vetkit.dev/checks/vetkit.js.crypto.static-iv/) (`vetkit.js.crypto.static-iv`): createCipheriv is called with a constant IV (literal, zero-filled or fixed buffer). Reusing an IV makes ciphertexts linkable and, with CTR/GCM modes, lets attackers recover plaintext and forge messages. - [Node.js HMAC signature compared with === (timing attack)](https://vetkit.dev/checks/vetkit.js.crypto.timing-unsafe-compare/) (`vetkit.js.crypto.timing-unsafe-compare`): An HMAC/signature is compared with `===`/`!==`. Ordinary string comparison returns early at the first differing byte, which can leak the expected value through response timing. - [Node.js weak cipher: DES, 3DES, RC2, RC4 or Blowfish](https://vetkit.dev/checks/vetkit.js.crypto.weak-cipher/) (`vetkit.js.crypto.weak-cipher`): A broken or legacy cipher (DES, 3DES, RC2, RC4, Blowfish ...) is used. These ciphers have small keys or blocks and practical attacks. - [JavaScript weak hash: MD5 or SHA-1 is broken](https://vetkit.dev/checks/vetkit.js.crypto.weak-hash/) (`vetkit.js.crypto.weak-hash`): MD5/SHA-1 is cryptographically broken; do not use it for signatures, integrity or secrets. - [Node.js password hashed with MD5 or SHA-1](https://vetkit.dev/checks/vetkit.js.crypto.weak-password-hash/) (`vetkit.js.crypto.weak-password-hash`): A password or secret is hashed with a fast, broken digest (MD5/SHA-1). Such hashes are trivially brute-forced. - [Node.js RSA or DSA key shorter than 2048 bits](https://vetkit.dev/checks/vetkit.js.crypto.weak-rsa-key/) (`vetkit.js.crypto.weak-rsa-key`): An RSA/DSA key pair is generated with a modulus shorter than 2048 bits. This is below current minimum key-size recommendations. - [JavaScript framework CSRF protection disabled](https://vetkit.dev/checks/vetkit.js.csrf.protection-disabled/) (`vetkit.js.csrf.protection-disabled`): The framework's built-in CSRF / origin check is explicitly disabled or opened to every origin. Other sites can then submit state-changing requests on behalf of logged-in users. - [Node.js insecure deserialization: serialize-to-js, cryo](https://vetkit.dev/checks/vetkit.js.deserialization.eval-based-library/) (`vetkit.js.deserialization.eval-based-library`): A deserializer that revives functions with eval (serialize-to-js, funcster or cryo) is used. Deserializing attacker-controlled input with it is remote code execution. - [node-serialize unserialize: insecure deserialization RCE](https://vetkit.dev/checks/vetkit.js.deserialization.node-serialize/) (`vetkit.js.deserialization.node-serialize`): node-serialize `unserialize` executes functions embedded in the payload (remote code execution). - [js-yaml DEFAULT_FULL_SCHEMA allows code execution](https://vetkit.dev/checks/vetkit.js.deserialization.yaml-full-schema/) (`vetkit.js.deserialization.yaml-full-schema`): YAML is loaded with js-yaml's DEFAULT_FULL_SCHEMA. That schema constructs `!!js/function` values, so loading untrusted YAML executes attacker-supplied JavaScript. - [Electron contextIsolation disabled in BrowserWindow](https://vetkit.dev/checks/vetkit.js.electron.context-isolation-disabled/) (`vetkit.js.electron.context-isolation-disabled`): An Electron window disables context isolation. Web content can then tamper with the preload script's globals and reach privileged APIs. - [Electron nodeIntegration enabled for web content](https://vetkit.dev/checks/vetkit.js.electron.node-integration/) (`vetkit.js.electron.node-integration`): An Electron window enables Node.js integration for its web content. Any XSS or loaded remote content then gets full access to the operating system. - [Electron shell.openExternal with an unchecked URL](https://vetkit.dev/checks/vetkit.js.electron.open-external-untrusted/) (`vetkit.js.electron.open-external-untrusted`): shell.openExternal is called with a URL that is not checked first. Web content can make the app open `file:` or custom-protocol URLs, which can execute programs on the user's machine. - [Electron renderer sandbox disabled](https://vetkit.dev/checks/vetkit.js.electron.sandbox-disabled/) (`vetkit.js.electron.sandbox-disabled`): The Electron renderer sandbox is disabled. This weakens the boundary between web content and the operating system. - [Electron webSecurity disabled in BrowserWindow](https://vetkit.dev/checks/vetkit.js.electron.web-security-disabled/) (`vetkit.js.electron.web-security-disabled`): An Electron window disables web security (same-origin policy) or allows insecure content on HTTPS pages. - [GraphQL introspection enabled in production (Node.js)](https://vetkit.dev/checks/vetkit.js.graphql.introspection-enabled/) (`vetkit.js.graphql.introspection-enabled`): GraphQL introspection or a GraphQL IDE is enabled unconditionally. This exposes the full API schema in production. - [Helmet security header disabled: CSP, HSTS, frameguard](https://vetkit.dev/checks/vetkit.js.headers.helmet-protection-disabled/) (`vetkit.js.headers.helmet-protection-disabled`): A helmet security header (CSP, frame options, HSTS or nosniff) is explicitly disabled. This removes a browser-side defence against XSS, clickjacking or protocol downgrade. - [Node.js error stack trace sent to the client](https://vetkit.dev/checks/vetkit.js.info-exposure.stack-trace/) (`vetkit.js.info-exposure.stack-trace`): An error stack trace is sent to the client. Stack traces reveal file paths, library versions and internal logic that help attackers. - [JWT jwt.decode() trusted without signature verification](https://vetkit.dev/checks/vetkit.js.jwt.decode-trusted/) (`vetkit.js.jwt.decode-trusted`): The authenticated user is taken from `jwt.decode()`, which does not verify the token signature. Anyone can craft a token with arbitrary claims and impersonate any user. - [JWT hardcoded secret in jsonwebtoken sign or verify](https://vetkit.dev/checks/vetkit.js.jwt.hardcoded-secret/) (`vetkit.js.jwt.hardcoded-secret`): JWT signed or verified with a hard-coded secret. Anyone with access to the source can forge tokens. - [JWT verify with ignoreExpiration: true accepts expired tokens](https://vetkit.dev/checks/vetkit.js.jwt.ignore-expiration/) (`vetkit.js.jwt.ignore-expiration`): JWT verification is configured with `ignoreExpiration: true`, so expired (e.g. revoked or stolen) tokens are accepted forever. - [JWT verify accepts the none algorithm](https://vetkit.dev/checks/vetkit.js.jwt.none-algorithm/) (`vetkit.js.jwt.none-algorithm`): JWT verification accepts the `none` algorithm, which disables signature checking. - [jsonwebtoken verify without the algorithms option](https://vetkit.dev/checks/vetkit.js.jwt.verify-without-algorithms/) (`vetkit.js.jwt.verify-without-algorithms`): jsonwebtoken `verify` is called without the `algorithms` option, so the accepted algorithms are inferred from the key. With an empty or unset secret (for example a missing environment variable) versions before 9 then accept unsigned `none` tokens, and a key object or a public key that is not PEM-encoded is treated as an HMAC secret (algorithm confusion). - [Node.js LDAP injection: request input in a search filter](https://vetkit.dev/checks/vetkit.js.ldap-injection.request-filter/) (`vetkit.js.ldap-injection.request-filter`): Request input is spliced into an LDAP search filter. Characters such as `*`, `(` and `)` let an attacker rewrite the filter, for example to bypass a login check. - [Node.js mass assignment: request body written to a model](https://vetkit.dev/checks/vetkit.js.mass-assignment.request-body/) (`vetkit.js.mass-assignment.request-body`): The whole request body is written into a database model. Clients can set any field they like, including privileged ones such as role, isAdmin, ownerId or balance (mass assignment). - [MongoDB NoSQL injection: request body in a query filter](https://vetkit.dev/checks/vetkit.js.nosql-injection.request-filter/) (`vetkit.js.nosql-injection.request-filter`): A MongoDB query filter takes a value straight from the parsed request body or query string. JSON bodies and nested query strings can carry operator objects such as {"$ne": null}, which turns an equality check into an attacker-chosen condition (e.g. login bypass). - [MongoDB $where NoSQL injection from a dynamic string](https://vetkit.dev/checks/vetkit.js.nosql-injection.where-operator/) (`vetkit.js.nosql-injection.where-operator`): A MongoDB `$where` clause is built from a dynamic string. `$where` executes JavaScript on the database server, so any spliced-in value is server-side code injection. - [JavaScript open redirect via location from query string](https://vetkit.dev/checks/vetkit.js.open-redirect.client-location/) (`vetkit.js.open-redirect.client-location`): The browser navigates to a URL taken from the query string or fragment. Attackers can send links that redirect users to phishing pages or run `javascript:` URLs. - [Node.js open redirect: redirect target from request input](https://vetkit.dev/checks/vetkit.js.open-redirect.request-input/) (`vetkit.js.open-redirect.request-input`): Redirect target comes from request input. Attackers can craft links that redirect victims to malicious sites. - [Node.js zip slip path traversal on archive extraction](https://vetkit.dev/checks/vetkit.js.path-traversal.archive-entry/) (`vetkit.js.path-traversal.archive-entry`): A file path is built from an archive entry name while extracting. Entries named `../../somewhere` are written outside the target directory (zip slip). - [Multer originalname path traversal in disk storage](https://vetkit.dev/checks/vetkit.js.path-traversal.multer-original-name/) (`vetkit.js.path-traversal.multer-original-name`): multer disk storage saves uploads under the client-supplied `file.originalname`. A name such as `../../app/server.js` writes outside the upload directory and can overwrite application files. - [Express res.render path traversal from request view name](https://vetkit.dev/checks/vetkit.js.path-traversal.render-view-name/) (`vetkit.js.path-traversal.render-view-name`): The view name passed to res.render comes from request input. An attacker can render arbitrary template files from disk, which can disclose files or lead to code execution. - [Node.js path traversal: file path from request input](https://vetkit.dev/checks/vetkit.js.path-traversal.request-input/) (`vetkit.js.path-traversal.request-input`): A filesystem path is derived from request input, which can allow reading or writing arbitrary files. - [JavaScript postMessage handler without event.origin check](https://vetkit.dev/checks/vetkit.js.postmessage.missing-origin-check/) (`vetkit.js.postmessage.missing-origin-check`): A window `message` event handler uses `event.data` without checking `event.origin` (or `event.source`). Any page that can open or frame this one can send it messages. - [JavaScript prototype pollution in a recursive merge](https://vetkit.dev/checks/vetkit.js.prototype-pollution.recursive-merge/) (`vetkit.js.prototype-pollution.recursive-merge`): A hand-written recursive merge copies every key of the source object into the target, recursing into nested objects, without rejecting `__proto__`, `constructor` or `prototype`. Called on parsed JSON from a request, a `{"__proto__": {"isAdmin": true}}` payload modifies Object.prototype for the whole process (prototype pollution). - [JavaScript prototype pollution via obj[key][prop] request key](https://vetkit.dev/checks/vetkit.js.prototype-pollution.request-key/) (`vetkit.js.prototype-pollution.request-key`): A request value is used as the first key of a nested property assignment (`obj[key][prop] = value`). A key of `__proto__` or `constructor` modifies Object.prototype for the whole process (prototype pollution). - [Node.js prototype pollution: request body deep merge](https://vetkit.dev/checks/vetkit.js.prototype-pollution.request-merge/) (`vetkit.js.prototype-pollution.request-merge`): A parsed request body or query object is deep-merged into another object, or a request value is used as the property path of a `set` helper. A payload with a `__proto__` or `constructor.prototype` key then modifies Object.prototype for the whole process (prototype pollution): lodash before 4.17.21, the standalone lodash.merge / lodash.set packages, deepmerge, merge-deep, mixin-deep, extend and dot-prop releases with known advisories do not block such keys. - [JavaScript async callback in forEach is not awaited](https://vetkit.dev/checks/vetkit.js.quality.async-foreach/) (`vetkit.js.quality.async-foreach`): An async callback is passed to forEach. forEach ignores the returned promises, so the surrounding code does not wait for them and their rejections are unhandled. - [JavaScript async function as a Promise executor](https://vetkit.dev/checks/vetkit.js.quality.async-promise-executor/) (`vetkit.js.quality.async-promise-executor`): An async function is used as a Promise executor. Errors thrown after the first await are lost instead of rejecting the promise, and the wrapper is usually unnecessary. - [JavaScript comparison with NaN is always false](https://vetkit.dev/checks/vetkit.js.quality.compare-nan/) (`vetkit.js.quality.compare-nan`): Comparing with NaN is always false (or always true for !=). NaN is not equal to anything, including itself. - [JavaScript debugger statement left in code](https://vetkit.dev/checks/vetkit.js.quality.debugger-statement/) (`vetkit.js.quality.debugger-statement`): A `debugger` statement was left in the code. - [JavaScript duplicate else-if condition never runs](https://vetkit.dev/checks/vetkit.js.quality.duplicate-else-if-condition/) (`vetkit.js.quality.duplicate-else-if-condition`): This else-if branch repeats an earlier condition in the same chain, so it can never run. - [JavaScript empty catch block silently swallows errors](https://vetkit.dev/checks/vetkit.js.quality.empty-catch/) (`vetkit.js.quality.empty-catch`): Empty catch block. The error is silently discarded, which hides failures and makes bugs hard to diagnose. - [JavaScript identical operands on both sides of expression](https://vetkit.dev/checks/vetkit.js.quality.identical-operands/) (`vetkit.js.quality.identical-operands`): Both operands are identical, so the expression is constant or redundant. This is almost always a copy-paste mistake. - [JavaScript variable assigned to itself (self-assignment)](https://vetkit.dev/checks/vetkit.js.quality.self-assignment/) (`vetkit.js.quality.self-assignment`): A variable is assigned to itself. This has no effect and usually indicates a typo. - [JavaScript catch block that only rethrows the error](https://vetkit.dev/checks/vetkit.js.quality.useless-catch-rethrow/) (`vetkit.js.quality.useless-catch-rethrow`): The catch block only rethrows the caught error, so the try/catch adds nothing. - [Node.js ReDoS: RegExp compiled from request input](https://vetkit.dev/checks/vetkit.js.redos.request-regexp/) (`vetkit.js.redos.request-regexp`): A regular expression is compiled from request input. Attackers can submit catastrophic patterns that block the Node.js event loop (ReDoS) or match more than intended. - [Auth cookie set without httpOnly in Express and Next.js](https://vetkit.dev/checks/vetkit.js.session.auth-cookie-without-httponly/) (`vetkit.js.session.auth-cookie-without-httponly`): A session or auth token cookie is set without `httpOnly: true`. Express `res.cookie`, Next.js `cookies().set` / `response.cookies.set` and Hono `setCookie` do not add HttpOnly by default, so any cross-site scripting bug can read the token and take over the session. - [Session cookie with httpOnly: false in Node.js](https://vetkit.dev/checks/vetkit.js.session.cookie-httponly-disabled/) (`vetkit.js.session.cookie-httponly-disabled`): A session or authentication cookie is created with `httpOnly: false`. Any cross-site scripting bug can then read the cookie and hijack the session. - [Session cookie with secure: false in Node.js](https://vetkit.dev/checks/vetkit.js.session.cookie-secure-disabled/) (`vetkit.js.session.cookie-secure-disabled`): The session cookie is configured with `secure: false`. Browsers then also send it over plain HTTP, where it can be intercepted. - [Express session or cookie secret hardcoded in source](https://vetkit.dev/checks/vetkit.js.session.hardcoded-secret/) (`vetkit.js.session.hardcoded-secret`): The session or cookie signing secret is a string literal in the source code. Anyone who can read the code can forge signed cookies or session data. - [JavaScript SOQL injection from string concatenation](https://vetkit.dev/checks/vetkit.js.soql-injection.string-building/) (`vetkit.js.soql-injection.string-building`): SOQL query built with string concatenation or template interpolation. An unescaped value in a WHERE clause changes which Salesforce records are returned or matched (SOQL injection). - [Node.js SQL injection: request input in a raw query](https://vetkit.dev/checks/vetkit.js.sql-injection.request-input/) (`vetkit.js.sql-injection.request-input`): Request input reaches the text of a raw SQL query or SQL fragment. An attacker can change the query and read or modify arbitrary data. - [JavaScript SQL injection from string concatenation](https://vetkit.dev/checks/vetkit.js.sql-injection.string-building/) (`vetkit.js.sql-injection.string-building`): SQL query built with string concatenation or template interpolation. Untrusted values in the query text lead to SQL injection. - [Node.js SSRF: outbound request URL from request input](https://vetkit.dev/checks/vetkit.js.ssrf.request-input/) (`vetkit.js.ssrf.request-input`): An outbound HTTP request URL is built from request input. This allows server-side request forgery against internal services and cloud metadata endpoints. - [Express res.render with request object as template locals](https://vetkit.dev/checks/vetkit.js.ssti.render-request-locals/) (`vetkit.js.ssti.render-request-locals`): The whole request object is passed as template locals to res.render. Template engines read special keys from locals (layout, settings, view options), so request fields can switch layouts, include arbitrary files or reach engine options that execute code. - [Node.js SSTI: request input compiled as a template](https://vetkit.dev/checks/vetkit.js.ssti.request-template/) (`vetkit.js.ssti.request-template`): Request input is compiled as a template (EJS, Pug, Handlebars, Nunjucks, lodash.template ...). Server-side template injection lets an attacker run code on the server. - [Node.js TLS checkServerIdentity disabled](https://vetkit.dev/checks/vetkit.js.tls.hostname-check-disabled/) (`vetkit.js.tls.hostname-check-disabled`): TLS hostname verification is disabled with a no-op `checkServerIdentity`. Any valid certificate for any domain is accepted, so the connection can be intercepted. - [Node.js rejectUnauthorized: false disables TLS validation](https://vetkit.dev/checks/vetkit.js.tls.reject-unauthorized-disabled/) (`vetkit.js.tls.reject-unauthorized-disabled`): TLS certificate verification is disabled. Connections can be intercepted by a man-in-the-middle. - [Node.js rejectUnauthorized: false behind an env flag](https://vetkit.dev/checks/vetkit.js.tls.reject-unauthorized-disabled-guarded/) (`vetkit.js.tls.reject-unauthorized-disabled-guarded`): TLS certificate verification is disabled behind an environment or opt-in check (`rejectUnauthorized: false`). The insecure path is reachable whenever that flag is set in production. - [Node.js TLS allows SSLv3, TLS 1.0 or TLS 1.1](https://vetkit.dev/checks/vetkit.js.tls.weak-protocol-version/) (`vetkit.js.tls.weak-protocol-version`): TLS is configured to allow SSLv3, TLS 1.0 or TLS 1.1. These deprecated protocol versions are vulnerable to known downgrade and decryption attacks. - [tRPC publicProcedure mutation without an auth check](https://vetkit.dev/checks/vetkit.js.trpc.public-procedure-destructive-mutation/) (`vetkit.js.trpc.public-procedure-destructive-mutation`): A tRPC publicProcedure mutation updates or deletes database rows without checking who is calling. Anyone can call this procedure over HTTP and change or delete records by id. - [JavaScript endsWith() host check bypass with evil domain](https://vetkit.dev/checks/vetkit.js.validation.host-suffix-match/) (`vetkit.js.validation.host-suffix-match`): A host, origin or e-mail domain is validated with endsWith() against a bare domain name. An attacker-registered domain such as `evilexample.com` also passes the check. - [Node.js XPath injection: request input in an expression](https://vetkit.dev/checks/vetkit.js.xpath-injection.request-input/) (`vetkit.js.xpath-injection.request-input`): Request input is spliced into an XPath expression. An attacker can change the query to read other parts of the XML document. - [Angular bypassSecurityTrust* with a dynamic value: XSS](https://vetkit.dev/checks/vetkit.js.xss.angular-bypass-security/) (`vetkit.js.xss.angular-bypass-security`): Angular's sanitizer is bypassed (bypassSecurityTrust*) for a dynamic value. If any part of the value is user-controlled this is cross-site scripting. - [React dangerouslySetInnerHTML with a dynamic value: XSS](https://vetkit.dev/checks/vetkit.js.xss.dangerously-set-inner-html/) (`vetkit.js.xss.dangerously-set-inner-html`): dangerouslySetInnerHTML receives a non-literal value. Unsanitised HTML leads to cross-site scripting. - [DOM XSS: URL, referrer or window.name inserted as HTML](https://vetkit.dev/checks/vetkit.js.xss.dom-location-source/) (`vetkit.js.xss.dom-location-source`): Data from the page URL, referrer or window.name is inserted as HTML through jQuery or another HTML-parsing API (DOM-based cross-site scripting). - [JavaScript innerHTML and document.write XSS](https://vetkit.dev/checks/vetkit.js.xss.inner-html/) (`vetkit.js.xss.inner-html`): innerHTML / outerHTML / insertAdjacentHTML / document.write receives a non-literal value. Unsanitised HTML leads to cross-site scripting. - [Node.js reflected XSS: request input in an HTML response](https://vetkit.dev/checks/vetkit.js.xss.response-html-request/) (`vetkit.js.xss.response-html-request`): Request input is concatenated into an HTML response body without escaping (reflected cross-site scripting). - [libxmljs noent: true expands external entities (XXE)](https://vetkit.dev/checks/vetkit.js.xxe.libxml-noent/) (`vetkit.js.xxe.libxml-noent`): XML is parsed with libxmljs and `noent: true`, which expands external entities. A crafted document can read local files or make the server issue requests (XXE). - [Jupyter server allow_origin = '*' allows any website](https://vetkit.dev/checks/vetkit.jupyter.server.cors-any-origin/) (`vetkit.jupyter.server.cors-any-origin`): The Jupyter server allows cross-origin requests from any website (`allow_origin = '*'`). A malicious page can then drive the kernel API in the user's browser. - [Jupyter server with empty token and no password](https://vetkit.dev/checks/vetkit.jupyter.server.no-authentication/) (`vetkit.jupyter.server.no-authentication`): The Jupyter server is configured with an empty token and no password. Anyone who can reach it gets an unauthenticated notebook, i.e. arbitrary code execution as the server user. - [Android SharedPreferences plaintext secret in Kotlin](https://vetkit.dev/checks/vetkit.kotlin.android.shared-preferences-plaintext-secret/) (`vetkit.kotlin.android.shared-preferences-plaintext-secret`): A password, token, API key or similar secret is written to SharedPreferences in plain text. The XML file is readable on rooted devices and from extracted backups. - [Kotlin Android WebView allowFileAccess enabled](https://vetkit.dev/checks/vetkit.kotlin.android.webview-file-access/) (`vetkit.kotlin.android.webview-file-access`): A WebView explicitly enables access to the local file system. - [Kotlin WebView onReceivedSslError calls proceed()](https://vetkit.dev/checks/vetkit.kotlin.android.webview-ignores-ssl-errors/) (`vetkit.kotlin.android.webview-ignores-ssl-errors`): A WebView proceeds past TLS certificate errors (onReceivedSslError calls proceed()). - [Kotlin Android WebView addJavascriptInterface exposed](https://vetkit.dev/checks/vetkit.kotlin.android.webview-javascript-interface/) (`vetkit.kotlin.android.webview-javascript-interface`): A JavaScript bridge is added to a WebView with JavaScript enabled; any page it loads can call the exposed methods. - [Kotlin Android WebView loads URL from Intent extra](https://vetkit.dev/checks/vetkit.kotlin.android.webview-loads-intent-url/) (`vetkit.kotlin.android.webview-loads-intent-url`): A WebView loads a URL taken from the launching Intent (extra or deep-link data). Any app or web link that can start this component can make the WebView open an attacker's page with the app's cookies, JavaScript bridges and file access. - [Kotlin setAllowUniversalAccessFromFileURLs in WebView](https://vetkit.dev/checks/vetkit.kotlin.android.webview-universal-file-access/) (`vetkit.kotlin.android.webview-universal-file-access`): A WebView lets file:// pages read other files or any origin (allowUniversalAccessFromFileURLs/allowFileAccessFromFileURLs). - [Kotlin Android world-readable or world-writable file mode](https://vetkit.dev/checks/vetkit.kotlin.android.world-accessible-mode/) (`vetkit.kotlin.android.world-accessible-mode`): A file, database or SharedPreferences is created world-readable or world-writable. - [Kotlin SpEL injection: request data evaluated as code](https://vetkit.dev/checks/vetkit.kotlin.code-injection.expression-language/) (`vetkit.kotlin.code-injection.expression-language`): Request data is evaluated as a SpEL expression, which allows remote code execution. - [Kotlin command injection via Runtime.exec or a shell](https://vetkit.dev/checks/vetkit.kotlin.command-injection.runtime-exec/) (`vetkit.kotlin.command-injection.runtime-exec`): An OS command is executed from a dynamically built string or through a shell (command injection). - [Kotlin AES ECB mode leaks plaintext patterns](https://vetkit.dev/checks/vetkit.kotlin.crypto.ecb-mode/) (`vetkit.kotlin.crypto.ecb-mode`): A block cipher is used in ECB mode (explicitly or as the `"AES"` default), which leaks plaintext patterns. - [Kotlin hardcoded cryptographic key in source code](https://vetkit.dev/checks/vetkit.kotlin.crypto.hardcoded-key/) (`vetkit.kotlin.crypto.hardcoded-key`): A cryptographic key is hard-coded in the source code. - [Kotlin insecure random number generator for tokens](https://vetkit.dev/checks/vetkit.kotlin.crypto.insecure-random-token/) (`vetkit.kotlin.crypto.insecure-random-token`): A security-sensitive value (token, password, session id, nonce, salt) is generated with a predictable random number generator. - [Kotlin static IV or nonce used for encryption](https://vetkit.dev/checks/vetkit.kotlin.crypto.static-iv/) (`vetkit.kotlin.crypto.static-iv`): A constant initialization vector/nonce is used for encryption. - [Kotlin weak cipher: DES, 3DES, RC2, RC4 or Blowfish](https://vetkit.dev/checks/vetkit.kotlin.crypto.weak-cipher/) (`vetkit.kotlin.crypto.weak-cipher`): A broken or weak cipher (DES, 3DES, RC2, RC4, Blowfish) is used. - [Kotlin weak hash: MD5 or SHA-1 is broken](https://vetkit.dev/checks/vetkit.kotlin.crypto.weak-hash/) (`vetkit.kotlin.crypto.weak-hash`): MD5/SHA-1 is cryptographically broken; do not use it for signatures, integrity or passwords. - [Kotlin Jackson default typing: unsafe deserialization](https://vetkit.dev/checks/vetkit.kotlin.deserialization.jackson-default-typing/) (`vetkit.kotlin.deserialization.jackson-default-typing`): Jackson polymorphic typing accepts arbitrary class names from JSON input (unsafe deserialization). - [Kotlin ObjectInputStream insecure deserialization](https://vetkit.dev/checks/vetkit.kotlin.deserialization.object-input-stream/) (`vetkit.kotlin.deserialization.object-input-stream`): Java native deserialization (ObjectInputStream/XMLDecoder) of untrusted data can lead to remote code execution. - [Kotlin JWT signed or verified with a hardcoded secret](https://vetkit.dev/checks/vetkit.kotlin.jwt.hardcoded-secret/) (`vetkit.kotlin.jwt.hardcoded-secret`): A JWT is signed or verified with a hard-coded secret. - [Kotlin JWT accepted without signature verification](https://vetkit.dev/checks/vetkit.kotlin.jwt.signature-not-verified/) (`vetkit.kotlin.jwt.signature-not-verified`): A JWT is accepted without signature verification (unsigned/`none` algorithm tokens). - [Ktor CORS anyHost with credentials allows any origin](https://vetkit.dev/checks/vetkit.kotlin.ktor.cors-any-host-credentials/) (`vetkit.kotlin.ktor.cors-any-host-credentials`): Ktor CORS allows any host together with credentials: the plugin reflects the request Origin, so any website can make authenticated cross-origin requests and read the responses. - [Ktor session cookie without secure or httpOnly flag](https://vetkit.dev/checks/vetkit.kotlin.ktor.session-cookie-insecure/) (`vetkit.kotlin.ktor.session-cookie-insecure`): A Ktor session cookie is configured without `cookie.secure = true` (Ktor's default) or with `cookie.httpOnly = false`, so the session id can be sent over plain HTTP or read by page scripts. - [Kotlin open redirect: redirect target from request data](https://vetkit.dev/checks/vetkit.kotlin.open-redirect.request-redirect/) (`vetkit.kotlin.open-redirect.request-redirect`): A redirect target is built from request data (open redirect). - [Kotlin path traversal: file path built from request data](https://vetkit.dev/checks/vetkit.kotlin.path-traversal.request-file-path/) (`vetkit.kotlin.path-traversal.request-file-path`): A file system path is built from request data, allowing path traversal (`../`) outside the intended directory. - [Spring Security Kotlin CORS any origin with credentials](https://vetkit.dev/checks/vetkit.kotlin.spring-security.cors-any-origin-credentials/) (`vetkit.kotlin.spring-security.cors-any-origin-credentials`): CORS allows any origin together with credentials, so any website can make authenticated requests and read the responses. - [Spring Security Kotlin CSRF protection disabled](https://vetkit.dev/checks/vetkit.kotlin.spring-security.csrf-disabled/) (`vetkit.kotlin.spring-security.csrf-disabled`): Spring Security CSRF protection is disabled. - [Kotlin Spring Security frameOptions disabled: clickjacking](https://vetkit.dev/checks/vetkit.kotlin.spring-security.frame-options-disabled/) (`vetkit.kotlin.spring-security.frame-options-disabled`): The X-Frame-Options header is disabled, so pages can be framed by other sites (clickjacking). - [Spring Security NoOp, MD5 or SHA password encoder](https://vetkit.dev/checks/vetkit.kotlin.spring-security.insecure-password-encoder/) (`vetkit.kotlin.spring-security.insecure-password-encoder`): Passwords are stored in plain text or with a fast, unsalted digest (NoOp/MD5/SHA password encoder). - [Spring Security anyRequest().permitAll() in Kotlin](https://vetkit.dev/checks/vetkit.kotlin.spring-security.permit-all-requests/) (`vetkit.kotlin.spring-security.permit-all-requests`): Spring Security permits every request that is not matched by an earlier rule (`anyRequest().permitAll()`, `authorize(anyRequest, permitAll)` or `web.ignoring()` on `/**`). - [Spring Security permitAll on /admin and /actuator paths](https://vetkit.dev/checks/vetkit.kotlin.spring-security.permit-all-sensitive-path/) (`vetkit.kotlin.spring-security.permit-all-sensitive-path`): Spring Security permits unauthenticated access to an administrative or management path (`/admin/**`, `/actuator/**`, `/internal/**` or `EndpointRequest.toAnyEndpoint()`). - [Kotlin SQL injection: query built with string template](https://vetkit.dev/checks/vetkit.kotlin.sql-injection.string-building/) (`vetkit.kotlin.sql-injection.string-building`): SQL query text is built with a string template or concatenation (SQL injection). - [Kotlin SSRF: HTTP request to a URL from request data](https://vetkit.dev/checks/vetkit.kotlin.ssrf.request-url/) (`vetkit.kotlin.ssrf.request-url`): An outbound HTTP request is sent to a URL taken from request data (server-side request forgery). - [Kotlin TrustManager and HostnameVerifier accept all certs](https://vetkit.dev/checks/vetkit.kotlin.tls.trust-all/) (`vetkit.kotlin.tls.trust-all`): A TrustManager or HostnameVerifier accepts every certificate/host, disabling TLS validation. - [Kotlin SSLv3, TLS 1.0 or TLS 1.1 protocol requested](https://vetkit.dev/checks/vetkit.kotlin.tls.weak-protocol/) (`vetkit.kotlin.tls.weak-protocol`): A deprecated SSL/TLS protocol version (SSLv3, TLS 1.0 or TLS 1.1) is requested. - [Kotlin Ktor XSS: request data in an HTML response](https://vetkit.dev/checks/vetkit.kotlin.xss.ktor-html-response/) (`vetkit.kotlin.xss.ktor-html-response`): Request data is sent back as an HTML response without encoding (cross-site scripting). - [LLM agent code execution tool: Python REPL or shell tool](https://vetkit.dev/checks/vetkit.llm-app.code-execution-tool/) (`vetkit.llm-app.code-execution-tool`): The agent is given a tool that runs the code the model writes (a Python REPL tool, a pandas / CSV / Spark dataframe agent, a shell tool, or a framework flag that opts into unsandboxed code execution). Whatever the model emits runs with the server's privileges, so prompt injection in a chat message or in a document the agent reads becomes remote code execution. - [Vite define exposes LLM API key in the client bundle](https://vetkit.dev/checks/vetkit.llm-app.llm-api-key-in-client/) (`vetkit.llm-app.llm-api-key-in-client`): The Vite `define` option copies an LLM provider API key into the client bundle. Every visitor of the app can read the key and call the provider on your account. An LLM provider API key is used by code that runs in the browser. Anyone who opens the app can read the key from the bundle or the network tab and call the provider on your account. - [LLM call without max tokens limit on request input](https://vetkit.dev/checks/vetkit.llm-app.llm-call-without-token-limit/) (`vetkit.llm-app.llm-call-without-token-limit`): A model call driven by request input sets no output token limit. Each request can generate up to the model's maximum output, so a user (or a script) can drive cost and latency up with a single prompt. - [LLM-chosen URL fetched by server: SSRF via prompt injection](https://vetkit.dev/checks/vetkit.llm-app.llm-chosen-url-fetch/) (`vetkit.llm-app.llm-chosen-url-fetch`): The server fetches a URL chosen by the language model (model output or an argument of an LLM tool). A prompt-injected request can point it at internal services (cloud metadata endpoints, admin panels, databases behind the firewall) and read the response back through the model (server-side request forgery). - [LLM output executed as code or shell command](https://vetkit.dev/checks/vetkit.llm-app.llm-output-code-execution/) (`vetkit.llm-app.llm-output-code-execution`): Text generated by a language model is executed as code or as a shell command. Anyone who can influence the model's input (a chat message, a web page or document it reads) can use prompt injection to make it emit code that then runs with the server's privileges. Text generated by a language model is executed as code, as a shell command or as a template. Anyone who can influence the model's input (a chat message, a web page or document it reads) can use prompt injection to make it emit code that then runs with the server's privileges. - [LLM-chosen file path used to write or delete files](https://vetkit.dev/checks/vetkit.llm-app.llm-output-file-path/) (`vetkit.llm-app.llm-output-file-path`): A file path chosen by a language model is used to write or delete files. A prompt-injected response can point it outside the intended directory (`../`, absolute paths) and overwrite source code, shell profiles or credentials. - [LLM output rendered as HTML without sanitising: XSS](https://vetkit.dev/checks/vetkit.llm-app.llm-output-html/) (`vetkit.llm-app.llm-output-html`): Text generated by a language model is inserted into the page as HTML without sanitisation. A prompt-injected response can carry script tags or event handlers (cross-site scripting), or image links that leak the conversation to another site. Text generated by a language model is rendered as HTML without sanitisation. A prompt-injected response can carry script tags or event handlers (cross-site scripting), or image links that leak the conversation to another site. - [LLM-generated query executed as raw SQL](https://vetkit.dev/checks/vetkit.llm-app.llm-output-sql/) (`vetkit.llm-app.llm-output-sql`): A query generated by a language model is executed as raw SQL. A prompt-injected request can make the model write any statement the database user is allowed to run: reading other users' rows, changing data or dropping tables. - [Request input in the LLM system prompt: prompt injection](https://vetkit.dev/checks/vetkit.llm-app.request-input-in-system-prompt/) (`vetkit.llm-app.request-input-in-system-prompt`): Request input is interpolated into the system prompt. Text placed in the system role carries the developer's authority, so a user can rewrite the model's instructions (prompt injection) instead of merely asking it a question. - [Text-to-SQL chain or SQL agent runs model-written queries](https://vetkit.dev/checks/vetkit.llm-app.text-to-sql-chain/) (`vetkit.llm-app.text-to-sql-chain`): A text-to-SQL chain or SQL agent executes the queries the model writes against the connected database. The model can be steered (by the user or by prompt injection in retrieved content) into writing any statement the database user is allowed to run: reading other users' rows, changing data or dropping tables. - [LLM tool arguments passed to shell, eval or raw SQL](https://vetkit.dev/checks/vetkit.llm-app.tool-args-command-execution/) (`vetkit.llm-app.tool-args-command-execution`): An LLM tool (function calling / MCP tool) passes arguments chosen by the model straight to a shell, to code evaluation or to raw SQL without an allow-list. Prompt injection in any content the agent reads can steer the model into calling the tool with an arbitrary command or query. - [macOS entitlements disable-library-validation code injection](https://vetkit.dev/checks/vetkit.macos.entitlements.code-injection/) (`vetkit.macos.entitlements.code-injection`): An entitlements file weakens the hardened runtime against code injection (`disable-library-validation` or `allow-dyld-environment-variables`). Other code can be loaded into the process and inherit its privileges and TCC permissions. - [macOS entitlements allow unsigned executable memory](https://vetkit.dev/checks/vetkit.macos.entitlements.executable-memory/) (`vetkit.macos.entitlements.executable-memory`): An entitlements file allows unsigned executable memory or disables executable page protection, which makes memory-corruption exploits easier. - [macOS entitlements com.apple.security.app-sandbox disabled](https://vetkit.dev/checks/vetkit.macos.entitlements.sandbox-disabled/) (`vetkit.macos.entitlements.sandbox-disabled`): An entitlements file explicitly disables the App Sandbox (`com.apple.security.app-sandbox`). A compromised app then has the user's full file and network access. - [MongoDB bindIp 0.0.0.0 without security.authorization](https://vetkit.dev/checks/vetkit.mongodb.network.exposed-without-auth/) (`vetkit.mongodb.network.exposed-without-auth`): MongoDB listens on all interfaces (`bindIp: 0.0.0.0` / `bindIpAll: true`) but access control is not enabled (`security.authorization`). Anyone who can reach the port can read and modify every database. - [MySQL and MariaDB local_infile enabled: LOAD DATA LOCAL](https://vetkit.dev/checks/vetkit.mysql.server.local-infile/) (`vetkit.mysql.server.local-infile`): MySQL/MariaDB enables `local_infile`. A malicious or compromised client/server pair can use LOAD DATA LOCAL to read files from the other side. - [MySQL and MariaDB skip-grant-tables disables passwords](https://vetkit.dev/checks/vetkit.mysql.server.skip-grant-tables/) (`vetkit.mysql.server.skip-grant-tables`): MySQL/MariaDB is configured with `skip-grant-tables`. The privilege system is disabled and every connection gets full access to all databases without a password. - [nginx alias off-by-slash path traversal](https://vetkit.dev/checks/vetkit.nginx.alias.path-traversal/) (`vetkit.nginx.alias.path-traversal`): nginx `alias` with a trailing slash is used in a prefix location without a trailing slash. A request such as `/static../secret` escapes the aliased directory and reads files from its parent ("off-by-slash" path traversal). - [nginx CORS reflects Origin with credentials allowed](https://vetkit.dev/checks/vetkit.nginx.cors.reflected-origin-credentials/) (`vetkit.nginx.cors.reflected-origin-credentials`): nginx reflects the request's Origin header into Access-Control-Allow-Origin while also allowing credentials. Any website can then make authenticated cross-origin requests and read the responses. - [nginx $uri in header: CRLF injection, response splitting](https://vetkit.dev/checks/vetkit.nginx.header.crlf-injection/) (`vetkit.nginx.header.crlf-injection`): nginx writes the decoded request path (`$uri` / `$document_uri`) into a redirect or response header. A request containing an encoded line break (%0d%0a) can inject headers into the response (HTTP response splitting). - [nginx autoindex on exposes directory listing](https://vetkit.dev/checks/vetkit.nginx.listing.autoindex/) (`vetkit.nginx.listing.autoindex`): nginx directory listing is enabled (`autoindex on`). Every file in the served directory, including backups, dumps or configuration files that were never linked, can be discovered and downloaded. - [nginx proxy_pass with $host or $http_host: SSRF](https://vetkit.dev/checks/vetkit.nginx.proxy.host-header-upstream/) (`vetkit.nginx.proxy.host-header-upstream`): nginx `proxy_pass` uses the request's Host header (`$host` / `$http_host`) as the upstream. In a default or wildcard server block the client chooses where the server connects (SSRF / open proxy). - [nginx proxy_pass upstream from request header: SSRF](https://vetkit.dev/checks/vetkit.nginx.proxy.request-controlled-upstream/) (`vetkit.nginx.proxy.request-controlled-upstream`): nginx `proxy_pass` takes its upstream host from a request header, query argument or cookie. Any client can make the server send requests to arbitrary internal or external hosts (SSRF / open proxy). - [nginx ssl_protocols enables SSLv3, TLSv1 or TLSv1.1](https://vetkit.dev/checks/vetkit.nginx.tls.legacy-protocols/) (`vetkit.nginx.tls.legacy-protocols`): nginx enables an obsolete SSL/TLS protocol version (SSLv2, SSLv3, TLSv1 or TLSv1.1). These versions have known cryptographic weaknesses and are deprecated by RFC 8996. - [nginx ssl_ciphers enables RC4, 3DES, NULL or EXPORT](https://vetkit.dev/checks/vetkit.nginx.tls.weak-ciphers/) (`vetkit.nginx.tls.weak-ciphers`): nginx enables a broken cipher suite (RC4, DES/3DES, NULL, EXPORT, LOW, MD5 or anonymous key exchange) in `ssl_ciphers`. Clients that negotiate it get no real confidentiality or authenticity. - [OpenAPI API key passed in the query string](https://vetkit.dev/checks/vetkit.openapi.auth.api-key-in-query/) (`vetkit.openapi.auth.api-key-in-query`): The API description defines an API key passed in the query string. Keys in URLs end up in server, proxy and browser logs and in Referer headers. - [OpenAPI servers URL uses plain HTTP for a remote host](https://vetkit.dev/checks/vetkit.openapi.transport.http-server/) (`vetkit.openapi.transport.http-server`): The API description lists a plain-HTTP server URL for a non-local host. Clients generated from it send credentials and data unencrypted. - [OpenSearch plugins.security.disabled: true, no auth](https://vetkit.dev/checks/vetkit.opensearch.security.disabled/) (`vetkit.opensearch.security.disabled`): The OpenSearch security plugin is disabled (`plugins.security.disabled: true`). The cluster accepts requests without authentication or TLS. - [PHP loose == hash comparison: type juggling auth bypass](https://vetkit.dev/checks/vetkit.php.auth.loose-hash-comparison/) (`vetkit.php.auth.loose-hash-comparison`): A hash, HMAC or password digest is compared with loose == / !=. PHP type juggling treats '0e…' digests as equal numbers, allowing authentication bypass. - [PHP strcmp() == 0 on request input allows auth bypass](https://vetkit.dev/checks/vetkit.php.auth.strcmp-loose-comparison/) (`vetkit.php.auth.strcmp-loose-comparison`): strcmp() on request input is checked with == 0 / !strcmp(). On PHP < 8 an array input makes strcmp() return NULL, which loosely equals 0 and bypasses the check. - [PHP unsafe reflection: class or method from request input](https://vetkit.dev/checks/vetkit.php.code-injection.dynamic-class-or-method/) (`vetkit.php.code-injection.dynamic-class-or-method`): A class to instantiate or a method to call is chosen by request input (unsafe reflection). Attackers can reach classes and methods that were never meant to be exposed. - [PHP code injection: function name from request input](https://vetkit.dev/checks/vetkit.php.code-injection.dynamic-function-call/) (`vetkit.php.code-injection.dynamic-function-call`): A function to call is chosen by request input (code injection). Attackers can invoke any function such as system() or passthru(). - [PHP eval() code injection with non-literal value](https://vetkit.dev/checks/vetkit.php.code-injection.eval/) (`vetkit.php.code-injection.eval`): PHP code is evaluated from a non-literal value (code injection). - [PHP command injection: OS command from request input](https://vetkit.dev/checks/vetkit.php.command-injection.exec/) (`vetkit.php.command-injection.exec`): An OS command is built from request input (command injection). An attacker can append shell metacharacters to run arbitrary commands on the server. - [PHP mail() additional_parameters argument injection](https://vetkit.dev/checks/vetkit.php.command-injection.mail-parameters/) (`vetkit.php.command-injection.mail-parameters`): Request input reaches the additional_parameters argument of mail(), which is passed to the sendmail command line (argument injection; can write files or execute code). - [PHP display_errors enabled at runtime with ini_set](https://vetkit.dev/checks/vetkit.php.config.display-errors-enabled/) (`vetkit.php.config.display-errors-enabled`): display_errors is switched on at runtime. Error messages shown to visitors disclose paths, queries and configuration details. - [PHP cookie with Secure or HttpOnly flag disabled](https://vetkit.dev/checks/vetkit.php.cookie.insecure-flags/) (`vetkit.php.cookie.insecure-flags`): A cookie or the session cookie is configured with the Secure or HttpOnly flag explicitly disabled. It may travel over plain HTTP or be read by injected JavaScript. - [PHP CORS reflects Origin with credentials allowed](https://vetkit.dev/checks/vetkit.php.cors.reflected-origin-with-credentials/) (`vetkit.php.cors.reflected-origin-with-credentials`): The request's Origin is reflected into Access-Control-Allow-Origin while credentials are allowed. Any website can then read authenticated responses. - [PHP crypt() with a hardcoded salt](https://vetkit.dev/checks/vetkit.php.crypto.crypt-static-salt/) (`vetkit.php.crypto.crypt-static-salt`): crypt() is called with a hard-coded salt. Every password then shares the same salt (and legacy DES/MD5 salts are trivially cracked). - [PHP mt_rand, rand or uniqid used for tokens and passwords](https://vetkit.dev/checks/vetkit.php.crypto.insecure-random-token/) (`vetkit.php.crypto.insecure-random-token`): A token, password, salt or nonce is generated with a non-cryptographic random source (rand / mt_rand / uniqid / lcg_value / microtime), so it can be predicted. - [PHP mcrypt extension used for encryption (removed in 7.2)](https://vetkit.dev/checks/vetkit.php.crypto.mcrypt/) (`vetkit.php.crypto.mcrypt`): The mcrypt extension is used for encryption. It is unmaintained, was removed in PHP 7.2 and makes weak modes and padding easy to misuse. - [PHP openssl_encrypt with a constant IV](https://vetkit.dev/checks/vetkit.php.crypto.openssl-static-iv/) (`vetkit.php.crypto.openssl-static-iv`): openssl_encrypt() is called with a constant initialization vector. Reusing an IV with the same key leaks plaintext relationships (and breaks GCM/CTR completely). - [PHP openssl_encrypt weak cipher: DES, RC4 or ECB mode](https://vetkit.dev/checks/vetkit.php.crypto.openssl-weak-cipher/) (`vetkit.php.crypto.openssl-weak-cipher`): openssl_encrypt/decrypt uses a broken cipher or ECB mode (DES, 3DES, RC2, RC4, Blowfish, *-ECB). ECB leaks plaintext patterns and the others are breakable. - [PHP weak password hashing with md5, sha1 or hash()](https://vetkit.dev/checks/vetkit.php.crypto.weak-password-hash/) (`vetkit.php.crypto.weak-password-hash`): A password is hashed with a fast general-purpose hash (md5 / sha1 / hash() / unsalted crypt()) instead of a password hashing function, so leaked hashes can be brute-forced offline. - [Laravel VerifyCsrfToken wildcard disables CSRF globally](https://vetkit.dev/checks/vetkit.php.csrf.laravel-disabled-globally/) (`vetkit.php.csrf.laravel-disabled-globally`): CSRF verification is disabled for every route (wildcard exception in VerifyCsrfToken / validateCsrfTokens). Any site can submit state-changing requests as a logged-in user. - [Laravel route withoutMiddleware skips CSRF verification](https://vetkit.dev/checks/vetkit.php.csrf.laravel-route-exempt/) (`vetkit.php.csrf.laravel-route-exempt`): A route opts out of Laravel CSRF verification with withoutMiddleware(). This is only safe for endpoints authenticated by something other than the session cookie (e.g. signed webhooks). - [PHP phar:// deserialization via file functions on user path](https://vetkit.dev/checks/vetkit.php.deserialization.phar-metadata/) (`vetkit.php.deserialization.phar-metadata`): A file-metadata function receives a path fully controlled by request input. On PHP < 8 a phar:// path triggers deserialization of the archive metadata (object injection). - [PHP unserialize() on request input: object injection](https://vetkit.dev/checks/vetkit.php.deserialization.unserialize/) (`vetkit.php.deserialization.unserialize`): unserialize() is called on request input, enabling PHP object injection. Gadget chains in loaded classes can lead to remote code execution. - [PHP file inclusion (LFI/RFI) from request input](https://vetkit.dev/checks/vetkit.php.file-inclusion.request-input/) (`vetkit.php.file-inclusion.request-input`): A file is included based on request input (local/remote file inclusion). - [PHP world-writable files: chmod 0777, 0666 or umask(0)](https://vetkit.dev/checks/vetkit.php.file-permissions.world-writable/) (`vetkit.php.file-permissions.world-writable`): A file or directory is made world-writable (chmod 0777 / 0666, or umask(0), which makes every file the process creates world-writable). Any local user or co-hosted application can replace its content; for a PHP script or configuration file that is code execution. - [PHP file upload stored under client-chosen filename](https://vetkit.dev/checks/vetkit.php.file-upload.client-filename/) (`vetkit.php.file-upload.client-filename`): An uploaded file is stored under a name or extension chosen by the client. Without an extension allow-list this allows uploading executable .php files or overwriting files. - [PHP upload validated by client MIME type in $_FILES](https://vetkit.dev/checks/vetkit.php.file-upload.client-mime-type-trusted/) (`vetkit.php.file-upload.client-mime-type-trusted`): An upload is validated by the MIME type the client sent ($_FILES[...]['type'] / getClientMimeType()). The browser supplies that value and an attacker sets it freely, so the check does not restrict what gets stored. - [PHP phpinfo() exposes configuration and environment](https://vetkit.dev/checks/vetkit.php.info-disclosure.phpinfo/) (`vetkit.php.info-disclosure.phpinfo`): phpinfo() output is generated by application code. It exposes the full PHP configuration, server paths and environment variables (often including secrets). - [php.ini allow_url_include enabled: remote file inclusion](https://vetkit.dev/checks/vetkit.php.ini.allow-url-include/) (`vetkit.php.ini.allow-url-include`): PHP `allow_url_include` is enabled. Any include/require of an attacker-influenced path turns into remote code execution by loading code from a URL. - [php.ini display_errors enabled prints errors to users](https://vetkit.dev/checks/vetkit.php.ini.display-errors/) (`vetkit.php.ini.display-errors`): PHP `display_errors` is enabled. Error messages with file paths, queries and stack details are printed into HTTP responses. - [php.ini enable_dl enabled allows loading extensions](https://vetkit.dev/checks/vetkit.php.ini.enable-dl/) (`vetkit.php.ini.enable-dl`): PHP `enable_dl` is enabled, which lets scripts load arbitrary native extensions at runtime with dl() and bypass other restrictions. - [php.ini expose_php enabled leaks X-Powered-By version](https://vetkit.dev/checks/vetkit.php.ini.expose-php/) (`vetkit.php.ini.expose-php`): PHP `expose_php` is enabled, so every response advertises the exact PHP version in the X-Powered-By header. - [php.ini session.cookie_httponly off exposes session ID](https://vetkit.dev/checks/vetkit.php.ini.session-cookie-httponly-off/) (`vetkit.php.ini.session-cookie-httponly-off`): PHP session cookies are explicitly made readable by JavaScript (`session.cookie_httponly` off). Any XSS can then steal the session identifier. - [PHP LDAP injection: request input without ldap_escape()](https://vetkit.dev/checks/vetkit.php.ldap-injection.request-input/) (`vetkit.php.ldap-injection.request-input`): Request input is built into an LDAP search filter without ldap_escape() (LDAP injection). Attackers can alter the filter to bypass authentication or enumerate the directory. - [PHP extract() on request input overwrites variables](https://vetkit.dev/checks/vetkit.php.mass-assignment.extract-request/) (`vetkit.php.mass-assignment.extract-request`): extract() imports request input as local variables. Attackers can overwrite any variable in scope, such as authorization flags or file paths. - [Laravel forceFill and forceCreate mass assignment](https://vetkit.dev/checks/vetkit.php.mass-assignment.laravel-force-fill/) (`vetkit.php.mass-assignment.laravel-force-fill`): Request input is mass-assigned with forceFill()/forceCreate(), which bypasses $fillable and $guarded. Attackers can set any column, such as is_admin or user_id. - [Laravel $request->all() mass assignment to Eloquent model](https://vetkit.dev/checks/vetkit.php.mass-assignment.laravel-request-all/) (`vetkit.php.mass-assignment.laravel-request-all`): The whole request payload ($request->all()) is mass-assigned to an Eloquent model. Only the model's $fillable / $guarded lists stop attackers from setting extra attributes. - [Laravel $guarded = [] or Model::unguard() mass assignment](https://vetkit.dev/checks/vetkit.php.mass-assignment.laravel-unguarded-model/) (`vetkit.php.mass-assignment.laravel-unguarded-model`): A Laravel model disables mass-assignment protection ($guarded = [] or Model::unguard()). Any attribute passed to create()/update()/fill() is then writable. - [PHP parse_str() without result array overwrites variables](https://vetkit.dev/checks/vetkit.php.mass-assignment.parse-str-global/) (`vetkit.php.mass-assignment.parse-str-global`): parse_str() is called without a result array, so query-string keys become local variables (variable overwrite; removed in PHP 8). - [PHP variable variable $$name from request input](https://vetkit.dev/checks/vetkit.php.mass-assignment.variable-variable/) (`vetkit.php.mass-assignment.variable-variable`): A variable name is taken from request input ($$name). Attackers can overwrite any variable in scope, emulating register_globals. - [PHP open redirect: redirect target from request input](https://vetkit.dev/checks/vetkit.php.open-redirect.request-input/) (`vetkit.php.open-redirect.request-input`): A redirect target is taken from request input (open redirect). Attackers can craft links on your domain that forward victims to a phishing site. - [PHP path traversal: file path from request input](https://vetkit.dev/checks/vetkit.php.path-traversal.request-input/) (`vetkit.php.path-traversal.request-input`): A file path (or URL) used to read, write or delete a file comes from request input (path traversal). Attackers can use ../ sequences or absolute paths to reach other files. - [PHP var_dump, print_r or dd() debug output left in code](https://vetkit.dev/checks/vetkit.php.quality.debug-output/) (`vetkit.php.quality.debug-output`): A debugging dump (var_dump, print_r, var_export, dd, dump) was left in the code. - [PHP empty catch block silently swallows exceptions](https://vetkit.dev/checks/vetkit.php.quality.empty-catch/) (`vetkit.php.quality.empty-catch`): Empty catch block. The exception is silently discarded, which hides failures and makes bugs hard to diagnose. - [PHP @ error suppression operator hides failures](https://vetkit.dev/checks/vetkit.php.quality.error-suppression/) (`vetkit.php.quality.error-suppression`): The @ operator suppresses every error raised by the expression, hiding failures such as missing files or network errors. - [PHP session fixation: session_id set from request input](https://vetkit.dev/checks/vetkit.php.session.fixation/) (`vetkit.php.session.fixation`): The session id is set from request input (session fixation). An attacker can plant a known session id and take over the session after the victim logs in. - [PHP Doctrine DQL SQL injection from request input](https://vetkit.dev/checks/vetkit.php.sql-injection.doctrine/) (`vetkit.php.sql-injection.doctrine`): Request input is built into a Doctrine DQL/SQL string (SQL injection). Doctrine only protects values passed as parameters. - [Laravel SQL injection: request input as column name](https://vetkit.dev/checks/vetkit.php.sql-injection.laravel-column-name/) (`vetkit.php.sql-injection.laravel-column-name`): Request input is used as a column / table name in a Laravel query-builder call (orderBy, where, select, pluck …). PDO cannot bind identifiers, so Laravel only wraps them; an attacker can sort or filter by hidden columns (password hashes, tokens) and, on some grammars, break out of the wrapping (SQL injection). - [Laravel SQL injection in DB::raw, whereRaw, orderByRaw](https://vetkit.dev/checks/vetkit.php.sql-injection.laravel-raw/) (`vetkit.php.sql-injection.laravel-raw`): Request input reaches a raw Laravel query fragment (DB::raw, whereRaw, orderByRaw …), bypassing query-builder bindings (SQL injection). - [PHP SQL injection: query built from request input](https://vetkit.dev/checks/vetkit.php.sql-injection.string-building/) (`vetkit.php.sql-injection.string-building`): Request input is concatenated or interpolated into a SQL query (SQL injection). An attacker can read or modify arbitrary database rows. - [WordPress $wpdb->prepare() SQL injection in format string](https://vetkit.dev/checks/vetkit.php.sql-injection.wordpress-prepare-format/) (`vetkit.php.sql-injection.wordpress-prepare-format`): Request input is built into the format string of $wpdb->prepare() (SQL injection). prepare() only escapes the values passed as separate arguments. - [WordPress $wpdb query SQL injection without prepare()](https://vetkit.dev/checks/vetkit.php.sql-injection.wordpress-wpdb/) (`vetkit.php.sql-injection.wordpress-wpdb`): Request input is built into a $wpdb query string without $wpdb->prepare() placeholders (SQL injection). - [PHP SSRF: outbound HTTP request to URL from request input](https://vetkit.dev/checks/vetkit.php.ssrf.request-url/) (`vetkit.php.ssrf.request-url`): An outbound HTTP request is sent to a URL taken from request input (server-side request forgery). Attackers can reach internal services and cloud metadata endpoints. - [PHP server-side template injection from request input](https://vetkit.dev/checks/vetkit.php.template-injection.request-input/) (`vetkit.php.template-injection.request-input`): Request input is compiled as a template (server-side template injection). Template code can call PHP functions and lead to remote code execution. - [PHP cURL TLS verification disabled (CURLOPT_SSL_VERIFYPEER)](https://vetkit.dev/checks/vetkit.php.tls.curl-verification-disabled/) (`vetkit.php.tls.curl-verification-disabled`): cURL TLS verification is disabled. - [PHP HTTP client TLS certificate verification disabled](https://vetkit.dev/checks/vetkit.php.tls.http-client-verification-disabled/) (`vetkit.php.tls.http-client-verification-disabled`): TLS certificate verification is disabled for an HTTP client or stream context, enabling man-in-the-middle attacks. - [PHP TLS verification disabled behind local env check](https://vetkit.dev/checks/vetkit.php.tls.verification-disabled-guarded/) (`vetkit.php.tls.verification-disabled-guarded`): TLS certificate verification is disabled behind an environment or opt-in check (`App::environment('local')`, `app()->isLocal()`, a debug flag). The insecure path is reachable whenever that condition holds in production. - [PHP XPath injection from request input](https://vetkit.dev/checks/vetkit.php.xpath-injection.request-input/) (`vetkit.php.xpath-injection.request-input`): Request input is built into an XPath expression (XPath injection). Attackers can change the query to read other nodes or bypass checks. - [Laravel Blade {!! !!} unescaped request input: XSS](https://vetkit.dev/checks/vetkit.php.xss.blade-unescaped-request/) (`vetkit.php.xss.blade-unescaped-request`): A Blade template prints request input with the unescaped {!! !!} syntax (reflected XSS). Blade only escapes output written with {{ }}. - [PHP reflected XSS: request input echoed without escaping](https://vetkit.dev/checks/vetkit.php.xss.echo-request/) (`vetkit.php.xss.echo-request`): Request input is echoed without HTML escaping (reflected XSS). - [PHP XXE: XML external entity loading or substitution](https://vetkit.dev/checks/vetkit.php.xxe.entity-substitution/) (`vetkit.php.xxe.entity-substitution`): XML is parsed with external entity loading or entity substitution enabled (XXE). Untrusted XML can then read local files or trigger requests to internal hosts. - [PostgreSQL pg_hba.conf trust authentication for remote hosts](https://vetkit.dev/checks/vetkit.postgres.hba.trust-remote/) (`vetkit.postgres.hba.trust-remote`): pg_hba.conf allows passwordless `trust` authentication for TCP connections from non-loopback addresses. Anyone who can reach PostgreSQL can log in as the listed users (often any user). - [Python assert used for authorization is removed by -O](https://vetkit.dev/checks/vetkit.py.auth.assert-authorization/) (`vetkit.py.auth.assert-authorization`): An authorization check is written as an assert statement. Python removes asserts when run with -O, which silently disables the check. - [Python hardcoded password or API key compared to literal](https://vetkit.dev/checks/vetkit.py.auth.hardcoded-credential-compare/) (`vetkit.py.auth.hardcoded-credential-compare`): A password, API key or token is compared against a string literal. The credential lives in source control and cannot be rotated without a deployment; anyone who reads the code can authenticate. - [Python cleartext FTP or Telnet connection (ftplib, telnetlib)](https://vetkit.dev/checks/vetkit.py.cleartext.ftp-telnet/) (`vetkit.py.cleartext.ftp-telnet`): A cleartext FTP or Telnet connection is opened; credentials and data travel unencrypted. - [Python cloud SDK client with hardcoded secret access key](https://vetkit.dev/checks/vetkit.py.cloud.hardcoded-credentials/) (`vetkit.py.cloud.hardcoded-credentials`): A cloud SDK client is created with a literal secret access key. Committed cloud keys grant account access to anyone who obtains the code. - [Python eval() and exec() with non-literal argument](https://vetkit.dev/checks/vetkit.py.code-injection.eval-exec/) (`vetkit.py.code-injection.eval-exec`): eval()/exec() called with a non-literal argument. Attacker-influenced input leads to arbitrary code execution. - [Python dynamic import of module name from request input](https://vetkit.dev/checks/vetkit.py.code-injection.request-dynamic-import/) (`vetkit.py.code-injection.request-dynamic-import`): A module name taken from request input is imported dynamically. Attackers can load arbitrary installed modules. - [Python getattr() with attribute name from request input](https://vetkit.dev/checks/vetkit.py.code-injection.request-getattr/) (`vetkit.py.code-injection.request-getattr`): An attribute name taken from request input is looked up with getattr() and called. Attackers can invoke any method of the object. - [Python XML-RPC allow_dotted_names=True enables code execution](https://vetkit.dev/checks/vetkit.py.code-injection.xmlrpc-dotted-names/) (`vetkit.py.code-injection.xmlrpc-dotted-names`): An XML-RPC server registers an instance with allow_dotted_names=True. Remote callers can traverse attributes and reach module globals, which can lead to code execution. - [Python subprocess.getoutput runs commands via shell](https://vetkit.dev/checks/vetkit.py.command-injection.implicit-shell/) (`vetkit.py.command-injection.implicit-shell`): A non-literal command is passed to an API that always runs it through /bin/sh (subprocess.getoutput, asyncio.create_subprocess_shell). This allows OS command injection. - [Python os.system and shell=True command injection](https://vetkit.dev/checks/vetkit.py.command-injection.shell/) (`vetkit.py.command-injection.shell`): A shell command is built from a non-literal value (os.system / subprocess with shell=True). This allows OS command injection. - [Python SSH exec_command built with string interpolation](https://vetkit.dev/checks/vetkit.py.command-injection.ssh-exec-command/) (`vetkit.py.command-injection.ssh-exec-command`): A remote shell command for SSH exec_command() is built with string interpolation. Values containing shell metacharacters run arbitrary commands on the remote host. - [Python session cookie without the Secure flag](https://vetkit.dev/checks/vetkit.py.cookies.secure-flag-disabled/) (`vetkit.py.cookies.secure-flag-disabled`): The session or CSRF cookie is explicitly configured without the Secure flag, so it is also sent over plain HTTP. - [Python session cookie without HttpOnly enables hijacking](https://vetkit.dev/checks/vetkit.py.cookies.session-httponly-disabled/) (`vetkit.py.cookies.session-httponly-disabled`): The session cookie is configured without HttpOnly. Any XSS can then read the session cookie and hijack the account. - [Python CORS allows any origin with credentials](https://vetkit.dev/checks/vetkit.py.cors.wildcard-with-credentials/) (`vetkit.py.cors.wildcard-with-credentials`): CORS allows any origin together with credentials. The middleware then echoes the caller's Origin, so every website can read authenticated responses. - [Python broken cipher: DES, 3DES, RC4, Blowfish](https://vetkit.dev/checks/vetkit.py.crypto.broken-cipher/) (`vetkit.py.crypto.broken-cipher`): A broken or obsolete cipher (DES, 3DES, RC4, RC2, Blowfish, CAST, IDEA, SEED) is used. - [Python AES ECB mode leaks plaintext patterns](https://vetkit.dev/checks/vetkit.py.crypto.ecb-mode/) (`vetkit.py.crypto.ecb-mode`): A block cipher is used in ECB mode, which leaks patterns of the plaintext (identical blocks encrypt identically). - [Python password hashed with fast SHA-2 or SHA-3 digest](https://vetkit.dev/checks/vetkit.py.crypto.fast-password-hash/) (`vetkit.py.crypto.fast-password-hash`): A password is hashed with a single fast SHA-2/SHA-3/BLAKE2 digest. Fast hashes let attackers test billions of guesses per second. - [Python hardcoded encryption key in source code](https://vetkit.dev/checks/vetkit.py.crypto.hardcoded-key/) (`vetkit.py.crypto.hardcoded-key`): An encryption key is a literal in source code. Anyone with the code (or a leaked copy) can decrypt or forge the protected data. - [Python random module used for security tokens](https://vetkit.dev/checks/vetkit.py.crypto.insecure-random-token/) (`vetkit.py.crypto.insecure-random-token`): The `random` module is used to generate a security-sensitive value. It is predictable. - [Python cipher with static IV or nonce reuse](https://vetkit.dev/checks/vetkit.py.crypto.static-iv/) (`vetkit.py.crypto.static-iv`): A cipher is initialised with a constant IV/nonce. Reusing an IV/nonce with the same key breaks confidentiality (and integrity for GCM/CTR). - [Python HMAC compared with == enables timing attacks](https://vetkit.dev/checks/vetkit.py.crypto.timing-unsafe-compare/) (`vetkit.py.crypto.timing-unsafe-compare`): An HMAC digest is compared with == / !=. The comparison time leaks how many leading bytes match, allowing signatures to be forged byte by byte. - [Python weak hash: MD5 or SHA-1 for signatures](https://vetkit.dev/checks/vetkit.py.crypto.weak-hash/) (`vetkit.py.crypto.weak-hash`): MD5/SHA-1 is cryptographically broken; do not use it for signatures, integrity or secrets. - [Python password hashing with MD5 or SHA-1](https://vetkit.dev/checks/vetkit.py.crypto.weak-password-hash/) (`vetkit.py.crypto.weak-password-hash`): A password or secret is hashed with a fast, broken digest (MD5/SHA-1). - [Python RSA or DSA key shorter than 2048 bits](https://vetkit.dev/checks/vetkit.py.crypto.weak-rsa-key/) (`vetkit.py.crypto.weak-rsa-key`): An RSA/DSA key shorter than 2048 bits is generated; such keys are within reach of factoring attacks. - [Python joblib.load and torch.load run pickle code](https://vetkit.dev/checks/vetkit.py.deserialization.pickle-file-load/) (`vetkit.py.deserialization.pickle-file-load`): A file is loaded with a pickle-based loader (joblib.load, pandas.read_pickle, torch.load). Loading an untrusted file runs arbitrary code. - [Python allow_pickle=True and weights_only=False risks](https://vetkit.dev/checks/vetkit.py.deserialization.pickle-opt-in/) (`vetkit.py.deserialization.pickle-opt-in`): A loader is explicitly told to accept pickled objects (weights_only=False, allow_pickle=True, safe_mode=False). A malicious file executes code when loaded. - [Python insecure deserialization: pickle and yaml.load](https://vetkit.dev/checks/vetkit.py.deserialization.unsafe-load/) (`vetkit.py.deserialization.unsafe-load`): Deserializing data with pickle/marshal/shelve or yaml.load without a safe loader can execute arbitrary code if the input is untrusted. - [Django ALLOWED_HOSTS wildcard enables Host header attacks](https://vetkit.dev/checks/vetkit.py.django.allowed-hosts-wildcard/) (`vetkit.py.django.allowed-hosts-wildcard`): A Django settings module allows every Host header (ALLOWED_HOSTS contains "*"). Forged Host headers then poison password-reset links and caches. - [Django @csrf_exempt on session-authenticated view (CSRF)](https://vetkit.dev/checks/vetkit.py.django.csrf-exempt-session-view/) (`vetkit.py.django.csrf-exempt-session-view`): A view that relies on the logged-in user or session is marked @csrf_exempt. Other sites can make the victim's browser perform this action (CSRF). - [Django DEBUG = True leaks source and settings](https://vetkit.dev/checks/vetkit.py.django.debug-enabled/) (`vetkit.py.django.debug-enabled`): A Django settings module sets DEBUG = True unconditionally. Deployed with it, error pages leak source code, settings and environment details. - [Django AUTH_PASSWORD_VALIDATORS empty accepts any password](https://vetkit.dev/checks/vetkit.py.django.empty-password-validators/) (`vetkit.py.django.empty-password-validators`): A Django settings module sets AUTH_PASSWORD_VALIDATORS to an empty list, so any password (including "1") is accepted. - [Django hardcoded SECRET_KEY in settings](https://vetkit.dev/checks/vetkit.py.django.hardcoded-secret-key/) (`vetkit.py.django.hardcoded-secret-key`): A Django settings module hard-codes SECRET_KEY. Anyone with the source can forge sessions, password-reset tokens and signed data. - [Django PASSWORD_HASHERS uses MD5 or SHA-1 hasher](https://vetkit.dev/checks/vetkit.py.django.weak-password-hasher/) (`vetkit.py.django.weak-password-hasher`): The preferred Django password hasher (first entry of PASSWORD_HASHERS) is a fast, broken digest such as MD5 or SHA-1. Leaked hashes are cracked quickly. - [Django REST framework default AllowAny makes APIs public](https://vetkit.dev/checks/vetkit.py.drf.allow-any-default/) (`vetkit.py.drf.allow-any-default`): Django REST framework's default permission class is AllowAny. Every API view without its own permission_classes is public. - [Python chmod and umask making files world-writable](https://vetkit.dev/checks/vetkit.py.filesystem.world-writable/) (`vetkit.py.filesystem.world-writable`): A file or directory is made world-writable (chmod / umask). Any local user can then modify it. - [Flask-WTF WTF_CSRF_ENABLED = False disables CSRF protection](https://vetkit.dev/checks/vetkit.py.flask.csrf-disabled/) (`vetkit.py.flask.csrf-disabled`): Flask-WTF CSRF protection is disabled (WTF_CSRF_ENABLED = False) outside of test configuration. - [Flask debug mode enabled exposes Werkzeug console (RCE)](https://vetkit.dev/checks/vetkit.py.flask.debug-enabled/) (`vetkit.py.flask.debug-enabled`): The Flask/Werkzeug debugger is enabled. In production it exposes an interactive console (remote code execution). - [Python JWT algorithm taken from the unverified token header](https://vetkit.dev/checks/vetkit.py.jwt.algorithm-from-token/) (`vetkit.py.jwt.algorithm-from-token`): The JWT verification algorithm is taken from the token's own unverified header. Attackers choose the algorithm (algorithm confusion, "none"). - [Python jwt.decode verify_exp False accepts expired tokens](https://vetkit.dev/checks/vetkit.py.jwt.expiry-verification-disabled/) (`vetkit.py.jwt.expiry-verification-disabled`): JWT expiry verification is disabled (verify_exp = False); stolen tokens stay valid forever. - [Python JWT hardcoded signing secret in source](https://vetkit.dev/checks/vetkit.py.jwt.hardcoded-secret/) (`vetkit.py.jwt.hardcoded-secret`): A JWT or framework signing secret is hard-coded in source. Anyone with the code can forge tokens/sessions. - [Python JWT signature verification disabled](https://vetkit.dev/checks/vetkit.py.jwt.verification-disabled/) (`vetkit.py.jwt.verification-disabled`): JWT signature verification is disabled; forged tokens will be accepted. - [Python LDAP injection from string-built search filters](https://vetkit.dev/checks/vetkit.py.ldap-injection.filter-building/) (`vetkit.py.ldap-injection.filter-building`): An LDAP search filter is built with string interpolation and no escaping. Characters such as * ( ) in the value alter the filter (LDAP injection, authentication bypass). - [Python mass assignment: setattr with request data](https://vetkit.dev/checks/vetkit.py.mass-assignment.request-setattr/) (`vetkit.py.mass-assignment.request-setattr`): Attribute names taken from request data are written onto an object with setattr() or __dict__.update() without an allow-list. Clients can set any field, including is_admin or password (mass assignment). - [Python MongoDB $where string interpolation injection](https://vetkit.dev/checks/vetkit.py.nosql-injection.mongo-where/) (`vetkit.py.nosql-injection.mongo-where`): A MongoDB $where JavaScript expression is built with string interpolation. Injected values run as server-side JavaScript. - [Python MongoDB NoSQL injection from request JSON filter](https://vetkit.dev/checks/vetkit.py.nosql-injection.request-filter/) (`vetkit.py.nosql-injection.request-filter`): JSON request data is placed into a MongoDB query filter without type checks. Objects such as {"$ne": null} change the query logic (operator injection). - [Python open redirect from request input](https://vetkit.dev/checks/vetkit.py.open-redirect.request-input/) (`vetkit.py.open-redirect.request-input`): Redirect target comes from request input (open redirect). - [Python path traversal: request input used in file path](https://vetkit.dev/checks/vetkit.py.path-traversal.request-to-file/) (`vetkit.py.path-traversal.request-to-file`): A filesystem path built from request input is opened, served or modified. Sequences such as ../ let attackers read or overwrite arbitrary files. - [Python tarfile extractall path traversal without filter](https://vetkit.dev/checks/vetkit.py.path-traversal.tar-extractall/) (`vetkit.py.path-traversal.tar-extractall`): A tar archive is extracted (extractall / extract / shutil.unpack_archive) without a safety filter. Crafted member names or links (../, absolute paths) can write files outside the target directory. - [Python assert on a tuple is always true](https://vetkit.dev/checks/vetkit.py.quality.assert-tuple/) (`vetkit.py.quality.assert-tuple`): `assert (condition, message)` asserts a non-empty tuple, which is always true, so the assertion never fails. - [Python bare except: pass swallows all exceptions](https://vetkit.dev/checks/vetkit.py.quality.bare-except-pass/) (`vetkit.py.quality.bare-except-pass`): A bare `except:` silently swallows every exception, including KeyboardInterrupt and SystemExit. - [Python except Exception: pass hides real errors](https://vetkit.dev/checks/vetkit.py.quality.broad-except-pass/) (`vetkit.py.quality.broad-except-pass`): `except Exception: pass` silently discards every error raised in the try block, which hides real failures. - [Python comparing to None with == instead of is](https://vetkit.dev/checks/vetkit.py.quality.compare-to-none/) (`vetkit.py.quality.compare-to-none`): Comparison to None with `==`/`!=` can be overridden by `__eq__`; use `is` / `is not`. - [Python duplicate elif condition makes branch unreachable](https://vetkit.dev/checks/vetkit.py.quality.duplicate-elif-condition/) (`vetkit.py.quality.duplicate-elif-condition`): This elif branch repeats an earlier condition in the same chain, so it can never run. - [Python comparing against a literal with is](https://vetkit.dev/checks/vetkit.py.quality.is-literal/) (`vetkit.py.quality.is-literal`): `is` compares identity, not value. Comparing against a str/int/bytes literal with `is` depends on interpreter caching and can silently return False. - [Python mutable default argument shared between calls](https://vetkit.dev/checks/vetkit.py.quality.mutable-default-argument/) (`vetkit.py.quality.mutable-default-argument`): A mutable default argument is created once and shared between calls, so changes made in one call leak into the next. - [Python variable assigned to itself has no effect](https://vetkit.dev/checks/vetkit.py.quality.self-assignment/) (`vetkit.py.quality.self-assignment`): A variable is assigned to itself. This has no effect and usually indicates a typo. - [Python regex injection and ReDoS from request pattern](https://vetkit.dev/checks/vetkit.py.regex-injection.request-pattern/) (`vetkit.py.regex-injection.request-pattern`): A regular expression is compiled from request input. Crafted patterns cause catastrophic backtracking (ReDoS) or match more than intended. - [Django RawSQL and extra() SQL injection via interpolation](https://vetkit.dev/checks/vetkit.py.sql-injection.orm-fragment/) (`vetkit.py.sql-injection.orm-fragment`): A raw SQL fragment for the Django ORM (RawSQL, QuerySet.extra) is built with string interpolation. Untrusted values in it lead to SQL injection. - [Python SQL injection from f-string or format queries](https://vetkit.dev/checks/vetkit.py.sql-injection.string-building/) (`vetkit.py.sql-injection.string-building`): SQL executed from a string built with %, .format(), f-strings or concatenation. This is vulnerable to SQL injection. - [Paramiko AutoAddPolicy accepts unknown SSH host keys](https://vetkit.dev/checks/vetkit.py.ssh.unverified-host-key/) (`vetkit.py.ssh.unverified-host-key`): Paramiko is told to accept unknown SSH host keys (AutoAddPolicy / WarningPolicy). The first connection can be intercepted by a man-in-the-middle. - [Python SSRF: outbound request URL from request input](https://vetkit.dev/checks/vetkit.py.ssrf.request-input/) (`vetkit.py.ssrf.request-input`): An outbound HTTP request URL is taken from request input (server-side request forgery). - [Python SSTI: render_template_string with request input](https://vetkit.dev/checks/vetkit.py.ssti.request-template/) (`vetkit.py.ssti.request-template`): Request input is compiled as template source (render_template_string / Template). Template injection lets attackers run code on the server. - [Python pip install at runtime bypasses the lockfile](https://vetkit.dev/checks/vetkit.py.supply-chain.runtime-pip-install/) (`vetkit.py.supply-chain.runtime-pip-install`): The application installs a Python package at runtime by invoking pip. This bypasses the lockfile and the review of dependency changes; when the package name is computed (from configuration, a provider name or model output) the process can be made to install any package from the index, which runs arbitrary code. - [Python trust_remote_code=True runs Hub repository code](https://vetkit.dev/checks/vetkit.py.supply-chain.trust-remote-code/) (`vetkit.py.supply-chain.trust-remote-code`): A model, tokenizer, pipeline or dataset is loaded with trust_remote_code=True. The Hub repository's own Python code is downloaded and executed on load, so whoever controls (or hijacks) that repository runs code on this machine; an unpinned revision lets the code change at any time. - [Python tempfile.mktemp race condition](https://vetkit.dev/checks/vetkit.py.tempfile.mktemp/) (`vetkit.py.tempfile.mktemp`): tempfile.mktemp() is race-prone; another process can create the file first. - [Python TLS certificate verification disabled (verify=False)](https://vetkit.dev/checks/vetkit.py.tls.verification-disabled/) (`vetkit.py.tls.verification-disabled`): TLS certificate verification is disabled, enabling man-in-the-middle attacks. - [Python obsolete SSLv3, TLS 1.0 or TLS 1.1 protocol](https://vetkit.dev/checks/vetkit.py.tls.weak-protocol/) (`vetkit.py.tls.weak-protocol`): An obsolete SSL/TLS protocol version (SSLv2, SSLv3, TLS 1.0 or TLS 1.1) is selected or allowed. - [Python XPath injection from request input](https://vetkit.dev/checks/vetkit.py.xpath-injection.request-query/) (`vetkit.py.xpath-injection.request-query`): Request input is embedded into an XPath expression. Quotes in the value change the query (XPath injection). - [Django format_html with pre-interpolated string (XSS)](https://vetkit.dev/checks/vetkit.py.xss.format-html-prebuilt/) (`vetkit.py.xss.format-html-prebuilt`): format_html() receives a string that was already interpolated, so the inserted values are not escaped (XSS). - [Jinja2 autoescape=False leaves templates open to XSS](https://vetkit.dev/checks/vetkit.py.xss.jinja2-autoescape-disabled/) (`vetkit.py.xss.jinja2-autoescape-disabled`): A Jinja2 environment is created with autoescape=False. If it renders HTML, every variable is inserted unescaped (XSS). - [Django mark_safe on non-literal value causes XSS](https://vetkit.dev/checks/vetkit.py.xss.mark-safe/) (`vetkit.py.xss.mark-safe`): A non-literal value is marked as safe HTML, bypassing template auto-escaping (XSS). - [Python reflected XSS: request input in HTML response](https://vetkit.dev/checks/vetkit.py.xss.request-to-html-response/) (`vetkit.py.xss.request-to-html-response`): Request input is written into an HTML response without escaping. This is reflected cross-site scripting. - [Python XML parser external entities enabled (XXE)](https://vetkit.dev/checks/vetkit.py.xxe.external-entities-enabled/) (`vetkit.py.xxe.external-entities-enabled`): An XML parser is configured to resolve external entities or fetch DTDs. Untrusted XML can then read local files or reach internal hosts (XXE). - [Redis listening on all interfaces without a password](https://vetkit.dev/checks/vetkit.redis.network.exposed-without-auth/) (`vetkit.redis.network.exposed-without-auth`): Redis listens on all network interfaces but no password or ACL is configured. Anyone who can reach the port can read and change all data and, through CONFIG/MODULE commands, often run code on the host. - [Redis protected-mode no without bind or password](https://vetkit.dev/checks/vetkit.redis.network.protected-mode-off/) (`vetkit.redis.network.protected-mode-off`): Redis protected mode is off while no bind address or password is configured. Any network client can run commands without authenticating. - [Node.js synchronous blocking call in a request handler](https://vetkit.dev/checks/vetkit.resilience.blocking-call-in-handler.js-handler/) (`vetkit.resilience.blocking-call-in-handler.js-handler`): `$FN` runs synchronously inside a request handler. Node.js serves every request of the process on one thread, so while this call reads or writes a file, waits for a child process or hashes (bcrypt, scrypt and PBKDF2 take tens to hundreds of milliseconds by design), no other request is handled. - [Node.js bcrypt hashSync blocks the event loop on login](https://vetkit.dev/checks/vetkit.resilience.blocking-call-in-handler.js-password-hash/) (`vetkit.resilience.blocking-call-in-handler.js-password-hash`): `$FN` hashes a password synchronously. Password checks run on the login and sign-up request path, and bcrypt's cost factor makes each call take tens to hundreds of milliseconds, during which the Node.js process serves no other request. - [Python blocking call inside async def blocks the event loop](https://vetkit.dev/checks/vetkit.resilience.blocking-call-in-handler.py-async/) (`vetkit.resilience.blocking-call-in-handler.py-async`): `$CALL` blocks inside a coroutine. Async frameworks (FastAPI, Starlette, aiohttp, Django async views) serve every request of a worker on one event loop thread, so while this call waits on the network, a timer or a child process, or hashes a password, no other request on that worker makes progress. - [Node.js database client created inside request handler](https://vetkit.dev/checks/vetkit.resilience.db-client-per-request.js-handler/) (`vetkit.resilience.db-client-per-request.js-handler`): `$CLIENT` is created inside a request handler. Every request then opens its own database connections (or a whole pool) and pays for the handshake and authentication, and under load the connections pile up until the database refuses new ones. - [Python new database connection per route request](https://vetkit.dev/checks/vetkit.resilience.db-client-per-request.py-route/) (`vetkit.resilience.db-client-per-request.py-route`): `$CALL` opens a new database connection or client inside the route handler `$F`, so every request pays for a TCP and TLS handshake and authentication, and concurrent requests can exhaust the database's connection limit. - [Go http.Client without Timeout blocks indefinitely](https://vetkit.dev/checks/vetkit.resilience.http-call-without-timeout.go-client-literal/) (`vetkit.resilience.http-call-without-timeout.go-client-literal`): `http.Client` is created without a `Timeout` and used in the same function for requests that carry no context deadline, so a slow or unresponsive server blocks the call indefinitely. - [Go http.DefaultClient has no timeout](https://vetkit.dev/checks/vetkit.resilience.http-call-without-timeout.go-default-client/) (`vetkit.resilience.http-call-without-timeout.go-default-client`): `$CALL` sends the request through `http.DefaultClient`, which has no timeout. A slow or unresponsive server keeps the goroutine, its connection and everything waiting on the result blocked indefinitely. - [Java HttpClient.newHttpClient() without connect timeout](https://vetkit.dev/checks/vetkit.resilience.http-call-without-timeout.java-httpclient/) (`vetkit.resilience.http-call-without-timeout.java-httpclient`): `HttpClient.newHttpClient()` creates a client without a connect timeout, and its requests have no response timeout unless each `HttpRequest` sets one, so an unresponsive server blocks the caller indefinitely. - [Java new RestTemplate() has no connect or read timeout](https://vetkit.dev/checks/vetkit.resilience.http-call-without-timeout.java-resttemplate/) (`vetkit.resilience.http-call-without-timeout.java-resttemplate`): `new RestTemplate()` uses the JDK's default `HttpURLConnection` settings, which have no connect or read timeout, so a slow or unresponsive upstream blocks the calling thread (and the request it serves) indefinitely. - [axios request without timeout waits indefinitely](https://vetkit.dev/checks/vetkit.resilience.http-call-without-timeout.js-axios-call/) (`vetkit.resilience.http-call-without-timeout.js-axios-call`): An axios request is sent without a `timeout` through the global axios instance, whose default is to wait indefinitely. A slow or unresponsive upstream keeps the request, and whatever is waiting on it, open forever. - [axios.create without timeout waits indefinitely](https://vetkit.dev/checks/vetkit.resilience.http-call-without-timeout.js-axios-create/) (`vetkit.resilience.http-call-without-timeout.js-axios-create`): `axios.create` builds an HTTP client without a `timeout`. axios waits indefinitely by default, so a slow or unresponsive upstream keeps each request, and whatever is waiting on it, open forever. - [PHP Guzzle Client without timeout waits indefinitely](https://vetkit.dev/checks/vetkit.resilience.http-call-without-timeout.php-guzzle/) (`vetkit.resilience.http-call-without-timeout.php-guzzle`): `GuzzleHttp\Client` is created without a `timeout`. Guzzle's default of 0 waits indefinitely, so a slow or unresponsive upstream holds the PHP worker serving this request until the web server kills it. - [Python requests call without timeout hangs forever](https://vetkit.dev/checks/vetkit.resilience.http-call-without-timeout.py-requests/) (`vetkit.resilience.http-call-without-timeout.py-requests`): `$CALL` is called without a timeout. Requests waits forever by default, so a single slow or unresponsive upstream can hold this worker, and every request queued behind it, indefinitely. - [Python httpx and aiohttp timeout explicitly disabled](https://vetkit.dev/checks/vetkit.resilience.http-call-without-timeout.py-timeout-disabled/) (`vetkit.resilience.http-call-without-timeout.py-timeout-disabled`): `$CALL` explicitly disables the client's timeout. httpx and aiohttp time out by default; turning that off lets a single slow or unresponsive upstream hold the request open indefinitely. - [Python urlopen without timeout blocks indefinitely](https://vetkit.dev/checks/vetkit.resilience.http-call-without-timeout.py-urlopen/) (`vetkit.resilience.http-call-without-timeout.py-urlopen`): `$CALL` is called without a timeout. It then falls back to the global socket default, which is no timeout at all unless the process sets one, so an unresponsive server blocks the caller indefinitely. - [axios.defaults.timeout set globally (internal marker)](https://vetkit.dev/checks/vetkit.resilience.marker.axios-default-timeout/) (`vetkit.resilience.marker.axios-default-timeout`): axios.defaults.timeout is set (vetkit internal marker, never reported). - [Rails http_basic_authenticate_with hardcoded password](https://vetkit.dev/checks/vetkit.ruby.auth.http-basic-literal-password/) (`vetkit.ruby.auth.http-basic-literal-password`): http_basic_authenticate_with uses a hard-coded password literal. Anyone with source access knows it and it cannot be rotated without a deploy. - [Rails constantize on request input enables code execution](https://vetkit.dev/checks/vetkit.ruby.code-injection.constantize/) (`vetkit.ruby.code-injection.constantize`): A class is looked up from request input (constantize / const_get). Attackers can instantiate or call arbitrary classes, a known path to remote code execution. - [Ruby send and public_send with request-controlled method](https://vetkit.dev/checks/vetkit.ruby.code-injection.dynamic-send/) (`vetkit.ruby.code-injection.dynamic-send`): A method name taken from request input is invoked with send / public_send / try. Attackers can call any method on the object, such as destroy, update_columns or exit. - [Ruby eval of request input: code injection](https://vetkit.dev/checks/vetkit.ruby.code-injection.eval/) (`vetkit.ruby.code-injection.eval`): Ruby code is evaluated from request input (code injection). An attacker can run arbitrary code in the application process. - [Ruby command injection from request input in shell command](https://vetkit.dev/checks/vetkit.ruby.command-injection.interpolation/) (`vetkit.ruby.command-injection.interpolation`): A shell command is built from request input (command injection). An attacker can append shell metacharacters to run arbitrary commands. - [Ruby Kernel#open with request input runs shell commands](https://vetkit.dev/checks/vetkit.ruby.command-injection.kernel-open/) (`vetkit.ruby.command-injection.kernel-open`): Kernel#open / IO.read receives request input. A value starting with "|" runs a shell command, and any other value reads an arbitrary file. - [Rails cookie with secure or httponly disabled](https://vetkit.dev/checks/vetkit.ruby.cookie.insecure-flags/) (`vetkit.ruby.cookie.insecure-flags`): A cookie or the session store is configured with secure / httponly explicitly disabled. The cookie may travel over plain HTTP or be read by injected JavaScript. - [Ruby rand and Random used to generate security tokens](https://vetkit.dev/checks/vetkit.ruby.crypto.insecure-random-token/) (`vetkit.ruby.crypto.insecure-random-token`): A token, password, salt or nonce is generated with a non-cryptographic random source (rand / Random / Array#sample / shuffle), so it can be predicted. - [Ruby OpenSSL cipher with constant IV](https://vetkit.dev/checks/vetkit.ruby.crypto.static-iv/) (`vetkit.ruby.crypto.static-iv`): A cipher is given a constant initialization vector. Reusing an IV with the same key leaks plaintext relationships (and breaks GCM/CTR completely). - [Ruby weak cipher: DES, RC4, Blowfish or ECB mode](https://vetkit.dev/checks/vetkit.ruby.crypto.weak-cipher/) (`vetkit.ruby.crypto.weak-cipher`): A broken cipher or ECB mode is used (DES, 3DES, RC2, RC4, Blowfish, *-ECB). ECB leaks plaintext patterns and the others are breakable. - [Ruby password hashed with MD5 or SHA-1](https://vetkit.dev/checks/vetkit.ruby.crypto.weak-password-hash/) (`vetkit.ruby.crypto.weak-password-hash`): A password is hashed with MD5/SHA-1, which is trivially brute-forced. - [Rails protect_from_forgery with: :null_session](https://vetkit.dev/checks/vetkit.ruby.csrf.null-session/) (`vetkit.ruby.csrf.null-session`): protect_from_forgery uses with: :null_session, so requests with a bad token run with an empty session instead of failing. Cookie-based authentication outside the session stays usable. - [Rails CSRF protection disabled in controller or config](https://vetkit.dev/checks/vetkit.ruby.csrf.protection-disabled/) (`vetkit.ruby.csrf.protection-disabled`): CSRF protection is skipped for a browser-facing controller (or disabled in configuration). Any site can submit state-changing requests on behalf of a logged-in user. - [Ruby JSON create_additions and Oj object mode deserialization](https://vetkit.dev/checks/vetkit.ruby.deserialization.json-create-additions/) (`vetkit.ruby.deserialization.json-create-additions`): JSON / Oj parsing is configured to create Ruby objects from the document (create_additions or Oj object mode). Untrusted JSON can then instantiate arbitrary classes. - [Ruby Marshal and YAML.unsafe_load insecure deserialization](https://vetkit.dev/checks/vetkit.ruby.deserialization.unsafe-load/) (`vetkit.ruby.deserialization.unsafe-load`): Request data is deserialized with Marshal / YAML.unsafe_load / Oj object mode / JSON.load, which can instantiate arbitrary objects and lead to remote code execution. - [Ruby YAML.load and Psych.load on request data](https://vetkit.dev/checks/vetkit.ruby.deserialization.yaml-load-request/) (`vetkit.ruby.deserialization.yaml-load-request`): Request data is parsed with YAML.load / Psych.load. Before Psych 4 (Ruby < 3.1) this instantiates arbitrary Ruby objects and can lead to remote code execution. - [Ruby JWT.decode with verification disabled or none algorithm](https://vetkit.dev/checks/vetkit.ruby.jwt.verification-disabled/) (`vetkit.ruby.jwt.verification-disabled`): JWT.decode is called with signature verification disabled or the "none" algorithm, so anyone can forge tokens. - [Rails permit! and permit_all_parameters mass assignment](https://vetkit.dev/checks/vetkit.ruby.mass-assignment.permit-all/) (`vetkit.ruby.mass-assignment.permit-all`): Strong-parameter filtering is disabled (permit! / permit_all_parameters). Every attribute in the request, such as admin or role, becomes mass-assignable. - [Rails mass assignment from raw params without permit](https://vetkit.dev/checks/vetkit.ruby.mass-assignment.unfiltered-params/) (`vetkit.ruby.mass-assignment.unfiltered-params`): A model is created or updated from a raw params hash without permit. Rails 4+ rejects this at runtime, but in Sinatra / Grape or with permit_all_parameters it is mass assignment. - [Rails open redirect from request params](https://vetkit.dev/checks/vetkit.ruby.open-redirect.params/) (`vetkit.ruby.open-redirect.params`): A redirect target is taken from request params (open redirect). Attackers can craft links on your domain that forward victims to a phishing site. - [Ruby path traversal: request input in file path](https://vetkit.dev/checks/vetkit.ruby.path-traversal.file-access/) (`vetkit.ruby.path-traversal.file-access`): A file path used to read, write, send or delete a file comes from request input (path traversal). Attackers can use ../ sequences or absolute paths to reach other files. - [Rails render file: with request input (path traversal)](https://vetkit.dev/checks/vetkit.ruby.path-traversal.render-file/) (`vetkit.ruby.path-traversal.render-file`): render file: receives request input, so any file on the server can be rendered (path traversal / local file disclosure). - [Rails render template chosen by request input](https://vetkit.dev/checks/vetkit.ruby.path-traversal.render-template/) (`vetkit.ruby.path-traversal.render-template`): The template or partial to render is chosen by request input. Attackers can render templates that were never meant to be reachable (and on old Rails, arbitrary files). - [Ruby binding.pry, byebug or debugger left in code](https://vetkit.dev/checks/vetkit.ruby.quality.debugger-leftover/) (`vetkit.ruby.quality.debugger-leftover`): A debugger breakpoint (binding.pry, binding.irb, byebug, debugger) was left in the code. - [Ruby empty rescue clause silently discards errors](https://vetkit.dev/checks/vetkit.ruby.quality.empty-rescue/) (`vetkit.ruby.quality.empty-rescue`): The rescue clause is empty, so the error is silently discarded. - [Ruby rescue Exception catches SystemExit and signals](https://vetkit.dev/checks/vetkit.ruby.quality.rescue-exception/) (`vetkit.ruby.quality.rescue-exception`): `rescue Exception` also rescues SignalException, SystemExit and NoMemoryError, so the process can no longer be interrupted or shut down cleanly. - [Rails hardcoded secret_key_base in source code](https://vetkit.dev/checks/vetkit.ruby.rails.hardcoded-secret-key-base/) (`vetkit.ruby.rails.hardcoded-secret-key-base`): secret_key_base / secret_token is set to a string literal in code. Anyone with the source can forge signed cookies and sessions and decrypt encrypted ones. - [Rails consider_all_requests_local = true in production](https://vetkit.dev/checks/vetkit.ruby.rails.production-detailed-errors/) (`vetkit.ruby.rails.production-detailed-errors`): config.consider_all_requests_local is true in the production environment, so every visitor gets full exception pages with source, parameters and environment details. - [Rails config.force_ssl = false in production disables HTTPS](https://vetkit.dev/checks/vetkit.ruby.rails.production-force-ssl-disabled/) (`vetkit.ruby.rails.production-force-ssl-disabled`): config.force_ssl is explicitly false in the production environment, so HTTPS, HSTS and secure cookies are not enforced by Rails. - [Ruby regex injection and ReDoS from request input](https://vetkit.dev/checks/vetkit.ruby.regex.injection/) (`vetkit.ruby.regex.injection`): A regular expression is compiled from request input. Attackers can supply a catastrophic pattern (ReDoS) or alter the match logic. - [Ruby regex ^ and $ anchors let newline input pass validation](https://vetkit.dev/checks/vetkit.ruby.regex.multiline-anchor-validation/) (`vetkit.ruby.regex.multiline-anchor-validation`): Request input is validated with a regex anchored by ^ / $, which match at line breaks in Ruby. A value with an embedded newline passes the check (use \A and \z). - [Rails format validation multiline: true bypass with newline](https://vetkit.dev/checks/vetkit.ruby.regex.multiline-format-validation/) (`vetkit.ruby.regex.multiline-format-validation`): A format validation opts into multiline: true, allowing ^ / $ anchors that match at line breaks. Values with an embedded newline can pass the validation. - [Ruby Arel.sql with request input causes SQL injection](https://vetkit.dev/checks/vetkit.ruby.sql-injection.arel-sql/) (`vetkit.ruby.sql-injection.arel-sql`): Request input is wrapped in Arel.sql / SqlLiteral, which marks it as trusted raw SQL (SQL injection). - [Rails ActiveRecord SQL injection via string interpolation](https://vetkit.dev/checks/vetkit.ruby.sql-injection.interpolation/) (`vetkit.ruby.sql-injection.interpolation`): Request input is built into an ActiveRecord / SQL query string (SQL injection). An attacker can read or modify arbitrary database rows. - [Rails SQL injection in order and pluck from request input](https://vetkit.dev/checks/vetkit.ruby.sql-injection.order-clause/) (`vetkit.ruby.sql-injection.order-clause`): Request input is used as a raw ORDER BY / pluck expression (SQL injection). Rails 6.1+ rejects most non-column strings, older versions execute them verbatim. - [Ruby Sequel raw SQL string injection from request input](https://vetkit.dev/checks/vetkit.ruby.sql-injection.sequel/) (`vetkit.ruby.sql-injection.sequel`): Request input is built into a raw Sequel SQL string or literal (SQL injection). Sequel only escapes values passed as placeholders or in dataset filters. - [Ruby SSRF: HTTP request to a URL from request input](https://vetkit.dev/checks/vetkit.ruby.ssrf.request-url/) (`vetkit.ruby.ssrf.request-url`): An outbound HTTP request is sent to a URL taken from request input (server-side request forgery). Attackers can reach internal services and cloud metadata endpoints. - [Ruby SSTI: ERB.new or render inline with request input](https://vetkit.dev/checks/vetkit.ruby.template-injection.request-input/) (`vetkit.ruby.template-injection.request-input`): Request input is compiled as a template (ERB.new / render inline: / Haml / Slim). Template code runs Ruby, so this is server-side template injection leading to code execution. - [Ruby HTTP client verify: false disables TLS verification](https://vetkit.dev/checks/vetkit.ruby.tls.http-client-verification-disabled/) (`vetkit.ruby.tls.http-client-verification-disabled`): TLS certificate verification is disabled for an HTTP client (verify: false / verify_ssl: false / ssl_verify_peer: false), enabling man-in-the-middle attacks. - [Ruby VERIFY_NONE behind a flag or env check in production](https://vetkit.dev/checks/vetkit.ruby.tls.verification-disabled-guarded/) (`vetkit.ruby.tls.verification-disabled-guarded`): TLS peer verification is disabled behind a configuration flag or environment check (`VERIFY_NONE if setting`, `verify: false` under `Rails.env.development?`). The insecure path is reachable whenever that flag is set in production. - [Ruby OpenSSL::SSL::VERIFY_NONE disables TLS verification](https://vetkit.dev/checks/vetkit.ruby.tls.verify-none/) (`vetkit.ruby.tls.verify-none`): TLS peer verification is disabled (OpenSSL::SSL::VERIFY_NONE). - [Rails ERB raw and <%== print request data, causing XSS](https://vetkit.dev/checks/vetkit.ruby.xss.erb-raw-request/) (`vetkit.ruby.xss.erb-raw-request`): An ERB template prints request data without escaping (<%== / raw / html_safe), allowing reflected XSS. - [Rails html_safe and raw on dynamic strings cause XSS](https://vetkit.dev/checks/vetkit.ruby.xss.html-safe/) (`vetkit.ruby.xss.html-safe`): A non-literal string is marked html_safe / passed to raw, bypassing escaping (XSS). - [Rails link_to with request param allows javascript: XSS](https://vetkit.dev/checks/vetkit.ruby.xss.link-to-request-url/) (`vetkit.ruby.xss.link-to-request-url`): link_to uses a request parameter as the link target. Rails does not block javascript: URLs in href, so the parameter can inject script (XSS). - [Ruby Redcarpet without filter_html marked html_safe: XSS](https://vetkit.dev/checks/vetkit.ruby.xss.markdown-unsanitized/) (`vetkit.ruby.xss.markdown-unsanitized`): Markdown rendered by Redcarpet without `filter_html` / `escape_html` is marked html_safe (XSS). Markdown passes raw HTML through, so `