T09 · Insecure Skill Coding Practices
- Location
test_save_system.py:13- Finding
Test Scripts Overwrite and Delete Production Save Data
- Content
View full analysis
Vulnerability Details
File Location:
test_save_system.py:13, 118-120, 217-218, 232-233
Vulnerability Type: Test/production data-path collision causing destructive file operations
Risk Level: MediumVulnerable Code
python # Test directory SAVE_DIR = "./sms-rpg-saves"python filepath = os.path.join(SAVE_DIR, f"save_{slot:03d}.json") with open(filepath, 'w', encoding='utf-8') as f: json.dump(save_data, f, ensure_ascii=False, indent=2)python # Create test save create_test_save(1)python # Clean up test save delete_save(1)The duplicate script at
scripts/test_save_system.pycontains the same vulnerable logic at the same line numbers.Technical Analysis
The test script uses
./sms-rpg-saves, which is also the production save directory specified by the Skill. When executed from the project directory,create_test_save(1)openssave_001.jsonin write mode. Python'sopen(..., 'w')truncates an existing file before writing the test fixture, without checking whether it contains user data.At the end of execution,
delete_save(1)removes that same file. The test therefore lacks isolation from production data and performs destructive operations on a predictable production path. Both copies of the script independently expose this behavior.Attack Path
- A user has a legitimate game save at
./sms-rpg-saves/save_001.json. - The user, an automated test runner, or an Agent invokes either bundled test script from the project directory.
create_test_save(1)opens the legitimate save with write mode and replaces it with fixture data.- The script performs its update test against the replacement data.
- Cleanup calls
delete_save(1). - The slot-1 save is permanently removed unless an external backup exists.
No elevated privileges, network access, or attacker-supplied input are required.
Impact Assessment
The vulnerability permits destruction of data writable by the process running th ...[truncated 374 chars]
- A user has a legitimate game save at
- Remediation
View remediation
Remediation Suggestions
- Isolate every test run with a temporary directory:
python import tempfile from pathlib import Path def run_tests(): with tempfile.TemporaryDirectory(prefix="sms-rpg-test-") as temp_dir: save_dir = Path(temp_dir) # Pass save_dir explicitly to all save functions.- Refactor save functions to accept a directory argument rather than relying on a production-path global:
python def create_test_save(save_dir, slot=1): filepath = save_dir / f"save_{slot:03d}.json"-
Never use
./sms-rpg-savesas the default test target. If a persistent test directory is required, use an unmistakably separate path such as./.test-data/sms-rpg-saves. -
Add a safety check that refuses to run destructive tests when the resolved test directory equals the production save directory.
-
Avoid unconditional overwrite. Create test fixtures with exclusive creation mode (
'x') or unique generated filenames. -
Restrict cleanup to a temporary directory created and owned by the current test run. Do not delete predictable production filenames.
-
Apply the same correction to
scripts/test_save_system.py, or remove the duplicate script to prevent the vulnerable implementation from remaining callable. -
Add a regression test that places a sentinel file in the production save directory, runs the test suite against an isolated directory, and verifies that the sentinel remains unchanged.
