Back to Checks
alibabacloud

OSS bucket is not anonymously or publicly accessible

oss_bucket_not_publicly_accessible
Service: ossSeverity: critical
OfficialBuilt-inVerified
Categories:internet-exposed
Resource Type:ALIYUN::OSS::Bucket

Alibaba Cloud Object Storage Service (OSS) buckets store objects that may contain sensitive data. It is recommended that the access policy on OSS buckets does not allow anonymous or public access, ensuring that only authorized identities can interact with bucket contents. The bucket ACL should be set to private to prevent unintended data exposure.

Risk

Allowing anonymous or public access to OSS buckets grants permissions to anyone on the internet to read or modify bucket content. This can lead to data breaches, unauthorized data exfiltration, data tampering, and compliance violations, particularly when buckets contain sensitive or regulated information.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler alibabacloud --checks oss_bucket_not_publicly_accessible

Recommendation

Set the OSS bucket ACL to private and configure bucket policies to deny anonymous or public access, ensuring only authorized identities can access stored objects.

Remediation

CLI

aliyun oss PutBucketAcl --bucket <bucket-name> --acl private

Terraform

resource "alicloud_oss_bucket_public_access_block" "example" {
  bucket              = alicloud_oss_bucket.example.bucket
  block_public_access = true
}

Other

1*Set Bucket ACL to Private:**
2Log on to the **OSS Console**
3In the bucket-list pane, click on a target OSS bucket
4Click on **Basic Setting** in the top middle of the console
5Under ACL section, click on **Configure**
6Click **Private** and click **Save**
7*For Bucket Policy:**
8Click **Bucket**, and then click the name of the target bucket
9Click the **Files** tab and click **Authorize**
10In the Authorize dialog, choose `Anonymous Accounts (*)` for Accounts and choose `None` for Authorized Operation
11Click **OK**

Check Code

from prowler.lib.check.models import Check, CheckReportAlibabaCloud
from prowler.providers.alibabacloud.services.oss.oss_client import oss_client


def _is_policy_public(policy_document: dict) -> bool:
    """
    Check if a bucket policy allows public access.

    A policy is considered public if it has a statement with:
    - Effect: "Allow"
    - Principal: ["*"] (or contains "*")
    - No Condition elements

    Args:
        policy_document: The parsed policy document as a dictionary.

    Returns:
        bool: True if policy allows public access, False otherwise.
    """
    if not policy_document:
        return False

    statements = policy_document.get("Statement", [])
    if not isinstance(statements, list):
        statements = [statements]

    for statement in statements:
        effect = statement.get("Effect", "")
        principal = statement.get("Principal", [])
        condition = statement.get("Condition")

        # If there's a condition, it's not truly public
        if condition:
            continue

        if effect == "Allow":
            # Check if Principal is "*" or contains "*"
            if isinstance(principal, list):
                if "*" in principal:
                    return True
            elif principal == "*":
                return True

    return False


class oss_bucket_not_publicly_accessible(Check):
    """Check if OSS bucket is not anonymously or publicly accessible."""

    def execute(self) -> list[CheckReportAlibabaCloud]:
        findings = []

        for bucket in oss_client.buckets.values():
            report = CheckReportAlibabaCloud(metadata=self.metadata(), resource=bucket)
            report.region = bucket.region
            report.resource_id = bucket.name
            report.resource_arn = bucket.arn

            # Check bucket ACL
            acl_public = False
            if bucket.acl and bucket.acl != "private":
                if bucket.acl in ["public-read", "public-read-write"]:
                    acl_public = True

            # Check bucket policy
            policy_public = _is_policy_public(bucket.policy)

            # Determine status
            if acl_public or policy_public:
                report.status = "FAIL"
                issues = []
                if acl_public:
                    issues.append(f"Bucket ACL is set to {bucket.acl}")
                if policy_public:
                    issues.append("Bucket policy allows public access (Principal: '*')")
                report.status_extended = (
                    f"OSS bucket {bucket.name} is publicly accessible. "
                    + "; ".join(issues)
                )
            else:
                report.status = "PASS"
                report.status_extended = (
                    f"OSS bucket {bucket.name} is not publicly accessible. "
                    f"ACL is {bucket.acl} and bucket policy does not allow public access."
                )

            findings.append(report)

        return findings