Bug 65504 - Defaulting RequireAny globally violates best security practices
Summary: Defaulting RequireAny globally violates best security practices
Status: NEW
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_authz_core (show other bugs)
Version: 2.4.48
Hardware: All All
: P2 critical (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
Depends on:
Reported: 2021-08-17 21:38 UTC by Philip Prindeville
Modified: 2021-08-17 21:38 UTC (History)
1 user (show)


Note You need to log in before you can comment on or make changes to this bug.
Description Philip Prindeville 2021-08-17 21:38:34 UTC
Recently I was configuring a proxy URL for EJBCA on AWS, and has configured:

<Location /ejbca/adminweb>
    Require ssl
    Require expr "\
          %{SSL_CLIENT_I_DN} == 'O=ec2-n.n.n.n.us-east-1.compute.amazonaws.com,OU=ami-aaaaaaaaa,CN=ManagementCA,UID=r-uuuuuuuu' \
            && %{SSL_CLIENT_V_REMAIN} -gt 0 \
    SSLVerifyClient require

thinking that both Require statements had to be true.  Nope, turns out that's not the case, even though (1) it's completely counter-intuitive, and (2) it violates a couple of security Best Practices that "everything not explicitly permitted is implicitly defined" and "defense-in-depth".

So I thought I was battening things down by requiring that SSL be in use, and that any certs be issued from the server's own self-signed-cert, and that the cert not be expired.  In fact, only one of those two needs to be true (SSL is in use, OR the client's TLS certificate issuer DN match the server's subject DN and not be expired).

Completely counter-intuitive, and somewhat nonsensical.  If SSL *isn't* in use, then the "Require expr ..." will *never* be true.

Looking at https://httpd.apache.org/docs/2.4/howto/auth.html#beyond we have:

> By default all Require directives are handled as though contained within a <RequireAny> container directive. In other words, if any of the specified authorization methods succeed, then authorization is granted.
and in https://httpd.apache.org/docs/2.4/mod/mod_authz_core.html#requiredirectives we have:

> When multiple Require directives are used in a single configuration section and are not contained in another authorization directive like <RequireAll>, they are implicitly contained within a <RequireAny> directive. Thus the first one to authorize a user authorizes the entire request, and subsequent Require directives are ignored.
Again, completely counterintuitive and not following security Best Practices.

I recommend that the default for global scoping should be implicitly having the entire configuration being treated as if encompassed in <RequireAll>...</RequireAll>, or else there be a global directive one could apply server-config wide.