fix: what bandit and the remaining lint rules found
- WS-Management answers are parsed with defusedxml (new dependency, defusedxml>=0.7) with DTDs forbidden. The check for "<!DOCTYPE" in the raw bytes it replaces missed a DTD in a UTF-16 answer, which expat reads too; on plain HTTP (16992) anyone in the path can send one. An answer with a DTD in any encoding is now refused as no WS-Management answer, as a UTF-8 one already was (B314, B405). - xml.sax.saxutils only escapes the request envelopes, nothing parses with SAX (nosec B406). - python -m napalm_amt.record fetches the landing page without certificate checks, as before: it sends no credentials and records what discovery sees, and AMT's certificate is self-signed unless one was provisioned (nosec B501). The driver itself still verifies by default (verify_ssl).
This commit is contained in:
1 parent
87f0dff43f
commit
76f85051cc
4 files changed
+44
-12
No files matched your search
+17
-11
@@ -13,14 +13,21 @@ The envelopes follow Intel's own go-wsman-messages, which every AMT since versio
|
||||
from __future__ import annotations
|
||||
|
||||
import itertools
|
||||
import xml.etree.ElementTree as ET
|
||||
from collections.abc import Callable, Iterable, Mapping
|
||||
from typing import Any
|
||||
from xml.sax.saxutils import escape, quoteattr
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
# escape and quoteattr build the request envelopes; nothing here parses with SAX.
|
||||
from xml.sax.saxutils import escape, quoteattr # nosec B406
|
||||
|
||||
import requests
|
||||
from defusedxml import DefusedXmlException
|
||||
from defusedxml.ElementTree import ParseError, fromstring
|
||||
from requests.auth import HTTPDigestAuth
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# For the annotations only; answers are parsed by defusedxml.
|
||||
import xml.etree.ElementTree as ET # nosec B405
|
||||
|
||||
SOAP_NS = "http://www.w3.org/2003/05/soap-envelope"
|
||||
ADDRESSING_NS = "http://schemas.xmlsoap.org/ws/2004/08/addressing"
|
||||
WSMAN_NS = "http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"
|
||||
@@ -267,14 +274,13 @@ class WsmanTransport:
|
||||
"""The SOAP body of a response; a fault, a refusal or anything else raises."""
|
||||
if response.status_code == 401:
|
||||
raise WsmanAuthError(f"{self.url}: credentials refused (HTTP 401)")
|
||||
body = None
|
||||
# A DTD has no business in a WS-Management response; refusing one keeps entity
|
||||
# expansion out of the parser.
|
||||
if b"<!DOCTYPE" not in response.content:
|
||||
try:
|
||||
body = ET.fromstring(response.content).find(f"{{{SOAP_NS}}}Body")
|
||||
except ET.ParseError:
|
||||
body = None
|
||||
# A DTD has no business in a WS-Management response; refusing one, in whatever
|
||||
# encoding, keeps entity expansion out of the parser.
|
||||
body: ET.Element | None
|
||||
try:
|
||||
body = fromstring(response.content, forbid_dtd=True).find(f"{{{SOAP_NS}}}Body")
|
||||
except (ParseError, DefusedXmlException):
|
||||
body = None
|
||||
if body is not None:
|
||||
fault = body.find(f"{{{SOAP_NS}}}Fault")
|
||||
if fault is not None:
|
||||
|
||||
Reference in new issue
Block a user