Andrea Cosentino created CAMEL-25139:
----------------------------------------
Summary: camel-opa - failOpen allows the exchange when OPA
answered (undefined decision, rejected request), not only when it is unavailable
Key: CAMEL-25139
URL: https://issues.apache.org/jira/browse/CAMEL-25139
Project: Camel
Issue Type: Bug
Reporter: Andrea Cosentino
Assignee: Andrea Cosentino
Fix For: 4.23.0
With {{failOpen=true}}, {{OpaPolicyEvaluator}} lets the exchange proceed on
*every* exception from the evaluation, not only when the policy decision point
is unavailable. The option's own documentation promises less: "allow the
exchange to proceed when the policy cannot be evaluated at all, for example
because the OPA server is unreachable".
In the SDK (com.styra:opa 2.1.1, checked in the bytecode),
{{OPAClient.evaluate}}:
* wraps any HTTP failure as {{OPAException(..., cause)}}, where the cause is
{{ClientError}} (400), {{SDKError}} carrying the status code (other 4xx, such
as 401/403/404/429, and other 5xx), {{ServerError}} (500), or an
{{IOException}} from the transport;
* reports an *undefined* decision as a cause-less {{OPAException}} ("succeeded,
but OPA did not reply with a result"). The WASM evaluator throws on an
undefined rule the same way, on purpose.
So under {{failOpen=true}} these all turn into an allow, although in none of
them was the decision point unavailable:
* an undefined decision, for example {{policyPath=authz/allow}} against a
policy without {{default allow := false}}, where every request the rule does
not match becomes an allow. This is the most common Rego shape to trip it;
* OPA rejecting the request: 400, a wrong or expired {{bearerToken}} (401/403),
or a wrong path (404);
* a failure building or serializing the input document from the message, which
is a property of the message rather than of the decision point.
{{failOpen}} is {{insecure:dev}}, documented as not for production, and
camel-opa is not released yet (4.23.0). So this is fixed as a bug before
release rather than treated as a vulnerability. It is the same class as the
finding in the camel-openfga review (CAMEL-25028), where a 4xx was also read as
"no verdict" under {{failOpen}}.
Fix: {{failOpen}} applies only when the decision point is unavailable. In REST
mode that means transport failures ({{IOException}}, including timeouts), HTTP
5xx and 429. In WASM mode it means a pool that stays busy past
{{borrowTimeout}}. Everything else fails closed with {{failOpen}} set too:
undefined decisions, other 4xx, and input-document failures. This covers single
and batch evaluation and {{OpaSecurityPolicy}}.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)