CVE-2015-3185 (C, published 2015-07-20T23:59Z)
Description: value: The ap_some_auth_required function in server/request.c in the Apache HTTP Server 2.4.x before 2.4.14 does not consider that a Require directive may be associated with an authorization setting rather than an authentication setting, which allows remote attackers to bypass intended access restrictions in opportunistic circumstances by leveraging the presence of a module that relies on the 2.2 API behavior.
Severity: MEDIUM (CVSS v3 base score: )
Weakness: CWE-264 \u2014 Permissions, Privileges, and Access Controls
Weaknesses in this category are related to the management of permissions, privileges, and other security features that are used to perform access control.
Repository: https://github.com/apache/httpd
Files changed:
include/ap_mmn.h
include/http_request.h
server/request.c
Commit message: SECURITY: CVE-2015-3185 (cve.mitre.org)

Replacement of ap_some_auth_required (unusable in Apache httpd 2.4)
with new ap_some_authn_required and ap_force_authn hook.

Submitted by: breser


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1684524 13f79535-47bb-0310-9956-ffa450edef68


Vulnerable code:
#define MODULE_MAGIC_NUMBER_MINOR 2                 /* 0...n */
            if (access_status == OK) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                              "request authorized without authentication by "
                              "access_checker_ex hook: %s", r->uri);
            }
            else if (access_status != DECLINED) {
                return decl_die(access_status, "check access", r);
            }
            else {
            if (access_status == OK) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                              "request authorized without authentication by "
                              "access_checker_ex hook: %s", r->uri);
            }
            else if (access_status != DECLINED) {
                return decl_die(access_status, "check access", r);
            }
            else {

Fixed code:
 * 20150222.3 (2.5.0-dev)  Add ap_some_authn_required, ap_force_authn hook.
 *                         Deprecate broken ap_some_auth_required.
#define MODULE_MAGIC_NUMBER_MINOR 3                 /* 0...n */
 * @bug Behavior changed in 2.4.x refactoring, API no longer usable
 * @deprecated @see ap_some_authn_required()
 *
/**
 * This hook allows a module to force authn to be required when
 * processing a request.
 * This hook should be registered with ap_hook_force_authn().
 * @param r The current request
 * @return OK (force authn), DECLINED (let later modules decide)
 * @ingroup hooks
 */
AP_DECLARE_HOOK(int,force_authn,(request_rec *r))

/**
 * Can be used within any handler to determine if any authentication
 * is required for the current request.  Note that if used with an
 * access_checker hook, an access_checker_ex hook or an authz provider; the
 * caller should take steps to avoid a loop since this function is
 * implemented by calling these hooks.
 * @param r The current request
 * @return TRUE if authentication is required, FALSE otherwise
 */
AP_DECLARE(int) ap_some_authn_required(request_rec *r);

    APR_HOOK_LINK(force_authn)
AP_IMPLEMENT_HOOK_RUN_FIRST(int,force_authn,
                            (request_rec *r), (r), DECLINED)
AP_DECLARE(int) ap_some_authn_required(request_rec *r)
{
    int access_status;

    switch (ap_satisfies(r)) {
    case SATISFY_ALL:
    case SATISFY_NOSPEC:
        if ((access_status = ap_run_access_checker(r)) != OK) {
            break;
        }

        access_status = ap_run_access_checker_ex(r);
        if (access_status == DECLINED) {
            return TRUE;
        }

        break;
    case SATISFY_ANY:
        if ((access_status = ap_run_access_checker(r)) == OK) {
            break;
        }

        access_status = ap_run_access_checker_ex(r);
        if (access_status == DECLINED) {
            return TRUE;
        }

        break;
    }

    return FALSE;
}

            if (access_status == DECLINED
                || (access_status == OK && ap_run_force_authn(r) == OK)) {
            else if (access_status == OK) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                              "request authorized without authentication by "
                              "access_checker_ex hook: %s", r->uri);
            }
            else {
                return decl_die(access_status, "check access", r);
            }
            if (access_status == DECLINED
                || (access_status == OK && ap_run_force_authn(r) == OK)) {
            else if (access_status == OK) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                              "request authorized without authentication by "
                              "access_checker_ex hook: %s", r->uri);
            }
            else {
                return decl_die(access_status, "check access", r);
            }