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.
This commit is contained in:
48
claude_code_remaining_issues_prompt.txt
Normal file
48
claude_code_remaining_issues_prompt.txt
Normal file
@@ -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:`
|
||||||
@@ -3,7 +3,6 @@ Platform Gateway — Configuration constants and environment variables.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import ssl
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
# ── Server ──
|
# ── Server ──
|
||||||
@@ -62,9 +61,7 @@ SESSION_MAX_AGE = int(os.environ.get("SESSION_MAX_AGE", 30 * 86400)) # 30 days
|
|||||||
# ── Ensure data dir exists ──
|
# ── Ensure data dir exists ──
|
||||||
DATA_DIR.mkdir(parents=True, exist_ok=True)
|
DATA_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
# ── SSL contexts ──
|
# Note: All internal services use plain HTTP (Docker network).
|
||||||
# Internal: skip verification for Docker-internal services (no valid certs)
|
# No custom SSL context needed. External calls (OpenAI, SMTP2GO, Open Library)
|
||||||
_internal_ssl_ctx = ssl.create_default_context()
|
# use default TLS verification.
|
||||||
_internal_ssl_ctx.check_hostname = False
|
|
||||||
_internal_ssl_ctx.verify_mode = ssl.CERT_NONE
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,18 +6,19 @@ import json
|
|||||||
import urllib.request
|
import urllib.request
|
||||||
import urllib.error
|
import urllib.error
|
||||||
|
|
||||||
from config import _internal_ssl_ctx
|
|
||||||
from database import get_db
|
from database import get_db
|
||||||
|
|
||||||
|
|
||||||
def proxy_request(target_url, method, headers, body=None, timeout=120):
|
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:
|
try:
|
||||||
req = urllib.request.Request(target_url, data=body, method=method)
|
req = urllib.request.Request(target_url, data=body, method=method)
|
||||||
for k, v in headers.items():
|
for k, v in headers.items():
|
||||||
req.add_header(k, v)
|
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_body = resp.read()
|
||||||
resp_headers = dict(resp.headers)
|
resp_headers = dict(resp.headers)
|
||||||
return resp.status, resp_headers, resp_body
|
return resp.status, resp_headers, resp_body
|
||||||
|
|||||||
Reference in New Issue
Block a user