CVE-2026-73262: Prowler Remote Code Execution Vulnerability

MODERATE
Advisory Identifier: GHSA-c2jg-2778-ggm4
CVSS 5.4
CWE-79
Published
Advisory Summary

CVE-2026-73262 is a MODERATE (CVSS 5.4) remote code execution vulnerability (CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')) affecting Prowler libraries in the PyPI ecosystem. The issue involves stored xss in html reports through unescaped cloud resource tags. Remediation is available by upgrading affected packages to version 5.37.0.

CVE-2026-73262 at a Glance

CVE Identifier CVE-2026-73262
GHSA Identifier GHSA-c2jg-2778-ggm4
Severity MODERATE
CVSS v3.1 Base Score 5.4
CWE Classification CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
Affected Product Prowler
Package Ecosystem PyPI
Published Date
Last Updated

Security Impact

CVSS: 5.4

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required Low (PR:L)
User Interaction Required (UI:R)
Scope Changed (S:C)
Confidentiality Low (C:L)
Integrity Low (I:L)
Availability None (A:N)

How to Fix CVE-2026-73262

To remediate this vulnerability, upgrade all affected Prowler dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

prowler fixed: 5.37.0
pip install prowler>=5.37.0
prowler-cloud fixed: 5.37.0
pip install prowler-cloud>=5.37.0
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

pip show prowler

How to Check if You Are Affected

To determine whether your Python environment is affected by CVE-2026-73262, inspect your installed packages using pip:

pip show prowler

Analyze the terminal output to locate any version of Prowler in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 5.37.0), your application is affected.

Note: The pip show prowler command checks currently installed packages in your active Python environment.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'), where the product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users. In Prowler, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

## Summary Prowler's HTML output formatter inserts `finding.resource_tags` into the generated report without HTML escaping. A cloud principal who can create or edit a resource tag in an account that is later scanned can store HTML or JavaScript in that tag. When another user opens the generated Prowler HTML report, the payload executes in the report page. ## Impact This is stored cross-site scripting in a security report artifact. The attacker needs permission to influence tags on a scanned cloud resource, and the victim must open the generated HTML report. In that context, JavaScript can read and modify the report DOM, alter displayed findings, and interact with any same-origin local or hosted report content available to the browser. This can undermine trust in generated security findings and can expose data contained in the report page. ## Gate checks The repository has 13,875 GitHub stars, which is above the 10,000 star floor. `SECURITY.md` is present and does not reject GitHub private reporting. The dedicated GitHub private vulnerability reporting endpoint for `prowler-cloud/prowler` returned `true`. ## Affected versions The vulnerable sink is present in current `master` at commit `329dfdf8e6cb8bc0424fb54b6595408e20969782` and in the latest GitHub release tag `5.28.0`. The package metadata identifies the Python package as `prowler`. ## Technical details The HTML formatter builds each finding row with an f-string in `prowler/lib/outputs/html/html.py`. Neighboring fields are explicitly escaped: - `resource_uid` is escaped at line 85 with `.replace("<", "&lt;").replace(">", "&gt;")`. - `status_extended` is escaped at line 87 with the same pattern. The tag column does not apply equivalent escaping: ```python <td>{parse_html_string(unroll_dict(finding.resource_tags))}</td> ``` `unroll_dict` concatenates tag keys and values into a string, and `parse_html_string` only prefixes each item with an HTML bullet. Neither function escapes `<`, `>`, quotes, or event-handler attributes before insertion into the table cell. As a result, a tag value such as this remains active markup in the generated report: ```html <img src=x onerror="window.PROWLER_TAG_XSS=1"> ``` ## Reproduction 1. Create or identify a cloud resource that Prowler will include in an HTML report. 2. Add a tag value containing a harmless proof payload, for example: ```html <img src=x onerror="window.PROWLER_TAG_XSS=1"> ``` 3. Run Prowler against the account and generate HTML output. 4. Open the generated HTML report in a browser. 5. The payload executes from the tags column. A proof HTML fragment using the same formatter structure set `window.PROWLER_TAG_XSS=1` from `resource_tags`, while equivalent payloads in `resource_uid` and `status_extended` stayed text because those fields are escaped. Local evidence: - `/home/unkn0wn/security_audit/vulnerability-reports/prowler-html-tag-xss-evidence-2026-05-26.json` - `/home/unkn0wn/security_audit/vulnerability-reports/prowler-html-tag-xss-proof-full.html` ## PoC The minimized generated row below mirrors the vulnerable formatter output. The first and third candidate payloads are escaped controls. The middle payload is the unescaped `resource_tags` value and executes when the report is rendered. ```html <tr class="table-danger"> <td>&lt;img src=x onerror="window.PROWLER_UID_XSS=1"&gt;</td> <td> &#x2022;Owner=<img src=x onerror="window.PROWLER_TAG_XSS=1;document.body.setAttribute('data-prowler-tag-xss','1')"> </td> <td>&lt;img src=x onerror="window.PROWLER_STATUS_XSS=1"&gt;</td> </tr> ``` Browser proof result from the local artifact: ```json {"tag": 1, "uid": 0, "status": 0, "attr": "1"} ``` ## Remediation Escape tag keys and values before inserting them into HTML output. Prefer a single HTML escaping helper for every finding field that can originate from provider data. If bullets or separators are needed, build the list structure after escaping each key and value, rather than escaping the final HTML string after markup has been added.

CVE-2026-73262 Affected Prowler Versions

2 component(s)
Fixed Versions:
5.37.0
Product / Package Ecosystem Affected Versions Fixed Version
prowler
PyPI
< 5.37.0
5.37.0
prowler-cloud
PyPI
< 5.37.0
5.37.0

References

Frequently Asked Questions

What is CVE-2026-73262?
CVE-2026-73262 is a security vulnerability in Prowler involving Stored XSS in HTML reports through unescaped cloud resource tags under CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting').
Which Prowler versions are affected?
Affected versions include releases prior to 5.37.0 across affected packages: prowler, prowler-cloud.
What version fixes CVE-2026-73262?
Upgrading to 5.37.0 (or the latest patched release for your respective branch) resolves the vulnerability.
Is prowler affected?
Yes, prowler is affected in releases prior to 5.37.0. Upgrade your dependency to 5.37.0 or later.
Is prowler-cloud affected?
Yes, prowler-cloud is affected in releases prior to 5.37.0. Upgrade your dependency to 5.37.0 or later.
What is the CVSS score of CVE-2026-73262?
CVE-2026-73262 has a CVSS v3.1 base score of 5.4 (MODERATE) with vector string CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N.
What CWE is associated with CVE-2026-73262?
CVE-2026-73262 is classified under CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.).
How can I check PyPI dependencies for CVE-2026-73262?
Run the dependency tree command: 'pip show prowler'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-c2jg-2778-ggm4",
  "modified" : "2026-09-08T18:09:25Z",
  "published" : "2026-09-08T18:09:25Z",
  "aliases" : [ "CVE-2026-73262" ],
  "summary" : "Prowler: Stored XSS in HTML reports through unescaped cloud resource tags",
  "details" : "## Summary\n\nProwler's HTML output formatter inserts `finding.resource_tags` into the generated report without HTML escaping. A cloud principal who can create or edit a resource tag in an account that is later scanned can store HTML or JavaScript in that tag. When another user opens the generated Prowler HTML report, the payload executes in the report page.\n\n## Impact\n\nThis is stored cross-site scripting in a security report artifact. The attacker needs permission to influence tags on a scanned cloud resource, and the victim must open the generated HTML report. In that context, JavaScript can read and modify the report DOM, alter displayed findings, and interact with any same-origin local or hosted report content available to the browser. This can undermine trust in generated security findings and can expose data contained in the report page.\n\n## Gate checks\n\nThe repository has 13,875 GitHub stars, which is above the 10,000 star floor. `SECURITY.md` is present and does not reject GitHub private reporting. The dedicated GitHub private vulnerability reporting endpoint for `prowler-cloud/prowler` returned `true`.\n\n## Affected versions\n\nThe vulnerable sink is present in current `master` at commit `329dfdf8e6cb8bc0424fb54b6595408e20969782` and in the latest GitHub release tag `5.28.0`. The package metadata identifies the Python package as `prowler`.\n\n## Technical details\n\nThe HTML formatter builds each finding row with an f-string in `prowler/lib/outputs/html/html.py`. Neighboring fields are explicitly escaped:\n\n- `resource_uid` is escaped at line 85 with `.replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\")`.\n- `status_extended` is escaped at line 87 with the same pattern.\n\nThe tag column does not apply equivalent escaping:\n\n```python\n<td>{parse_html_string(unroll_dict(finding.resource_tags))}</td>\n```\n\n`unroll_dict` concatenates tag keys and values into a string, and `parse_html_string` only prefixes each item with an HTML bullet. Neither function escapes `<`, `>`, quotes, or event-handler attributes before insertion into the table cell. As a result, a tag value such as this remains active markup in the generated report:\n\n```html\n<img src=x onerror=\"window.PROWLER_TAG_XSS=1\">\n```\n\n## Reproduction\n\n1. Create or identify a cloud resource that Prowler will include in an HTML report.\n2. Add a tag value containing a harmless proof payload, for example:\n\n```html\n<img src=x onerror=\"window.PROWLER_TAG_XSS=1\">\n```\n\n3. Run Prowler against the account and generate HTML output.\n4. Open the generated HTML report in a browser.\n5. The payload executes from the tags column.\n\nA proof HTML fragment using the same formatter structure set `window.PROWLER_TAG_XSS=1` from `resource_tags`, while equivalent payloads in `resource_uid` and `status_extended` stayed text because those fields are escaped.\n\nLocal evidence:\n\n- `/home/unkn0wn/security_audit/vulnerability-reports/prowler-html-tag-xss-evidence-2026-05-26.json`\n- `/home/unkn0wn/security_audit/vulnerability-reports/prowler-html-tag-xss-proof-full.html`\n\n## PoC\n\nThe minimized generated row below mirrors the vulnerable formatter output. The first and third candidate payloads are escaped controls. The middle payload is the unescaped `resource_tags` value and executes when the report is rendered.\n\n```html\n<tr class=\"table-danger\">\n  <td>&lt;img src=x onerror=\"window.PROWLER_UID_XSS=1\"&gt;</td>\n  <td>\n    &#x2022;Owner=<img src=x onerror=\"window.PROWLER_TAG_XSS=1;document.body.setAttribute('data-prowler-tag-xss','1')\">\n  </td>\n  <td>&lt;img src=x onerror=\"window.PROWLER_STATUS_XSS=1\"&gt;</td>\n</tr>\n```\n\nBrowser proof result from the local artifact:\n\n```json\n{\"tag\": 1, \"uid\": 0, \"status\": 0, \"attr\": \"1\"}\n```\n\n## Remediation\n\nEscape tag keys and values before inserting them into HTML output. Prefer a single HTML escaping helper for every finding field that can originate from provider data. If bullets or separators are needed, build the list structure after escaping each key and value, rather than escaping the final HTML string after markup has been added.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "PyPI",
      "name" : "prowler"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "5.37.0"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 5.36.0"
    }
  }, {
    "package" : {
      "ecosystem" : "PyPI",
      "name" : "prowler-cloud"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "5.37.0"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 5.36.0"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/prowler-cloud/prowler/security/advisories/GHSA-c2jg-2778-ggm4"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-73262"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/prowler-cloud/prowler/pull/12221"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/prowler-cloud/prowler/commit/6db407ed3c17d4c73a8f619fdb30580c8465027f"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/prowler-cloud/prowler"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/prowler-cloud/prowler/releases/tag/5.37.0"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-79" ],
    "severity" : "MODERATE",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-09-08T18:09:25Z",
    "nvd_published_at" : "2026-08-12T15:18:30Z"
  }
}