Describe the bug
The /api/scripts/run endpoint has no server-side rate limiting. Any client can POST to it repeatedly in a tight loop, spawning unlimited OS subprocesses on the host machine simultaneously. Even without malicious intent, a UI glitch or accidental double-click can trigger duplicate runs back-to-back.
Steps to Reproduce
Start the Flask backend
Send rapid repeated POST requests to /api/scripts/run
Observe that every request spawns a new subprocess with no rejection
Expected Behavior
The server should return HTTP 429 Too Many Requests when a script is already running or the request rate exceeds a safe threshold.
Root Cause
app.py has no rate limiting decorator or concurrent execution guard on the /api/scripts/run route.
Proposed Fix
Add flask-limiter to cap requests per minute per IP
Add a lightweight in-memory running_scripts set to block duplicate concurrent runs of the same script
Return a clear 429 JSON error response to the client
Related Issues
#27 — Kill mechanism (client-side stop, not server-side prevention)
#42 — UI execution guard (frontend only, not enforced server-side)
Describe the bug
The /api/scripts/run endpoint has no server-side rate limiting. Any client can POST to it repeatedly in a tight loop, spawning unlimited OS subprocesses on the host machine simultaneously. Even without malicious intent, a UI glitch or accidental double-click can trigger duplicate runs back-to-back.
Steps to Reproduce
Start the Flask backend
Send rapid repeated POST requests to /api/scripts/run
Observe that every request spawns a new subprocess with no rejection
Expected Behavior
The server should return HTTP 429 Too Many Requests when a script is already running or the request rate exceeds a safe threshold.
Root Cause
app.py has no rate limiting decorator or concurrent execution guard on the /api/scripts/run route.
Proposed Fix
Add flask-limiter to cap requests per minute per IP
Add a lightweight in-memory running_scripts set to block duplicate concurrent runs of the same script
Return a clear 429 JSON error response to the client
Related Issues
#27 — Kill mechanism (client-side stop, not server-side prevention)
#42 — UI execution guard (frontend only, not enforced server-side)