T09 · Insecure Skill Coding Practices
- Location
drift_guard.py:210- Finding
Unbounded Drift History Growth Can Cause Local Resource Exhaustion
- Content
View full analysis
Vulnerability Details
File Location:
drift_guard.py, lines 210-221; related configuration inconfig_example.pydefinesmax_history_sizebut the monitor does not enforce it.
Vulnerability Type: Uncontrolled resource consumption and unbounded persistent storage
Risk Level: LowTechnical Analysis
Every call to
monitor()creates a measurement containing metrics and detailed drift data.record_measurement()appends that record to the in-memory history and then serializes the entire history back to disk:python record = { 'timestamp': time.time(), 'datetime': datetime.now().isoformat(), 'metrics': metrics, 'drift_score': drift_score, 'drift_details': drift_details } self.history.append(record) # Save to file history_path = Path(self.config.get('history_file', 'drift_history.json')) with open(history_path, 'w') as f: json.dump(self.history, f, indent=2)The provided configuration defines a finite default:
python # How many measurements to keep in history (0 = unlimited) 'max_history_size': 10000,However,
record_measurement()never reads or enforcesmax_history_size. Consequently, history grows without an effective bound even when an administrator believes a retention limit has been configured.The full history is also loaded into memory during initialization and rewritten on every measurement. As the file grows, each invocation consumes progressively more memory, CPU time, disk I/O, and storage. The cumulative write complexity becomes increasingly expensive because all prior records are serialized again for each new record.
Attack Path
- An attacker or untrusted integration obtains the ability to submit responses to a service or workflow that invokes
DriftGuard.monitor(). - The attacker repeatedly submits responses, causing
record_measurement()to append a new entry for every invocation. - The configured `max_history_ ...[truncated 1179 chars]
- An attacker or untrusted integration obtains the ability to submit responses to a service or workflow that invokes
- Remediation
View remediation
Remediation Suggestions
Enforce the configured retention limit before persisting history:
python self.history.append(record) max_history_size = int(self.config.get('max_history_size', 10000)) if max_history_size > 0: self.history = self.history[-max_history_size:]Additional hardening should include:
- Validate that
max_history_sizeis a non-negative integer and reject invalid configuration values. - Use an append-oriented format such as JSON Lines instead of rewriting the complete history for every measurement.
- Implement file rotation based on record count, file size, or age.
- Set an explicit maximum history-file size and fail safely or rotate the file when the limit is reached.
- Write updates atomically through a temporary file followed by replacement to reduce corruption risk during interrupted writes.
- Apply file locking if concurrent monitor processes can write to the same history file.
- Add automated tests verifying that finite retention settings are respected and that
0remains the only explicitly unlimited mode. - Monitor disk usage and emit a local warning before storage reaches a critical threshold.
- Validate that
