tenable / pyTenable

Python Library for interfacing into Tenable's platform APIs
https://pytenable.readthedocs.io
MIT License
353 stars 173 forks source link

TypeError in NessusReportv2::_defs when trying to convert NoneType to float #551

Closed mzpqnxow closed 2 years ago

mzpqnxow commented 2 years ago

TypeError in NessusReportv2::_defs when trying to convert NoneType to float

I'm using TenableIO.scans.export() with a filter to export only a specific plugin_id and am encountering an exception when iterating over a NessusReportv2 object, which I'm creating from a BytesIO object

Details

I'm encountering an exception here:

https://github.com/tenable/pyTenable/blob/6661f516fb2be54f95ea6e39b8970bb05357649b/tenable/reports/nessusv2.py#L55-L57

Relevant Code

The code I'm using is as follows:

    ...
    start = time.time()
    filters = []
    if plugin_id is not None:
        filters.append(('plugin.id', 'eq', str(plugin_id)))
    byte_stream = tio.scans.export(scan_id, *filters, **export_kwargs)
    end = time.time()
    elapsed = end - start
    elapsed_str = seconds_to_human_readable(elapsed)
    report_records = NessusReportv2(byte_stream)
    for c, report in enumerate(report_records):
        print(len(report))  # <--- Dies in the first iteration, here

Traceback

Traceback (most recent call last):
  File "/home/user/./exp.py", line 120, in <module>
    main()
  File "/home/user/./exp.py", line 111, in main
    results = get_scan_instance_results(tio, scan_id, plugin_id=plugin_id, scan_history_id=scan_history_id)
  File "/home/user/./exp.py", line 90, in get_scan_instance_results
    for c, report in enumerate(report_records):
  File "/home/user/venv/lib/python3.9/site-packages/tenable/reports/nessusv2.py", line 47, in __next__
    return self.next()
  File "/home/user/venv/lib/python3.9/site-packages/tenable/reports/nessusv2.py", line 144, in next
    raise err
  File "/home/user/venv/lib/python3.9/site-packages/tenable/reports/nessusv2.py", line 134, in next
    vuln[c.tag] = self._defs(c.tag, c.text)
  File "/home/user/venv/lib/python3.9/site-packages/tenable/reports/nessusv2.py", line 60, in _defs
    return float(value)
TypeError: float() argument must be a string or a number, not 'NoneType'

Brief Analysis / Root-Cause / Fix

I initially suspected the byte_stream: BytesIO object might be corrupted in some way, but I found that the following change fixed the issue and produced proper report rows:

--- nessusv2.py.origin  2022-03-13 10:51:37.443438699 -0400
+++ nessusv2.py.fixed   2022-03-13 10:51:30.255438676 -0400
@@ -54,6 +54,9 @@

         elif name in ['cvss_base_score', 'cvss_temporal_score']:
             # CVSS scores are floats, so lets return them as such.
+            if value is None:
+                return 0  # I'm not sure what the appropriate value to return here is- `"N/A"`? `None`? `0`?
+
             return float(value)

         elif name in ['first_found', 'last_found', 'plugin_modification_date',

With that change, the NessusReportv2 iterator works as expected and all is well :>

NOTE: It's probably worth mentioning that plugin_id = 19506 is a special summary plugin, so there wouldn't ever be a CVSS score associated with it

Conclusion

This seems to me like a bug in in NessusReportv2::_defs (), perhaps only manifesting for this specific plugin_id

Thanks!

mzpqnxow commented 2 years ago

I've created PR #552 for this

Please let me know what you think about this, it would be great if you could merge this as I try to avoid having constraints.txt entries and/or setup.cfg git+https://... dependencies that point to personal forks/branches

Thanks again!