0

I am using a program to parse xml files from OpenVAS (someone else's code) and I am getting AttributeError: 'NoneType' object has no attribute 'text'. This is kind of expected because the "hostname" field can be empty for some of the scans. Ideally it should just put N/A as the hostname if it is blank.

Error:

File "/var/lib/openvasreporting/openvasreporting/libs/parser.py", line 115, in openvas_parser
vuln_host_name = vuln.find("./host/hostname").text
AttributeError: 'NoneType' object has no attribute 'text'

Here are the corresponding lines in the parser.py file:

# --------------------
#
# VULN_HOST
vuln_host = vuln.find("./host").text
vuln_host_name = vuln.find("./host/hostname").text
if vuln_host_name is None:
    vuln_host_name = "N/A"
logging.debug("* hostname:\t{}".format(vuln_host_name))  # DEBUG
vuln_port = vuln.find("./port").text
logging.debug(
    "* vuln_host:\t{} port:\t{}".format(vuln_host, vuln_port))  # DEBUG

# --------------------

As a side note, this was a bug in 2 other sections of the parser.py file. This is what the resolved sections look like:

# --------------------
#
# VULN_CVES
#vuln_cves = nvt_tmp.findall("./refs/ref")
vuln_cves = []
ref_list = []
for reference in nvt_tmp.findall('./refs/ref'):
    if reference.attrib.get('type') == 'cve':
        vuln_cves.append(reference.attrib.get('id'))
    else:
        ref_list.append(reference.attrib.get('id'))
logging.debug("* vuln_cves:\t{}".format(vuln_cves))  # DEBUG
logging.debug("* vuln_cves:\t{}".format(Et.tostring(vuln_cves).decode()))  # DEBUG
if vuln_cves is None or vuln_cves.text.lower() == "nocve":
    vuln_cves = []
else:
    vuln_cves = [vuln_cves.text.lower()]
vuln_references = ' , '.join(ref_list)
logging.debug("* vuln_cves:\t{}".format(vuln_cves))  # DEBUG
logging.debug("* vuln_references:\t{}".format(vuln_references))
# --------------------
#
# VULN_REFERENCES
vuln_references = nvt_tmp.find("./xref")
if vuln_references is None or vuln_references.text.lower() == "noxref":
    vuln_references = []
else:
    vuln_references = vuln_references.text.lower().replace("url:", "\n")

logging.debug("* vuln_references:\t{}".format(vuln_references))  # DEBUG
#
# --------------------

I've tried adding it with an else: pass but I am getting the same result.

I'm not really a programmer so I apologize if this doesn't have all the relevant information.

martineau
  • 119,623
  • 25
  • 170
  • 301

2 Answers2

1

This happens because you're calling find() and then immediately accessing the .text attribute, without checking if find() actually found anything.

Do it this way instead:

element = vuln.find("./host/hostname")
if element:
    vuln_host_name = element.text
else:
    vuln_host_name = "N/A"
John Gordon
  • 29,573
  • 7
  • 33
  • 58
  • That looks like it worked! Thank you. I guess it is throwing errors farther down the script now though, so it looks like I have more errors further down here that I will have to change. File "/var/lib/openvasreporting/openvasreporting/libs/parser.py", line 170, in openvas_parser if vuln_cves is None or vuln_cves.text.lower() == "nocve": AttributeError: 'list' object has no attribute 'text' – John Huseman Jun 16 '21 at 19:44
  • If I comment the VULN_CVES block out then it runs normally, so basically everything is working except that section. – John Huseman Jun 16 '21 at 20:00
-1

replace:

vuln_host = vuln.find("./host").text

with:

if vuln.find("./host") > -1:
  vuln_host = vuln.find("./host").text
else:
  vuln_host = "N/A"
Faulander
  • 327
  • 3
  • 12
  • I am getting: File "/var/lib/openvasreporting/openvasreporting/libs/parser.py", line 113, in openvas_parser if vuln.find("./host") > -1: TypeError: '>' not supported between instances of 'xml.etree.ElementTree.Element' and 'int' – John Huseman Jun 16 '21 at 16:12
  • Here is the section: # -------------------- # VULN_HOST if vuln.find("./host") > -1: vuln_host = vuln.find("./host").text else: vuln_host = "N/A" vuln_host_name = vuln.find("./host/hostname").text if vuln_host_name is None: vuln_host_name = "N/A" logging.debug("* hostname:\t{}".format(vuln_host_name)) # DEBUG vuln_port = vuln.find("./port").text logging.debug("* vuln_host:\t{} port:\t{}".format(vuln_host, vuln_port)) # DEBUG – John Huseman Jun 16 '21 at 16:12
  • `.find()` is not the standard string method. It doesn't return -1. – John Gordon Jun 16 '21 at 18:47