Invalid A records may DoS updates to a zone

Bug #1760833 reported by Dr. Jens Harbott
260
This bug affects 2 people
Affects Status Importance Assigned to Milestone
Designate
Fix Released
Critical
Graham Hayes

Bug Description

The API and OSC client allow to create records containing an IPv4 address with octal integer part, like 10.11.12.01.

openstack recordset create test2.org. srv01.test2.org. --type A --record 10.11.12.01
+-------------+--------------------------------------+
| Field | Value |
+-------------+--------------------------------------+
| action | CREATE |
| created_at | 2018-04-03T09:57:13.000000 |
| description | None |
| id | 35a64eaa-4e30-45f9-8be6-b65a516192e6 |
| name | srv01.test2.org. |
| project_id | f935a519f8f24b879acd6f4440a66434 |
| records | 10.11.12.01 |
| status | PENDING |
| ttl | None |
| type | A |
| updated_at | None |
| version | 1 |
| zone_id | 1ebd4a75-fdf4-4024-afd3-589d09d6838f |
| zone_name | test2.org. |
+-------------+--------------------------------------+

However eventlet doesn't allow addresses with leading zeroes, causing this and all subsequent zone updates to fail in mdns:

Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service Traceback (most recent call last):
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service File "/opt/stack/designate/designate/service.py", line 392, in _dns_handle_tcp_conn
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service {'payload': query, 'addr': addr}):
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service File "/opt/stack/designate/designate/dnsutils.py", line 134, in __call__
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service for response in self.application(message):
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service File "/opt/stack/designate/designate/mdns/handler.py", line 74, in __call__
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service for response in self._handle_axfr(request):
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service File "/opt/stack/designate/designate/mdns/handler.py", line 291, in _handle_axfr
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service [str(record[4])], # rdata
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service File "/usr/local/lib/python2.7/dist-packages/eventlet/support/dns/rrset.py", line 139, in from_text_list
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service rd = dns.rdata.from_text(r.rdclass, r.rdtype, t)
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service File "/usr/local/lib/python2.7/dist-packages/eventlet/support/dns/rdata.py", line 428, in from_text
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service return cls.from_text(rdclass, rdtype, tok, origin, relativize)
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service File "/usr/local/lib/python2.7/dist-packages/eventlet/support/dns/rdtypes/IN/A.py", line 44, in from_text
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service return cls(rdclass, rdtype, address)
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service File "/usr/local/lib/python2.7/dist-packages/eventlet/support/dns/rdtypes/IN/A.py", line 34, in __init__
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service dns.ipv4.inet_aton(address)
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service File "/usr/local/lib/python2.7/dist-packages/eventlet/support/dns/ipv4.py", line 54, in inet_aton
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service raise dns.exception.SyntaxError
Apr 03 09:55:20 jh-devstack-02 designate-mdns[24680]: ERROR designate.service SyntaxError: Text input is malformed.

This situation continues until the "broken" recordset is deleted.

Revision history for this message
Graham Hayes (grahamhayes) wrote :

OK - confirmed that both dnspython and eventlet explicitly block leading zeros on octets.

I think this needs to be a 2 part fix:

 - one commit to update the designate objects validation to catch the leading zeros (no backport)
 - one commit that does one or both of:
   - Strips out leading zeros in mdns before passing to dnspython
   - Fixes all records in the DB to remove the leading zeros. (probably an extra designate-manage subcommand)

I am going to set this public, as it only affects the project that creates the record, and they have a way to fix it without admin intervention.

information type: Private Security → Public Security
Changed in designate:
importance: Undecided → Critical
milestone: none → 7.0.0.0b1
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to designate (master)

Fix proposed to branch: master
Review: https://review.openstack.org/558869

Changed in designate:
assignee: nobody → Graham Hayes (grahamhayes)
status: New → In Progress
Revision history for this message
Graham Hayes (grahamhayes) wrote :

This was only introduced by the OVO migration - no previous releases are affected.

We previously did https://github.com/openstack/designate/blob/stable/queens/designate/schema/format.py#L62-L66

>>> import netaddr
>>> str(netaddr.IPAddress("10.001.1.1", version=4))
'10.1.1.1'

which would have caught the issue.

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to designate (master)

Reviewed: https://review.openstack.org/558869
Committed: https://git.openstack.org/cgit/openstack/designate/commit/?id=d72c652013f1e6a33c75580075a93357587ffde5
Submitter: Zuul
Branch: master

commit d72c652013f1e6a33c75580075a93357587ffde5
Author: Graham Hayes <email address hidden>
Date: Wed Apr 4 16:54:16 2018 +0100

    Ensure we do not pass invalid data for A records

    DNSPython does not allow IPs to have leading zeros
    for A records [1] and eventlet agrees [2], so we should
    ensure we do not create a situation where a project can
    DOS itself.

    This patch uses the DNSPython method to ensure it is kept in sync

    1 - https://github.com/rthalley/dnspython/blob/v1.15.0/dns/ipv4.py#L52-L54
    2 - https://github.com/eventlet/eventlet/blob/v0.20.0/eventlet/support/dns/ipv4.py#L52-L54

    Partial-Bug: 1760833
    Change-Id: I975b18d390647de9fe11c105cd421b761f88be6c

no longer affects: designate/ocata
no longer affects: designate/pike
no longer affects: designate/queens
no longer affects: designate/rocky
To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.