fix: require HTTPS for secret-bearing requests#163
Conversation
Greptile SummaryThis PR adds HTTPS enforcement for secret-bearing
Confidence Score: 5/5Safe to merge — the new transport guard correctly enforces HTTPS for secret-bearing requests and the loopback development exception is tightly scoped, proxy-bypassed, and DNS-pinned. The validate_secret_transport logic is sound: HTTPS passes unconditionally, the development exception requires both APP_ENV=development and a host that resolves as loopback (127.x or ::1 — not 0.0.0.0, not localhost.), and everything else is rejected before any network I/O. The no_proxy() + resolve_to_addrs hardening for the loopback path is correctly applied only when the transport check explicitly opted in. SSRF protection remains an independent gate and its augmented error message is helpful. Tests cover production rejection, development acceptance, and proxy bypass in separate subprocesses. No files require special attention. All five changed files are consistent with one another. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[http_fetch called] --> B{contains_secret?}
B -- No --> E[validate_url_for_ssrf]
B -- Yes --> C[validate_secret_transport]
C --> D{scheme == https?}
D -- Yes --> E
D -- No --> F{APP_ENV=development\nAND loopback host?}
F -- Yes --> G[direct_loopback_http = true]
F -- No --> H[TypeError: require HTTPS]
G --> E
E --> I{SSRF passes?}
I -- No --> J[format_ssrf_error\nadd APP_ENV hint if loopback]
I -- Yes --> K[Build reqwest Client]
K --> L{contains_secret?}
L -- Yes --> M[redirect = none]
L -- No --> N[normal redirect]
M --> O{direct_loopback_http?}
N --> P[Execute request]
O -- Yes --> Q[no_proxy\nresolve localhost to 127.0.0.1/::1]
O -- No --> P
Q --> P
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[http_fetch called] --> B{contains_secret?}
B -- No --> E[validate_url_for_ssrf]
B -- Yes --> C[validate_secret_transport]
C --> D{scheme == https?}
D -- Yes --> E
D -- No --> F{APP_ENV=development\nAND loopback host?}
F -- Yes --> G[direct_loopback_http = true]
F -- No --> H[TypeError: require HTTPS]
G --> E
E --> I{SSRF passes?}
I -- No --> J[format_ssrf_error\nadd APP_ENV hint if loopback]
I -- Yes --> K[Build reqwest Client]
K --> L{contains_secret?}
L -- Yes --> M[redirect = none]
L -- No --> N[normal redirect]
M --> O{direct_loopback_http?}
N --> P[Execute request]
O -- Yes --> Q[no_proxy\nresolve localhost to 127.0.0.1/::1]
O -- No --> P
Q --> P
Reviews (2): Last reviewed commit: "fix: clarify secret transport diagnostic..." | Re-trigger Greptile |
|
Addressed Greptile’s summary-only P2 in 0f02dbf: when |
Summary
Completes the ntnt-side transport boundary for
std/secrets:std/http.fetchrequest contains an opaqueSecretAPP_ENV=developmentand the destination islocalhostor a loopback IPlocalhostdirectly to IPv4/IPv6 loopback addressesVerification
cargo test --all-targetscargo build --profile dev-releaseNotes
APP_ENVcontrols only this application-level plaintext development exception. ExistingNTNT_ENVruntime and SSRF controls remain independent and can further restrict requests.