35 lines
2.3 KiB
Python
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))
|