fix(c2): redteam-friendly verify_tls default (sprint 10) #12
Reference in New Issue
Block a user
Delete Branch "sprint/10-c2-tls-default"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Fix 1 —
verify_tlsdefaultMimic est un BAS lab tool dont le workflow dominant est un Mythic auto-hébergé avec certificat self-signed. L'ancien default
verify_tls=Trueà chaque couche cassait silencieusement la première connexion Test (CERTIFICATE_VERIFY_FAILED) tant que l'opérateur n'avait pas remarqué la checkbox. Sprint 10 aligne le default sur le workflow réel.C2ConfigCard.tsx), 1 ligneSPEC.md.0008:server_defaultflippé àsa.false()viaop.batch_alter_table(SQLite). Round-tripupgrade → downgrade → upgradetesté. Les lignes existantes ne sont pas mutées (valeur stockée préservée).urllib3.disable_warnings(InsecureRequestWarning)gated surnot verify_tlsdansMythicAdapter.__init__. Pas de suppression module-level.Fix 2 —
/graphql→/graphql/(HTTP 301 fix)Bug surface en user testing avec un Mythic réel à
https://192.168.10.60:7443:test_connectionretournaitHTTP 301. Cause confirmée à 92 % par un workflow diagnostic (lecture adapter + WebFetch source canonique Mythic_Scripting), puis confirmée par l'utilisateur viacurl -kv(Location header :/graphql/)."/graphql"sans slash final. Le client officielmythic_utilities.get_http_transportutilisef"{...}:{port}/graphql/"(slash REQUIS). Nginx Mythic 3.x retourne301pour la canonicalisation.allow_redirects=Falsedu sprint 8 (défense SSRF intentionnelle, gardée) faisait surface le 301 raw au lieu de le suivre.mythic.py:119+ maj du commentaire de pinning + 3 fichiers de tests + 1 nouveau test de régression.Reviews : code-review APPROVED + 1 NIT non-bloquant ; design-review APPROVED (0 finding) ; spec-review APPROVED post-amendement (
SPEC.md:85ligne du default mise à jour).Test plan
test_mythic_adapter_url_has_trailing_slash).ruff+mypy --strictclean.tsc --noEmit+eslint --max-warnings=0clean.alembic upgrade head→downgrade -1→upgrade headsur SQLite fresh, OK.Comment tester en local
Scénarios :
https://<lab>:7443, paste un token, laisse la box décochée,Save→Test connection→ réponse{ ok: true }(FakeAdapter répond toujours OK, en prod-live le cert self-signed n'est plus rejeté). Tail backend stderr : 0InsecureRequestWarning(suppression engagée).Save,Test connectioncontre un cert self-signed → réponse{ ok: false, error: "<SSLError CERTIFICATE_VERIFY_FAILED>" }. Prouve que le flag est toujours honoré bout-en-bout.alembic upgrade headpuispragma table_info(c2_config)(SQLite) →verify_tlsdefault0. PuisINSERT INTO c2_config (engagement_id, url, api_token_encrypted) VALUES (1, 'https://x', 'y')→ la row auraverify_tls = 0.verify_tls = 1AVANT cette migration reste à1. L'opérateur qui veut basculer doit explicitement re-Save la config avec la box décochée.403sur/api/engagements/<id>/c2-config*. Aucun changement.Fichiers touchés
SPEC.md:85verify_tls défaut true→défaut false+ justificationbackend/app/models/c2_config.py:22default=True→default=Falsebackend/app/api/c2.py:87True→Falsebackend/app/services/c2/factory.py:9verify_tls: bool = True→Falsebackend/app/services/c2/mythic.py:18,19,116,122-125True→False+urllib3import +disable_warnings(InsecureRequestWarning)gated surnot verify_tlsbackend/migrations/versions/0008_c2_verify_tls_default_false.pyserver_defaultflippé viabatch_alter_tablebackend/tests/test_c2_config.pyis False(renaméedefault_false) ; tests qui PUTverify_tls=Trueexplicitement laissés intactsfrontend/src/components/C2ConfigCard.tsxuseState(false)+ delete-resetfalse+ helper text MITM entext-graphitemirror FormField hintSecurity tradeoff acknowledged
Default sécu-relevant flippé en pleine conscience :
tasks/todo.md§ Decisions + ce PR body.security-guidance@claude-code-pluginsa flagged 3 fois (HIGH × frontend useState, HIGH × API fallback, MEDIUM × adapter/factory/model/migration). Conditions de "proceed without changes" du plugin elles-mêmes remplies : user a explicitement demandé le flip + tradeoff surfacé dans l'UI.verify_tls=truenon mutées par la migration — defense in depth pour qui aurait déjà bouclé sa config en mode strict.NITs reportés (non-bloquants, polish sprint éventuel)
test_c2_config.py:209— renamertest_get_config_verify_tls_default_falseentest_get_config_verify_tls_roundtrip_false(le test PUT explicitement la valeur, ne teste pas le default ORM). Optionnel ; cosmétique.mythic.py:122-125—urllib3.disable_warningsest process-global. Alternative cleaner :warnings.catch_warnings()dans_post(). Plus de code pour bénéfice marginal (aucun autre caller urllib3 dans Mimic). Skipped.test_migration_0008_c2.pyabsent vs 0006/0007 ont chacun le leur. 0008 est 10 lignes, round-trip déjà confirmé manuellement, faible risque. Skipped.Commits
🤖 Generated with Claude Code