Sandor Molnar created KNOX-3557:
-----------------------------------
Summary: K8sDestinationAudienceValidator: do not match aud entries
that carry a resource path when the path header is not configured
Key: KNOX-3557
URL: https://issues.apache.org/jira/browse/KNOX-3557
Project: Apache Knox
Issue Type: Task
Components: KnoxIDF
Reporter: Sandor Molnar
Assignee: Sandor Molnar
Fix For: 3.1.0
h3. Problem
When {{request.audience.k8s.path.header.name}} is not configured,
{{K8sDestinationAudienceValidator.matchesPath}} returns {{true}} for any
resource path. So an {{aud}} entry that names a resource path matches every
request to that destination service, although the entry asks for something
narrower.
Because of how the two forms are parsed, Knox may then read an entry as naming
a different service than its path suggests:
* *DNS form.* With {{{}request.audience.k8s.dns.format.enabled=true{}}}, every
entry is tried as the DNS form first, and the custom form is used only if that
doesn't match. A host with one or two labels, or of the form
{{{}<a>.<b>.svc[.<cluster-domain prefix>]{}}}, parses as a DNS name, and the
path is never compared. {{[https://svc-a.ns-a.svc.cluster.local/ns-b/svc-b]}}
therefore matches {{svc-a}} in {{{}ns-a{}}}.
* *Custom form.* The first two path segments are the namespace and service.
The rest is the resource path, which is also never compared.
{{https://<cluster-domain>/ns-a/svc-a/ns-b/svc-b}} therefore matches {{svc-a}}
in {{{}ns-a{}}}.
Some components check these values outside Knox. One example is an admission
policy that authorizes delegation-policy {{resourcePolicy}} keys by their
trailing {{{}/<namespace>/<service>{}}}. Such a component reads both entries
above as targeting {{{}ns-b/svc-b{}}}, while Knox accepts them for
{{{}ns-a/svc-a{}}}. Today it can only be safe by copying Knox's host-parsing
rules.
h3. Proposal
When the path header is not configured, treat an {{aud}} entry whose resource
path is not {{/}} as not matching, in both forms. Entries without a path don't
change: they still mean the whole service. A DNS-form entry that doesn't match
still falls back to the custom form, as it does today. There the host must be
in {{{}request.audience.k8s.cluster-domains{}}}.
With this change, both examples above are rejected for {{{}svc-a{}}}. An
external check then only needs an exact {{/<namespace>/<service>}} ending for
the custom form, or an exact host for the DNS form.
*Compatibility:* deployments that configure no path header but mint audiences
with a path would start failing. Either:
* make this the default and say so in the release notes; or
* keep today's behaviour behind an opt-out parameter.
h3. Tests
* No path header configured:
** a DNS-form entry with a non-root path doesn't match;
** a custom-form entry with segments after {{/<namespace>/<service>}} doesn't
match;
** entries without a path, in either form, still match.
* No path header configured: a DNS-form entry with a path falls back to the
custom form, and matches only if its host is in {{cluster-domains}} and its
path is exactly {{{}/<namespace>/<service>{}}}.
* Path header configured: behavior unchanged.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)