Skip to content

fix(evonet): add configurable protocol detection for binary downloads#74

Open
DeryFerd wants to merge 1 commit into
anvie:mainfrom
DeryFerd:fix/evonet-protocol-detection
Open

fix(evonet): add configurable protocol detection for binary downloads#74
DeryFerd wants to merge 1 commit into
anvie:mainfrom
DeryFerd:fix/evonet-protocol-detection

Conversation

@DeryFerd

Copy link
Copy Markdown
Contributor

Problem

When you deploy Evonic behind a reverse proxy, the system needs to figure out whether it's running on http:// or https:// so it can embed the right URL in the downloaded Evonet connector binaries. Get it wrong and the connector fails to connect—or worse, tries to send the connector_token over plaintext HTTP.

The current implementation tries to auto-detect the protocol from request headers (X-Forwarded-Proto, request.scheme, etc.), which works fine if your proxy setup is standard. But if you're running something custom, or if your proxy chain is weird, or if ProxyFix isn't configured exactly right, the detection can fail. When it does, the code silently falls back to https without logging anything, which makes debugging really annoying.

I ran into this during a security audit when I realized that in some proxy configurations, the binary could end up with the wrong protocol embedded. If it guesses http when it should be https, the connection fails. If it guesses https when it should be http (rare but possible in dev setups), same problem. And if someone's proxy strips X-Forwarded-Proto entirely? The fallback just picks https and hopes for the best.

The Fix

This PR adds a new environment variable, EVONIC_PUBLIC_PROTOCOL, that lets you explicitly override the protocol. Three modes:

  • auto (default): Auto-detect from headers (current behavior, but with better logging)
  • https: Always use HTTPS (recommended for production)
  • http: Always use HTTP (local dev only, do not use in production)

When auto is set, the detection logic now checks headers in priority order:

  1. X-Forwarded-Proto
  2. X-Real-Proto
  3. CF-Visitor (Cloudflare-specific, parses the JSON)
  4. request.scheme (already corrected by ProxyFix if you have it)
  5. Fallback to https with a warning log

If you set EVONIC_PUBLIC_PROTOCOL=https or http explicitly, it skips all the detection and just uses what you told it to use. Debug logs show which source was used, so you can actually see what's happening instead of guessing.

Why

The connector_token is sensitive. If the binary embeds http://your-server.com when it should be https://your-server.com, the connector tries to authenticate over plaintext. That's not great. This fix gives you control so you can lock it down in production while still keeping auto-detection for simpler deployments.

Also, the warning log helps. If detection is uncertain, you'll see a message like:

Unable to reliably detect protocol from request headers (scheme='ws', X-Forwarded-Proto='(not set)'). Defaulting to 'https'. To override, set EVONIC_PUBLIC_PROTOCOL environment variable to 'http' or 'https'.

That's way better than silently picking https and hoping.

What Changed

Config (config.py)

  • Added EVONIC_PUBLIC_PROTOCOL with validation
  • Logs a warning if you set it to something invalid (falls back to auto)
  • Documented inline what each mode does

Protocol Detection (routes/workplaces.py)

  • Check config first (explicit override)
  • If auto, run through the header detection in priority order
  • Log which source was used (debug level when successful, warning when uncertain)
  • Preserve the existing header-checking logic but make it clearer what's happening

Documentation (.env.example)

  • Added entry with explanation of all three modes
  • Noted when to use each one
  • Explained the fallback behavior

Testing

I wrote two test scripts to verify this works:

Config loading test (6 scenarios):

  • Valid values (auto, http, https)
  • Case normalization (HTTPShttps)
  • Invalid values (logs warning, falls back to auto)
  • Empty value (uses default auto)

Protocol detection test (8 scenarios):

  • Config override beats headers
  • Header priority (X-Forwarded-Proto > X-Real-Proto > CF-Visitor)
  • request.scheme fallback
  • Uncertain detection (invalid scheme → https with warning)
  • Cloudflare JSON parsing

All tests passed. Syntax check passed. No regressions.

Backward Compatibility

The default is auto, which matches the current behavior (auto-detect from headers). Existing deployments don't need to change anything. If you're already using ProxyFix and standard headers, everything keeps working.

If you're in a weird proxy setup and want to lock it down, set EVONIC_PUBLIC_PROTOCOL=https and you're done.

When to Use Each Mode

auto (default) — Let Evonic figure it out from request headers. Works for most standard setups (Nginx, Caddy, Traefik with proper proxy headers).

https — Force HTTPS in production when you're behind a custom proxy or when auto-detection is unreliable. Set this if you've seen connection failures or if you want to eliminate the guesswork entirely.

http — Local development without TLS. Do not use this in production unless you really know what you're doing and have some other way of protecting the connector token in transit.

What I Checked

  • Syntax validated with python -m py_compile
  • Config loads correctly with all valid/invalid inputs
  • Protocol detection logic matches expected behavior in all scenarios
  • Logs show helpful messages (debug when detection succeeds, warning when it falls back)
  • No agent support files accidentally committed
  • .env.example updated with clear documentation

What I Didn't Test

I did not test this against a live reverse proxy setup with real connectors. The logic is sound and the tests pass, but if you're deploying this in production, verify the embedded URL in a downloaded binary before rolling it out widely.

To check: download a binary, extract the embedded JSON config at the end (after the \x00\x00EVONET_CFG\x00\x00 marker), and confirm the server_url field has the right protocol.

… Add EVONIC_PUBLIC_PROTOCOL environment variable to control protocol (http/https) embedded in downloaded Evonet connector binaries. Changes: - Add EVONIC_PUBLIC_PROTOCOL config with validation (auto/http/https) - Update protocol detection in _build_binary() with explicit override - Add debug/warning logs for protocol detection traceability - Document configuration in .env.example Motivation: When Evonic is deployed behind non-standard reverse proxies, automatic protocol detection from request headers may be unreliable. If the wrong protocol is embedded in the binary, the connector will: 1. Fail to connect (protocol mismatch) 2. Potentially expose connector_token over plaintext HTTP This fix allows explicit protocol configuration while maintaining backward-compatible auto-detection as the default. Protocol detection priority (auto mode): 1. X-Forwarded-Proto header 2. X-Real-Proto header 3. CF-Visitor header (Cloudflare) 4. request.scheme (ProxyFix-corrected) 5. Fallback to https with warning Closes issue identified in security audit: protocol misconfiguration could expose connector tokens in certain proxy configurations.
@DeryFerd DeryFerd changed the title fix(evonet): add configurable protocol detection for binary downloads… fix(evonet): add configurable protocol detection for binary downloads Jun 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant