From 2c2881b3517e7e3659f05d3386fae80907ffc55b Mon Sep 17 00:00:00 2001 From: Sandiyo Christan <55909152+sandiyochristan@users.noreply.github.com> Date: Tue, 17 Feb 2026 16:51:30 +0530 Subject: [PATCH] fix(oss): use defusedxml to prevent XXE vulnerabilities (#9999) Co-authored-by: Andoni A. <14891798+andoniaf@users.noreply.github.com> --- poetry.lock | 16 +++++++++++-- prowler/CHANGELOG.md | 4 ++++ .../alibabacloud/services/oss/oss_service.py | 2 +- pyproject.toml | 1 + .../services/oss/oss_service_test.py | 23 +++++++++++++++++++ 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index ea9d2504af..092d6351fe 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.2 and should not be changed by hand. [[package]] name = "about-time" @@ -2139,6 +2139,18 @@ files = [ {file = "decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360"}, ] +[[package]] +name = "defusedxml" +version = "0.7.1" +description = "XML bomb protection for Python stdlib modules" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +groups = ["main"] +files = [ + {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, + {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, +] + [[package]] name = "deprecated" version = "1.2.18" @@ -6881,4 +6893,4 @@ files = [ [metadata] lock-version = "2.1" python-versions = ">3.9.1,<3.13" -content-hash = "f1ac30f34fd838017ad24702043564e2c37afd1fdbf674cf5e5def79082463d5" +content-hash = "509440ff7a10d735686d330ac032f824fc92cf2dbacc66371e688ae1dd25dc2f" diff --git a/prowler/CHANGELOG.md b/prowler/CHANGELOG.md index be13cef868..39de66ba30 100644 --- a/prowler/CHANGELOG.md +++ b/prowler/CHANGELOG.md @@ -62,6 +62,10 @@ All notable changes to the **Prowler SDK** are documented in this file. - `--repository` and `--organization` flags combined interaction in GitHub provider, qualifying unqualified repository names with organization [(#10001)](https://github.com/prowler-cloud/prowler/pull/10001) - HPACK library logging tokens in debug mode for Azure, M365, and Cloudflare providers [(#10010)](https://github.com/prowler-cloud/prowler/pull/10010) +### 🐞 Fixed + +- Use `defusedxml` in the Alibaba Cloud OSS service to prevent XXE vulnerabilities when parsing XML responses [(#9999)](https://github.com/prowler-cloud/prowler/pull/9999) + --- ## [5.18.0] (Prowler v5.18.0) diff --git a/prowler/providers/alibabacloud/services/oss/oss_service.py b/prowler/providers/alibabacloud/services/oss/oss_service.py index 49db1b870c..378807bc5d 100644 --- a/prowler/providers/alibabacloud/services/oss/oss_service.py +++ b/prowler/providers/alibabacloud/services/oss/oss_service.py @@ -6,9 +6,9 @@ from datetime import datetime from email.utils import formatdate from threading import Lock from typing import Optional -from xml.etree import ElementTree import requests +from defusedxml import ElementTree from pydantic.v1 import BaseModel from prowler.lib.logger import logger diff --git a/pyproject.toml b/pyproject.toml index 3f9b699149..8d8452ad65 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,6 +47,7 @@ dependencies = [ "cryptography==44.0.3", "dash==3.1.1", "dash-bootstrap-components==2.0.3", + "defusedxml>=0.7.1", "detect-secrets==1.5.0", "dulwich==0.23.0", "google-api-python-client==2.163.0", diff --git a/tests/providers/alibabacloud/services/oss/oss_service_test.py b/tests/providers/alibabacloud/services/oss/oss_service_test.py index ea906f587e..e71c2eca9e 100644 --- a/tests/providers/alibabacloud/services/oss/oss_service_test.py +++ b/tests/providers/alibabacloud/services/oss/oss_service_test.py @@ -74,3 +74,26 @@ def test_list_buckets_respects_audit_filters(): oss._list_buckets() assert list(oss.buckets.keys()) == [] + + +def test_list_buckets_rejects_xxe_payload(): + oss = _build_oss_service() + xxe_payload = """ + + ]> + + + + &xxe; + 2025-01-01T00:00:00.000Z + oss-cn-hangzhou + + + """ + + with patch("requests.get") as get_mock: + get_mock.return_value = MagicMock(status_code=200, text=xxe_payload) + oss._list_buckets() + + assert oss.buckets == {}