Skip to content

SEVERE: Verbose Error Messages Leak Internal Information #34

@coderabbitai

Description

@coderabbitai

Security Issue

Severity: Severe
Related PR: #30

Description

Error handlers return detailed internal information that aids attackers in reconnaissance and exploitation.

Vulnerable Code

  1. Webhook Error Handler (backend/app/api/webhooks.py:54,93):
except Exception as e:
    print(f"❌ Webhook error: {e}")
    return {"status": "error", "message": str(e)}  # ❌ Full exception exposed
  1. Kestra Client (backend/app/core/kestra_client.py):
except Exception as e:
    return {"success": False, "error": str(e)}  # ❌ Raw exception string

Information Disclosed

Stack Traces (likely in development mode):

  • Internal file paths
  • Python version and library versions
  • Database connection strings
  • Function names and code structure

Error Messages May Reveal:

  • Connection refused → Internal service down/unreachable
  • Name or service not known → Invalid hostname (internal network)
  • Timeout → Service exists but slow/overloaded
  • KeyError: 'field' → Expected data structure
  • ImportError → Missing dependencies or version mismatch

Example Attack

# Probe internal services
curl -X POST http://api/kestra/trigger \
  -d '{"repository_url": "http://internal-service:8080/"}' 

# Response reveals:
# {"success": false, "error": "ConnectionError: Cannot connect to internal-service:8080"}
# Attacker now knows: internal network layout, service names, ports

Security Impact

  • Reconnaissance: Attackers learn system architecture
  • Version Detection: Identifies vulnerable dependencies
  • Path Disclosure: Reveals file system structure
  • Service Discovery: Maps internal network topology
  • Exploit Development: Detailed errors help craft exploits

Remediation

  1. Generic Error Messages for Users:
import logging

logger = logging.getLogger(__name__)

try:
    result = await kestra.trigger_flow(url, branch)
except Exception as e:
    logger.error("Flow trigger failed", exc_info=True)  # Log full details
    return {
        "success": False,
        "error": "Failed to trigger workflow"  # Generic message
    }
  1. Error Classification:
class SafeError(Exception):
    """Errors safe to expose to users."""
    pass

def handle_error(e: Exception) -> dict:
    if isinstance(e, SafeError):
        return {"error": str(e)}
    else:
        logger.error("Internal error", exc_info=True)
        return {"error": "An internal error occurred"}
  1. Global Exception Handler:
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse

@app.exception_handler(Exception)
async def generic_exception_handler(request: Request, exc: Exception):
    logger.error(
        "Unhandled exception",
        exc_info=exc,
        extra={"path": request.url.path, "method": request.method}
    )
    
    if os.getenv("ENV") == "production":
        return JSONResponse(
            status_code=500,
            content={"error": "Internal server error"}
        )
    else:
        # Development only
        return JSONResponse(
            status_code=500,
            content={"error": str(exc), "type": type(exc).__name__}
        )
  1. Validate Before Processing:
def validate_repository_url(url: str):
    if not url.startswith("https://github.com/"):
        raise SafeError("Only GitHub HTTPS URLs are supported")
    # More validation...

Configuration

# .env
ENV=production  # Controls error verbosity
DEBUG=false

Files to Update

  • backend/app/api/webhooks.py
  • backend/app/core/kestra_client.py
  • backend/app/api/routes.py
  • backend/app/main.py (global handler)

Assignee: @haroon0x

Metadata

Metadata

Assignees

Labels

securitySecurity related issues

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions