pogzyb / asyncwhois

Python WHOIS and RDAP utility for querying and parsing information about Domains, IPv4s, IPv6s, and AS numbers
MIT License
63 stars 18 forks source link

Infinite loop triggered with RDAP domain search #72

Closed koromodako closed 9 months ago

koromodako commented 9 months ago

Hello,

Many thanks for this interesting project, I encountered an infinite loop while using this package. Here is the scenario to reproduce this bug with the latest version of this package (1.0.10).

python3 -m venv venv
venv/bin/python -m pip install asyncwhois
venv/bin/python
from logging import basicConfig
from asyncwhois import rdap_domain
basicConfig(level='DEBUG')
result = rdap_domain('myspreadshop.net')
# infinite loop triggered, raising RecursionError at some point 
pogzyb commented 9 months ago

Sorry I missed this issue - I was focused on the other you raised earlier this week.

The RDAP client tries to find the "authoritative response" by making requests and parsing the responses. It looks like in this case it's stuck in a loop due to the registrar including a "related" link to itself, which the client keeps following over and over.

I'll take care of this over here: pogzyb/whodap#37 and keep you posted. Thanks!

pogzyb commented 9 months ago

Good news - the infinite looping should be fixed now when using whodap==0.1.12. Thanks for finding this!

q, p = asyncwhois.rdap("myspreadshop.net")

print(q)
'{"entities": [{"handle": "o_2309647", "links": [{"href": "https://rdap.eurodns.com/entity/o_2309647", "rel": "self", "type": "application/rdap+json", "value": "https://rdap.eurodns.com/entity/o_2309647"}], "objectClassName": "entity", "vcardArray": ["vcard", [["version", {}, "text", "4.0"], ["fn", {}, "text", "Julian de Grahl"], ["role", {}, "text", "registrant"], ["adr", {}, "text", ["", "Giesserstrasse 27 null null", "Leipzig", "", "04229", "GERMANY"]], ["tel", {"type": ["voice"]}, "uri", "tel:+49341594000"], ["email", {}, "text", "nic@spreadshirt.net"]]]}, {"handle": "a_2309647", "links": [{"href": "https://rdap.eurodns.com/entity/a_2309647", "rel": "self", "type": "application/rdap+json", "value": "https://rdap.eurodns.com/entity/a_2309647"}], "objectClassName": "entity", "vcardArray": ["vcard", [["version", {}, "text", "4.0"], ["fn", {}, "text", "Julian de Grahl"], ["role", {}, "text", "administrative"], ["adr", {}, "text", ["", "Giesserstrasse 27 null null", "Leipzig", "", "04229", "GERMANY"]], ["tel", {"type": ["voice"]}, "uri", "tel:+49341594000"], ["email", {}, "text", "nic@spreadshirt.net"]]]}, {"handle": "t_2309647", "links": [{"href": "https://rdap.eurodns.com/entity/t_2309647", "rel": "self", "type": "application/rdap+json", "value": "https://rdap.eurodns.com/entity/t_2309647"}], "objectClassName": "entity", "vcardArray": ["vcard", [["version", {}, "text", "4.0"], ["fn", {}, "text", "Thomas Abraham"], ["role", {}, "text", "technical"], ["adr", {}, "text", ["", "Giesserstrasse 27 null null", "Leipzig", "", "04229", "GERMANY"]], ["tel", {"type": ["voice"]}, "uri", "tel:+49341594000"], ["email", {}, "text", "eurodns@spreadshirt.net"]]]}, {"entities": [{"handle": "abuse", "links": [{"href": "https://rdap.eurodns.com/entity/abuse", "rel": "self", "type": "application/rdap+json", "value": "https://rdap.eurodns.com/entity/abuse"}], "objectClassName": "entity", "vcardArray": ["vcard", [["version", {}, "text", "4.0"], ["fn", {}, "text", "Eurodns S.A."], ["tel", {"type": ["voice"]}, "uri", "tel:+35227220150"], ["email", {}, "text", "legalservices@eurodns.com"]]]}], "handle": "1052", "links": [{"href": "https://rdap.eurodns.com/entity/1052", "rel": "self", "type": "application/rdap+json", "value": "https://rdap.eurodns.com/entity/1052"}], "objectClassName": "entity", "roles": ["registrar"], "vcardArray": ["vcard", [["version", {}, "text", "4.0"], ["fn", {}, "text", "Legal Services"], ["org", {}, "text", "EuroDNS S.A."]]]}], "events": [{"eventAction": "registration", "eventDate": "2021-05-06T00:00:00.000+02:00"}, {"eventAction": "expiration", "eventDate": "2024-05-05T00:00:00.000+02:00"}, {"eventAction": "last update of RDAP database", "eventDate": "2023-12-27T09:35:05.861+01:00"}], "handle": "myspreadshop.net", "lang": "en", "ldhName": "myspreadshop.net", "links": [{"href": "https://rdap.eurodns.com/domain/myspreadshop.net", "rel": "self", "type": "application/rdap+json", "value": "https://rdap.eurodns.com/domain/myspreadshop.net"}, {"href": "https://rdap.eurodns.com", "rel": "related", "type": "application/rdap+json", "value": "https://rdap.eurodns.com"}], "nameservers": [{"ipAddresses": {"v4": ["198.51.44.6"]}, "objectClassName": "nameserver"}, {"ipAddresses": {"v4": ["198.51.45.6"]}, "objectClassName": "nameserver"}, {"ipAddresses": {"v4": ["198.51.44.70"]}, "objectClassName": "nameserver"}, {"ipAddresses": {"v4": ["198.51.45.70"]}, "objectClassName": "nameserver"}], "notices": [{"description": ["The RDAP service offered by EuroDNS S.A. is subject to Terms and Conditions.", "Please visit https://www.eurodns.com/terms-and-conditions"], "links": [{"href": "https://www.eurodns.com/terms-and-conditions", "rel": "alternate", "type": "text/html", "value": "https://www.eurodns.com/terms-and-conditions"}], "title": "EuroDNS RDAP Terms and Conditions"}, {"description": ["For more information on domain status codes, please visit https://icann.org/epp"], "links": [{"href": "https://icann.org/epp", "rel": "alternate", "type": "text/html", "value": "https://icann.org/epp"}], "title": "Status Codes"}, {"description": ["URL of the ICANN RDDS Inaccuracy Complaint Form: https://icann.org/wicf"], "links": [{"href": "https://icann.org/wicf", "rel": "alternate", "type": "text/html", "value": "https://icann.org/wicf"}], "title": "RDDS Inaccuracy Complaint Form"}], "objectClassName": "domain", "port43": "whois.eurodns.com", "publicIds": [{"identifier": "1052", "type": "IANA Registrar ID"}], "rdapConformance": ["rdap_level_0", "icann_rdap_response_profile_0", "icann_rdap_technical_implementation_guide_0"], "secureDNS": {"delegationSigned": false, "zoneSigned": false}, "status": ["active", "client transfer prohibited"], "unicodeName": "myspreadshop.net"}'

print(p)
{admin_name: None, admin_organization: None, admin_email: None, admin_address: None, admin_phone: None, admin_fax: None, billing_name: None, billing_organization: None, billing_email: None, billing_address: None, billing_phone: None, billing_fax: None, registrant_name: None, registrant_organization: None, registrant_email: None, registrant_address: None, registrant_phone: None, registrant_fax: None, status: ['active', 'client transfer prohibited'], domain_name: 'myspreadshop.net', dnssec: None, expires: datetime.datetime(2024, 5, 5, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=7200))), updated: None, created: datetime.datetime(2021, 5, 6, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=7200))), name_servers: ['198.51.44.6', '198.51.45.6', '198.51.44.70', '198.51.45.70'], registrar_abuse_email: None, registrar_abuse_phone: None, tech_email: None, tech_address: None, tech_organization: None, tech_name: None, tech_phone: None, tech_fax: None, registrar: None, admin_id: None, admin_city: None, admin_state: None, admin_country: None, admin_zipcode: None, billing_id: None, billing_city: None, billing_state: None, billing_country: None, billing_zipcode: None, tech_id: None, tech_city: None, tech_state: None, tech_country: None, tech_zipcode: None, registrant_city: None, registrant_state: None, registrant_country: None, registrant_zipcode: None, registrar_iana_id: None, registrar_url: None}

Unfortunately as you can see above, the parsing of this RDAP response into a "whois-like" dictionary is missing a lot of information. I suspect this is for the same reason as why the infinite looping happened in the first place: the registrar (authoritative answer) for this domain, eurodns, has a slightly non-conforming RDAP implementation, which is causing the parser to implode. There's not a lot I can do about this, but I'm hoping in a future release to implement a feature inspired by icann/rdap-conformance-tool that can at least warn about these situations, throw an exception, or handle them entirely.