Fix bucket policy Condition evaluation by passing request context

This commit is contained in:
2026-01-12 23:33:35 +08:00
parent 433d291b4b
commit ba694cb717
2 changed files with 34 additions and 2 deletions

View File

@@ -53,6 +53,20 @@ def _bucket_policies() -> BucketPolicyStore:
return store return store
def _build_policy_context() -> Dict[str, Any]:
ctx: Dict[str, Any] = {}
if request.headers.get("Referer"):
ctx["aws:Referer"] = request.headers.get("Referer")
if request.access_route:
ctx["aws:SourceIp"] = request.access_route[0]
elif request.remote_addr:
ctx["aws:SourceIp"] = request.remote_addr
ctx["aws:SecureTransport"] = str(request.is_secure).lower()
if request.headers.get("User-Agent"):
ctx["aws:UserAgent"] = request.headers.get("User-Agent")
return ctx
def _object_lock() -> ObjectLockService: def _object_lock() -> ObjectLockService:
return current_app.extensions["object_lock"] return current_app.extensions["object_lock"]
@@ -380,7 +394,8 @@ def _authorize_action(principal: Principal | None, bucket_name: str | None, acti
policy_decision = None policy_decision = None
access_key = principal.access_key if principal else None access_key = principal.access_key if principal else None
if bucket_name: if bucket_name:
policy_decision = _bucket_policies().evaluate(access_key, bucket_name, object_key, action) policy_context = _build_policy_context()
policy_decision = _bucket_policies().evaluate(access_key, bucket_name, object_key, action, policy_context)
if policy_decision == "deny": if policy_decision == "deny":
raise IamError("Access denied by bucket policy") raise IamError("Access denied by bucket policy")
@@ -407,11 +422,13 @@ def _authorize_action(principal: Principal | None, bucket_name: str | None, acti
def _enforce_bucket_policy(principal: Principal | None, bucket_name: str | None, object_key: str | None, action: str) -> None: def _enforce_bucket_policy(principal: Principal | None, bucket_name: str | None, object_key: str | None, action: str) -> None:
if not bucket_name: if not bucket_name:
return return
policy_context = _build_policy_context()
decision = _bucket_policies().evaluate( decision = _bucket_policies().evaluate(
principal.access_key if principal else None, principal.access_key if principal else None,
bucket_name, bucket_name,
object_key, object_key,
action, action,
policy_context,
) )
if decision == "deny": if decision == "deny":
raise IamError("Access denied by bucket policy") raise IamError("Access denied by bucket policy")

View File

@@ -62,6 +62,20 @@ def _bucket_policies() -> BucketPolicyStore:
return store return store
def _build_policy_context() -> dict[str, Any]:
ctx: dict[str, Any] = {}
if request.headers.get("Referer"):
ctx["aws:Referer"] = request.headers.get("Referer")
if request.access_route:
ctx["aws:SourceIp"] = request.access_route[0]
elif request.remote_addr:
ctx["aws:SourceIp"] = request.remote_addr
ctx["aws:SecureTransport"] = str(request.is_secure).lower()
if request.headers.get("User-Agent"):
ctx["aws:UserAgent"] = request.headers.get("User-Agent")
return ctx
def _connections() -> ConnectionStore: def _connections() -> ConnectionStore:
return current_app.extensions["connections"] return current_app.extensions["connections"]
@@ -172,7 +186,8 @@ def _authorize_ui(principal, bucket_name: str | None, action: str, *, object_key
enforce_bucket_policies = current_app.config.get("UI_ENFORCE_BUCKET_POLICIES", True) enforce_bucket_policies = current_app.config.get("UI_ENFORCE_BUCKET_POLICIES", True)
if bucket_name and enforce_bucket_policies: if bucket_name and enforce_bucket_policies:
access_key = principal.access_key if principal else None access_key = principal.access_key if principal else None
decision = _bucket_policies().evaluate(access_key, bucket_name, object_key, action) policy_context = _build_policy_context()
decision = _bucket_policies().evaluate(access_key, bucket_name, object_key, action, policy_context)
if decision == "deny": if decision == "deny":
raise IamError("Access denied by bucket policy") raise IamError("Access denied by bucket policy")
if not iam_allowed and decision != "allow": if not iam_allowed and decision != "allow":