Andrea Cosentino created CAMEL-25368:
----------------------------------------

             Summary: camel-spiffe: the documented SpiffeSecurityPolicy example 
denies every request
                 Key: CAMEL-25368
                 URL: https://issues.apache.org/jira/browse/CAMEL-25368
             Project: Camel
          Issue Type: Bug
          Components: camel-spiffe
            Reporter: Andrea Cosentino
            Assignee: Andrea Cosentino
             Fix For: 4.23.0


The SpiffeSecurityPolicy section added in CAMEL-24735 ships an example that 
cannot work, and the surrounding text does not say where the policy is usable 
at all. Worth fixing before 4.23.0 ships, since a reader who copies the example 
gets a route that denies all traffic and no indication why.

h3. The example never authorizes anything

{code:java}
from("netty-http:https://0.0.0.0:8443?sslContextParameters=#spiffeSsl";)
    .policy(spiffePolicy)
    .to("direct:handleOrder");
{code}

Nothing sets {{clientAuthentication}} on the server parameters. Traced through 
main:

* {{SSLContextServerParameters.getSSLEngineConfigurers}} adds its client-auth 
configurer only {{if (this.getClientAuthentication() != null)}}, so an unset 
value installs no configurer at all - neither {{setNeedClientAuth}} nor 
{{setWantClientAuth}} is ever called, leaving the JSSE default of no client 
authentication.
* {{SpiffeSSLContextParameters}} does not set it either; it only preserves 
whatever the parent's {{serverParameters.clientAuthentication}} says.
* With no client certificate requested, {{SSLSession.getPeerCertificates()}} 
throws {{SSLPeerUnverifiedException}}, which {{SpiffePeerIdentity}} catches and 
turns into {{null}}.
* {{null}} is the fail-closed path, so the policy denies - every request, for 
every peer.

The docs must show {{clientAuthentication=REQUIRE}} on the server 
{{SSLContextServerParameters}}, and say that the server has to use 
{{SpiffeSSLContextParameters}} rather than a plain truststore: a plain 
truststore accepts any certificate chaining to the trust bundle, so the policy 
would be authorizing an identity nobody constrained.

h3. The scope of the policy is not stated

The identity comes from an {{SSLSession}} on the message, and 
{{NettyEndpoint.updateMessageHeader}} is the only place in the codebase that 
puts one there (gated on {{configuration.isSsl()}}). So the policy works with 
camel-netty and camel-netty-http and silently denies everything on 
platform-http, jetty, undertow and servlet. The servlet certificate fallback 
was dropped during the review of #27385, so there is no longer any non-netty 
path. That belongs in the docs rather than being discovered in production.

h3. Negative tests

The 13 tests that shipped cover the allow paths and the plainly-absent-identity 
denials. The denials that would actually be attacked are untested:

* a String-valued {{CamelNettySSLSession}} header, i.e. a sender trying to pass 
an identity as text rather than an {{SSLSession}};
* near-miss SPIFFE IDs against the allow-list - 
{{spiffe://example.org.evil/frontend}} and {{spiffe://example.org/frontend/x}} 
against an accepted {{spiffe://example.org/frontend}};
* a malformed {{spiffe://}} URI SAN;
* a leaf certificate that is not an X509Certificate.

No behaviour change is proposed for the code itself - the first of those is 
also the answer to the review question of whether {{sslSessionHeader}} should 
be forced to start with {{Camel}}: it need not, because an {{SSLSession}} is a 
Java object and a String header is already rejected. The tests pin that rather 
than relying on the argument.

Follow-up to CAMEL-24735.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to