T09 · Insecure Skill Coding Practices
- Location
scripts/main.py:395- Finding
Input Clinical Data Can Be Overwritten Without Safeguards
- Content
View full analysis
Vulnerability Details
File Location:
scripts/main.py:395-410
Vulnerability Type: Unrestricted output overwrite and loss of source-data integrity
Risk Level: HighVulnerable Code
python # Save output output_path = Path(args.output) if output_path.suffix.lower() == '.csv': df_cleaned.to_csv(args.output, index=False) elif output_path.suffix.lower() in ['.xlsx', '.xls']: df_cleaned.to_excel(args.output, index=False) else: # Default to CSV df_cleaned.to_csv(args.output, index=False) print(f"Cleaned data saved: {args.output}") # Save report cleaner.save_report(args.output)Technical Analysis
The application accepts independently controlled
--inputand--outputpaths but does not resolve and compare them before writing the cleaned dataset. Pandas output methods overwrite an existing destination by default. Consequently, selecting the source file itself as the output replaces the original clinical dataset.The implementation also does not require explicit authorization before replacing another existing output file and does not use an atomic temporary-file workflow. A failure during writing may therefore leave an incomplete or corrupted file.
This behavior conflicts with the project's own guidance in
references/common-patterns.md, which requires saving to a new file and preserving raw data. In a clinical-data workflow, preservation of source records is necessary for reproducibility, provenance, independent validation, and regulatory auditability.Attack Path
- An attacker, unsafe wrapper, or mistaken operator supplies a valid clinical dataset as
--input. - The same path is supplied for
--output, for example:bash python scripts/main.py \ --input clinical/raw_dm.csv \ --domain DM \ --output clinical/raw_dm.csv - The application reads the original file into memory.
- After transformation,
to_csv()or ...[truncated 1276 chars]
- An attacker, unsafe wrapper, or mistaken operator supplies a valid clinical dataset as
- Remediation
View remediation
Remediation Suggestions
-
Resolve and compare canonical input and output paths before processing:
python input_path = Path(args.input).expanduser().resolve() output_path = Path(args.output).expanduser().resolve() if input_path == output_path: parser.error("--output must be different from --input") -
Refuse to replace an existing output by default:
python if output_path.exists(): parser.error( f"Output already exists: {output_path}. " "Choose a new path or use an explicit overwrite option." ) -
If overwrite support is operationally necessary, require an explicit
--overwriteoption and continue to prohibit overwriting the input under all circumstances. -
Write to a temporary file in the destination directory, flush and synchronize it, validate that serialization completed successfully, and atomically rename it to the final destination.
-
Apply equivalent collision checks to the generated
.report.jsonpath. -
Record canonical input and output paths, source-file hash, output hash, software version, and overwrite authorization in the audit report.
-
Add automated tests covering identical paths, symlink aliases, relative-path aliases, pre-existing outputs, interrupted writes, and report-path collisions.
-
