fix(security): stop credential/PII leaks at capture, persistence and replay
SA
2mo ago+263+263+012345678901234567890123456789-22-22-01234567890123456789
Problem
Recorded credentials and PII currently leak on three independent paths:
semanticInfo.valuecarries the RAW value of every field — including passwords. The step's ownvalueis masked to********, but thesemanticInfoobject embedded in the same event still contains the cleartext, which is stored in the session log, dumped to the page console (console.log("Sending CUSTOM_INPUT_EVENT:", inputData)), and shipped to the local recorder server.- Masking only covers
input[type=password]. OTP fields (type=text/tel+autocomplete=one-time-code), credit-card/CVV fields (type=text/number), SSN/IBAN and password-named fields are recorded in cleartext. We verified this with a real recording where a phone number typed into atelfield landed verbatim in the saved.workflow.yaml. - High-confidence sensitive matches are persisted as plaintext defaults.
variable_identifierdeliberately setssuggested_default=Nonefor SSN/credit-card/password matches (confidence ≥ 0.95), but_generate_input_schemaoverrides that intent —entry['default'] = candidate.value— so the recorded secret is written into the saved workflow file anyway, taggedformat: ssn/credit-card.
On replay, input values (including ********-masked and unmasked ones) are logged at INFO and embedded in error reports verbatim on both executor paths.
Fix
Extension (capture):
- new
isSensitiveField(): checkstype,autocomplete(one-time-code,cc-number,cc-csc,cc-exp,new-password,current-password) and name/id/aria-label/placeholder conventions extractSemanticInfomasks the value of sensitive fields — the raw value never enters the event streamhandleInputmasks byisSensitiveFieldinstead oftype === 'password'only- per-event console dumps reduced to event-type-only lines (no payload objects)
Python (persistence + replay):
_generate_input_schemarespectssuggested_default=None: sensitive defaults are omitted instead of falling back to the raw recorded value- new
workflow_use/workflow/redaction.py:redact_step_value()masks values whose field hints look sensitive; wired into the semantic executor's input log,ErrorContext.input_value, and the deterministic controller's input log
No behavior change for non-sensitive fields.
Related: #165 (audit findings), #166, #168.
🤖 Generated with Claude Code
Summary by cubic
Prevents credential and PII leaks by masking sensitive values at capture, persistence, and replay. rrweb input events now use maskAllInputs, and logs/error reports no longer expose raw secrets; non-sensitive inputs behave the same.
- Bug Fixes
- Capture (extension): rrweb
maskAllInputs; broaden sensitive field detection (type, autocomplete, and name/label hints incl. tel/phone, EN/TR); masksemanticInfo.valueand input values; console logs omit payloads. - Persistence:
_generate_input_schemaomits defaults for sensitive types and for sensitive name/context hints; no'********'defaults; these inputs are forcedrequired. - Replay:
redact_step_valueredacts inputs in INFO logs and error reports using hints incl.elementText,elementTag,inputType; applied in the semantic executor, deterministic controller, and error context.
- Capture (extension): rrweb