-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
securitySecurity related issuesSecurity related issues
Description
Security Issue
Severity: Severe
Related PR: #30
Description
All API endpoints lack rate limiting, making the system vulnerable to abuse and denial of service attacks.
Vulnerable Endpoints
High-Risk (resource-intensive):
POST /api/kestra/trigger- Triggers full security scansPOST /webhook/task-update- State manipulationPOST /webhook/execution-update- State manipulation/ws/execution/{execution_id}- WebSocket connections
Medium-Risk:
GET /api/kestra/execution/{execution_id}GET /api/kestra/execution/{execution_id}/logsGET /webhook/status/{execution_id}
Attack Scenarios
- Resource Exhaustion:
# Trigger 1000 concurrent scans
for i in {1..1000}; do
curl -X POST http://api/kestra/trigger \
-H "Content-Type: application/json" \
-d '{"repository_url": "https://github.com/large/repo"}' &
done- WebSocket Flooding:
// Open thousands of WebSocket connections
for (let i = 0; i < 10000; i++) {
new WebSocket('ws://api/ws/execution/fake-id');
}- State Manipulation Storm:
# Spam fake webhook updates
while true; do
curl -X POST http://api/webhook/execution-update \
-d '{"execution_id":"x","state":"FAILED"}'
doneSecurity Impact
- Denial of Service: Overwhelming the backend and Kestra services
- Cost Escalation: Abuse of cloud resources and API quotas (Gemini)
- Service Degradation: Legitimate users unable to access system
- Data Corruption: Flood of fake webhook updates corrupting state
Remediation
- Install Rate Limiting Middleware:
# requirements.txt
slowapi==0.1.9- Apply Rate Limits:
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded
limiter = Limiter(key_func=get_remote_address)
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
# On expensive endpoints
@router.post("/kestra/trigger")
@limiter.limit("5/minute") # Max 5 scans per minute per IP
async def trigger_kestra_flow(request: Request, req: KestraFlowRequest):
...
# On webhooks
@webhook_router.post("/task-update")
@limiter.limit("100/minute")
async def receive_task_update(request: Request):
...
# On WebSocket
@app.websocket("/ws/execution/{execution_id}")
@limiter.limit("10/minute")
async def websocket_endpoint(websocket: WebSocket, execution_id: str):
...- Per-User Rate Limits (after authentication added):
def get_user_id(request: Request):
# Extract from JWT/API key
return request.headers.get("X-User-ID", get_remote_address(request))
limiter = Limiter(key_func=get_user_id)- Configure Redis for Distributed Rate Limiting:
from slowapi.util import get_remote_address
import redis
redis_client = redis.Redis(host='redis', port=6379)
limiter = Limiter(
key_func=get_remote_address,
storage_uri="redis://redis:6379"
)Recommended Limits
- Scan triggers: 5/minute, 20/hour per IP/user
- Webhooks: 100/minute per IP (legitimate Kestra)
- WebSocket connections: 10/minute, 5 concurrent per IP
- Status checks: 60/minute per IP
Assignee: @haroon0x
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
securitySecurity related issuesSecurity related issues