Repository navigation
Document the ID-token gap and make the header timeout configurable - #11
Conversation
The check refuses an ID token only by its markers (Keycloak typ, Cognito token_use, nonce, at_hash, c_hash, s_hash). An Entra ID token from the code exchange without a nonce has none, so it passes when the audience is the signing-in client's own ID. The README and SECURITY.md now say so, and the README gives the two Entra setups that close it: separate app registrations for the API and its clients, or a required scope, since Entra puts scp only in user access tokens.
hyper's header-read timeout also closes idle keep-alive connections, so the fixed 10 s made a load balancer that keeps connections open longer (AWS ALB: 60 s) occasionally send a request on a socket the server was closing and answer it with a 502. CVE_INTEL_HEADER_TIMEOUT_SECS sets it, 1-3600 whole seconds; unset or empty keeps 10 s. Anything else stops serve at startup with an error that names the variable, so a typo like "65s" can't quietly keep the default. serve prints the value at startup when it isn't the default. README, SECURITY.md and .env.example say when to raise it and what a longer value costs.
The parser's unit tests can't see serve() itself, so putting Limits::default() back in serve passed the whole suite. These tests run the cve-intel binary with an empty temp home, the developer's CVE_*, HOST and PORT removed, and proxies pointed at a closed port: "65s" must stop serve with an error naming the setting and its value, and "65" must print the startup line. Both fail with the serve change reverted.
|
Merged, thanks Paul! And sorry it took me a few days to get to this one, you were much quicker following up than I was. Both changes are exactly right. You're right that the ID token gap is really a setup problem, and the Entra section explains the two fixes clearly. Making a typo like One tiny thing for whenever you're next in there, not worth a PR of its own: Thanks again for all of this, it's been great working through these with you. |
Why
These are the two follow-ups from Fazmin's note after merging #10:
nonce, is one, so it passes when the audience is the signing-in client's own ID. The README didn't say so.Approach
ID tokens: documentation only. Without a marker, such an ID token has nothing in its claims that tells it apart from an access token. The fix belongs in how Entra is set up:
scponly in access tokens issued to users.Required roles don't help, because Entra puts app roles in ID tokens too. I checked these points against Microsoft's ID token and access token claims references.
Timeout: one setting,
CVE_INTEL_HEADER_TIMEOUT_SECS. hyper's HTTP/1 server closes idle keep-alive connections with the same header-read timeout, so the two can't be set separately.CVE_INTEL_OAUTH_LEEWAY_SECS.serveat startup, so a typo like65scan't quietly keep the default.How it works
listen::Limits::from_env()/from_lookup()read the setting.serve()parses it together with the TLS and OAuth settings, before any network call. It prints the value at startup when it isn't 10.README, SECURITY.md and
.env.exampleexplain when to raise it, e.g.65behind an ALB. The README's ID-token paragraph and SECURITY.md now describe the gap, and a new "Entra ID and ID tokens" paragraph in the README gives the two setups.Tests:
65s,1.5,0,3601, overflow.tests/serve_settings.rsruns thecve-intel servebinary in an empty temp home.65smust stop it with an error naming the setting, and65must print the startup line.Each test failed with its code reverted. That includes putting
Limits::default()back inserve(), which the unit tests alone didn't catch.Against the binary with the setting at
3, a silent connection and an idle keep-alive connection both closed at 3.0 s.cargo fmt --check, clippy with-D warnings,cargo test -p cve-core -p cve-server(399 passed) andcargo check -p cve-intel-desktopall pass locally.Links