Files
Investidor-V2/tools/portal-qa-manual-mfa-diagnosis.py
T
nala 20971d523f
tests / ci (push) Canceled after 0s
oportunidades 6
2026-10-10 21:17:46 +02:00

35 lines
2.3 KiB
Python

"""Read only sanitized QA traces; no auth requests, submitted values or secrets."""
import json, time
from datetime import datetime, timezone
from pathlib import Path
root=Path(__file__).resolve().parent.parent
private=root/'storage/app/private/investmoz-v2/portal-audit'
rows=[]
for file in sorted(private.glob('auth-session-trace-qa*.jsonl')):
for attempt in range(10):
try:
content=file.read_text(encoding='utf-8'); break
except PermissionError:
if attempt==9: raise
time.sleep(.1)
for line in content.splitlines():
try: row=json.loads(line)
except json.JSONDecodeError: continue # Concurrent append: incomplete final line, never infer success.
if row['at_utc']>='2026-10-10T15:00:00' and row['path']=='/two-factor-challenge' and row['method']=='POST' and (row.get('loaded') or {}).get('pending_mfa_user')==18:
rows.append(row)
failed=sorted([r for r in rows if not (r.get('after') or {}).get('authenticated_user')],key=lambda r:r['at_utc'])[-5:]
def window(row): return int(datetime.fromisoformat(row['at_utc']).timestamp())//30
successes=[r for r in rows if (r.get('after') or {}).get('authenticated_user')==18]
proof={'captured_at':datetime.now(timezone.utc).isoformat(),'case':'C37','active_writes':0,'secrets_or_codes_recorded':False,
'failed_mfa_requests':[{'at_utc':r['at_utc'],'trace':r['trace'],'status':r['status'],'redirect':r['redirect'],
'pending_actor_before':r['loaded']['pending_mfa_user'],'pending_actor_after':r['after']['pending_mfa_user'],
'authenticated_actor':r['after']['authenticated_user'],'session_preserved':r['loaded']['session']==r['after']['session'],
'mfa_input_check':r.get('mfa_input_check'),
'prior_success_same_30s_window':[s['at_utc'] for s in successes if window(s)==window(r) and s['at_utc']<=r['at_utc']],
'qa_target':r['qa_target'],'cookie_name_counts':r['cookie_name_counts']} for r in failed]}
proof['temporal_coincidence_is_not_code_reuse_proof']=True
out=private/'c37-manual-mfa-rejection-20261010.json'
if out.exists():out.with_name('c37-manual-mfa-rejection-'+datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')+'.json').write_bytes(out.read_bytes())
out.write_text(json.dumps(proof,ensure_ascii=False,indent=2),encoding='utf-8')
print(json.dumps(proof))