Back to Checks
openstack

Images are not shared with an excessive number of projects

image_not_shared_with_multiple_projects
Service: imageSeverity: medium
OfficialBuilt-inVerified
Categories:trust-boundaries
Resource Type:OS::Glance::WebImage

OpenStack images are evaluated to verify that shared images do not exceed a configurable member threshold (default: 5 accepted members). Images shared with many projects amplify the blast radius of any vulnerability found in the image, as all consuming projects would be affected. Best practices recommend limiting image sharing to the minimum set of projects required.

Risk

Images shared with many projects amplify the blast radius of image vulnerabilities, backdoors, or misconfigurations. If a widely shared image is compromised, all projects using it are affected. Oversharing also increases the risk of unauthorized access to proprietary software or sensitive OS configurations embedded in images.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler openstack --checks image_not_shared_with_multiple_projects

Recommendation

Review shared image membership regularly and remove projects that no longer need access. Consider creating separate images per team or environment instead of sharing a single image widely. The threshold is configurable via audit_config 'image_sharing_threshold' (default: 5).

Remediation

CLI

openstack image remove project <image_id> <project_id>

Other

1*Reduce image sharing:**
2List shared members: `openstack image member list <image_id>`
3Review each member project for continued need
4Remove unnecessary members: `openstack image remove project <image_id> <project_id>`
5Consider publishing separate images per team instead of oversharing

Check Code

"""OpenStack Image Sharing Scope Check."""

from typing import List

from prowler.lib.check.models import Check, CheckReportOpenStack
from prowler.providers.openstack.services.image.image_client import image_client


class image_not_shared_with_multiple_projects(Check):
    """Ensure images are not shared with an excessive number of projects."""

    def execute(self) -> List[CheckReportOpenStack]:
        """Execute image_not_shared_with_multiple_projects check.

        Iterates over all images and verifies that shared images do not
        exceed the accepted member threshold (default 5, configurable via
        audit_config 'image_sharing_threshold').

        Returns:
            list[CheckReportOpenStack]: List of findings for each image.
        """
        findings: List[CheckReportOpenStack] = []
        threshold = image_client.audit_config.get("image_sharing_threshold", 5)

        for image in image_client.images:
            report = CheckReportOpenStack(metadata=self.metadata(), resource=image)

            if image.visibility != "shared":
                report.status = "PASS"
                report.status_extended = f"Image {image.name} ({image.id}) is not shared (visibility={image.visibility})."
            else:
                accepted_count = sum(1 for m in image.members if m.status == "accepted")

                if accepted_count > threshold:
                    report.status = "FAIL"
                    report.status_extended = (
                        f"Image {image.name} ({image.id}) is shared with "
                        f"{accepted_count} accepted projects, exceeding the "
                        f"threshold of {threshold}."
                    )
                else:
                    report.status = "PASS"
                    report.status_extended = (
                        f"Image {image.name} ({image.id}) is shared with "
                        f"{accepted_count} accepted projects, within the "
                        f"threshold of {threshold}."
                    )

            findings.append(report)

        return findings