T09 · Insecure Skill Coding Practices
- Location
scripts/self_check.py:13- Finding
Self-Check Recursively Deletes Existing Application State Without Explicit Consent
- Content
View full analysis
Vulnerability Details
File Location:
scripts/self_check.py, lines 13-16
Vulnerability Type: Destructive filesystem operation without explicit consent or state isolation
Risk Level: MediumVulnerable Code:
python def main() -> int: if f.STATE.exists(): shutil.rmtree(f.STATE) checks = {"signature": f.SIG, "birth": False, "loop": False, "propose_dry": False, "ok": False}The documented installation procedure directs users to execute the affected script:
bash npx clawhub@latest install deepseekoracle/lygo-forkling cd path/to/lygo-forkling python scripts/self_check.pyTechnical Analysis
The self-check uses
shutil.rmtree()to recursively and irreversibly remove the complete application state directory whenever it exists. It does not request confirmation, require the documented--i-consentoption, create a backup, or isolate tests in a temporary directory.The removed directory can contain the fork identity, fitness information, ledger records, and generation snapshots. The self-check then calls the normal birth and loop functions, replacing the deleted state with test-generated data. Consequently, successful completion may conceal the fact that pre-existing data was destroyed.
This behavior conflicts with the documented security boundary that writes to
state/require explicit consent. Although the path is derived from the installed project location rather than direct attacker input, the unsafe lifecycle design creates a reliable local data-loss condition.Attack Path
- A user has an existing
state/directory containing prior Forkling state and generation history. - The user follows the documented installation, update, or verification procedure and runs
python scripts/self_check.py. - The script detects the existing directory and passes it to
shutil.rmtree(). - All files and subdirectories under
state/are recursively deleted without ...[truncated 640 chars]
- A user has an existing
- Remediation
View remediation
Remediation Suggestions
- Run self-check operations inside a newly created temporary directory, such as one managed by
tempfile.TemporaryDirectory(). - Refactor state paths so tests can inject an isolated state root rather than using the production
f.STATEconstant. - Never recursively delete the operational state directory as part of a normal self-check.
- If a reset feature is required, expose it as a separate command with an explicit option such as
--reset-state --i-consent. - Display the exact directory that will be removed and require interactive confirmation unless a separately documented non-interactive override is provided.
- Create a verified backup before destructive operations and restore it if the self-check fails.
- Add a regression test that creates sentinel data in the operational state directory, runs the self-check, and verifies that the sentinel remains unchanged.
- Update the documentation to distinguish non-destructive verification from explicitly authorized state-reset operations.
- Run self-check operations inside a newly created temporary directory, such as one managed by
