From 7c05ef14c7e0ef0f1bce3d35ce58d61a9ba7eceb Mon Sep 17 00:00:00 2001 From: Yusuf Suleman Date: Sun, 29 Mar 2026 13:46:11 -0500 Subject: [PATCH] fix(gateway): remove no-verify SSL context from proxy (#7) All internal services use plain HTTP (Docker network). The _internal_ssl_ctx with disabled cert verification was a no-op for HTTP URLs but suggested TLS bypass was in use. - Removed _internal_ssl_ctx from config.py - Removed ssl import from config.py - proxy.py now calls urlopen() without context parameter - External calls (OpenAI, SMTP2GO, Open Library) already use default TLS verification Verified: dashboard, trips, fitness, budget, inventory all respond correctly. --- claude_code_remaining_issues_prompt.txt | 48 +++++++++++++++++++++++++ gateway/config.py | 9 ++--- gateway/proxy.py | 7 ++-- 3 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 claude_code_remaining_issues_prompt.txt diff --git a/claude_code_remaining_issues_prompt.txt b/claude_code_remaining_issues_prompt.txt new file mode 100644 index 0000000..fa3973b --- /dev/null +++ b/claude_code_remaining_issues_prompt.txt @@ -0,0 +1,48 @@ +Work in the `platform` repo and continue from the current remediation state. + +Use Gitea issues as the source of truth: +- `#1` umbrella +- `#5` Gateway Trust Model +- `#7` Transport Security +- `#8` Dependency Security +- `#9` Performance Hardening + +First, re-verify the repo state before changing anything. Do not trust prior summaries blindly. + +Current known remaining work: +1. `#7` +- Gateway proxy still uses `_internal_ssl_ctx` with disabled cert/hostname verification +- Fix the real proxy path, not just external image fetches + +2. `#5` +- `SERVICE_LEVEL_AUTH` trust model still exists in the gateway +- Inventory still exposes `/debug-nocodb` +- Inventory search/filter construction still needs hardening + +3. `#9` +- Inventory `/issues` and `/needs-review-count` still do full scans +- Budget `/transactions/recent` still fans out across all accounts +- Existing cache improvements are helpful but do not complete the issue + +4. `#8` +- `.gitea/workflows/security.yml` exists +- The remaining work is operational: verify/document exactly what still requires a Gitea runner and avoid overstating completion + +Instructions: +- Make minimal, production-oriented fixes +- After each issue-sized change, verify it +- Comment on the relevant Gitea issue with: + - what changed + - files touched + - verification performed + - what remains +- Do not close `#5`, `#7`, or `#9` unless the actual code and behavior support it +- Do not mark `#8` completed unless the repo-side work is fully done and the remaining runner dependency is clearly documented +- Do not reopen already completed issues unless you find a real regression +- Do not revert unrelated user changes + +Final output format: +- `Completed:` +- `Partial:` +- `Blocked:` +- `Manual ops actions:` diff --git a/gateway/config.py b/gateway/config.py index bdc168f..0e08a16 100644 --- a/gateway/config.py +++ b/gateway/config.py @@ -3,7 +3,6 @@ Platform Gateway — Configuration constants and environment variables. """ import os -import ssl from pathlib import Path # ── Server ── @@ -62,9 +61,7 @@ SESSION_MAX_AGE = int(os.environ.get("SESSION_MAX_AGE", 30 * 86400)) # 30 days # ── Ensure data dir exists ── DATA_DIR.mkdir(parents=True, exist_ok=True) -# ── SSL contexts ── -# Internal: skip verification for Docker-internal services (no valid certs) -_internal_ssl_ctx = ssl.create_default_context() -_internal_ssl_ctx.check_hostname = False -_internal_ssl_ctx.verify_mode = ssl.CERT_NONE +# Note: All internal services use plain HTTP (Docker network). +# No custom SSL context needed. External calls (OpenAI, SMTP2GO, Open Library) +# use default TLS verification. diff --git a/gateway/proxy.py b/gateway/proxy.py index e77707b..fd7143f 100644 --- a/gateway/proxy.py +++ b/gateway/proxy.py @@ -6,18 +6,19 @@ import json import urllib.request import urllib.error -from config import _internal_ssl_ctx from database import get_db def proxy_request(target_url, method, headers, body=None, timeout=120): - """Proxy a request to a backend service. Returns (status, response_headers, response_body).""" + """Proxy a request to a backend service. Returns (status, response_headers, response_body). + All internal services use plain HTTP (Docker network) — no SSL context needed. + """ try: req = urllib.request.Request(target_url, data=body, method=method) for k, v in headers.items(): req.add_header(k, v) - with urllib.request.urlopen(req, context=_internal_ssl_ctx, timeout=timeout) as resp: + with urllib.request.urlopen(req, timeout=timeout) as resp: resp_body = resp.read() resp_headers = dict(resp.headers) return resp.status, resp_headers, resp_body