Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -304,3 +304,11 @@ STELLAR_RPC_MAX_KEYS=100
# Verify public-network endpoints resolve to a globally routable address (DNS)
# before each request. Keep enabled; disable only for isolated networks.
STELLAR_STRICT_HOST_VALIDATION=1

# Webhooks and event delivery (Phase 12, #674).
# WEBHOOK_MAX_PAYLOAD_BYTES bounds payload size to prevent unbounded memory buffering (default: 256 KB).
# WEBHOOK_OVERSIZED_POLICY defines behavior for oversized payloads: "reject" (default, HTTP 413) or "truncate".
WEBHOOK_MAX_PAYLOAD_BYTES=262144
WEBHOOK_OVERSIZED_POLICY=reject
# Optional secret for incoming webhook validation via X-Webhook-Secret or Authorization header.
WEBHOOK_INGESTION_SECRET=
2 changes: 2 additions & 0 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def create_app(config_name: str | None = None) -> Flask:
from app.reviews import bp as reviews_bp
from app.stellar import bp as stellar_bp
from app.tools import bp as tools_bp
from app.webhooks import bp as webhooks_bp
from app.workspaces import bp as workspaces_bp

app.register_blueprint(auth_bp)
Expand All @@ -118,6 +119,7 @@ def create_app(config_name: str | None = None) -> Flask:
app.register_blueprint(stellar_bp)
app.register_blueprint(billing_bp)
app.register_blueprint(admin_bp)
app.register_blueprint(webhooks_bp)

# Register Socket.IO event handlers (import has side effects by design).
from app.collaboration import realtime # noqa: F401
Expand Down
7 changes: 7 additions & 0 deletions app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,13 @@ class Config:
# (defense-in-depth against SSRF through a misconfigured endpoint).
STELLAR_STRICT_HOST_VALIDATION = os.getenv("STELLAR_STRICT_HOST_VALIDATION", "1") == "1"

# Webhooks and event delivery limits (Phase 12, #674).
# Bounds payload size to prevent unbounded memory buffering and DoS.
# Supported policies for oversized payloads: "reject" (default, fail closed)
# or "truncate" (explicit non-silent truncation of non-essential fields).
WEBHOOK_MAX_PAYLOAD_BYTES = _positive_int_env("WEBHOOK_MAX_PAYLOAD_BYTES", 256 * 1024)
WEBHOOK_OVERSIZED_POLICY = os.getenv("WEBHOOK_OVERSIZED_POLICY", "reject").strip().lower()


class DevelopmentConfig(Config):
"""Local development configuration."""
Expand Down
Loading