T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/run_interview.py:305
- Finding
- Excessive Persistence of Raw ASR Provider Responses<![CDATA[ ## Vulnerability Details **File Location**: `scripts/run_interview.py:305-313`, `scripts/run_interview.py:423-434`, and `scripts/run_interview.py:451-463` **Vulnerability Type**: Sensitive-data over-retention and insecure local storage **Risk Level**: Medium ### Vulnerable Code ```python payload = response.json() text = payload.get("text", "").strip() if not text and payload.get("segments"): text = " ".join(seg.get("text", "").strip() for seg in payload["segments"]).strip() if not text: raise ValueError("ASR 未返回可用文本") return {"text": text, "raw": payload} ``` ```python asr_result = transcribe_audio(audio_path, config["language"]) answer_text = asr_result["text"] asr_raw = asr_result["raw"] ``` ```python turn = { "round_id": round_id, "question_type": current_question_type, "interviewer_question": current_question, "interviewer_audio": tts_path, "asr_text": answer_text, "asr_raw": asr_raw, "evaluation": evaluation, "decision": decision, } turns.append(turn) ``` ```python payload = { "config": config, "closing_text": closing_text, "turns": turns, "final_report": final_report, "report_summary_tts_audio": report_tts, } if args.save_report: report_path = Path(args.save_report) else: OUTPUT_DIR.mkdir(parents=True, exist_ok=True) report_path = OUTPUT_DIR / "final_report.json" report_path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8") ``` ### Technical Analysis The ASR function returns both the normalized transcript and the complete response received from the external ASR provider. The complete response is subsequently assigned to `asr_raw`, inserted into every turn record, and written to the final JSON report. The interview workflow only requires the normalized transcript for evaluation and question generation. Retaining the complete provider response therefore exceeds the minimum data required for the declared functionality. Depending on the prov ...[truncated 1596 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Return and retain only the normalized transcript by default: ```python return {"text": text} ``` 2. Remove `asr_raw` from the persisted turn structure: ```python turn = { "round_id": round_id, "question_type": current_question_type, "interviewer_question": current_question, "interviewer_audio": tts_path, "asr_text": answer_text, "evaluation": evaluation, "decision": decision, } ``` 3. If raw ASR diagnostics are operationally necessary, make storage explicitly opt-in through a clearly documented debugging option. 4. Before storing an opted-in raw response, allowlist required fields rather than serializing the provider response wholesale. 5. Document what interview data is sent to third parties, what is written locally, and how long it should be retained. 6. Create reports with restrictive file permissions and recommend storage in a private, access-controlled directory. 7. Provide a cleanup or retention mechanism for generated reports and synthesized audio files. ]]>
