返回列表

AWS帳號快速充值 AWS IAM Policy 萬用字元(*)權限過大引發安全漏洞?最小權限審計實戰

亞馬遜雲AWS / 2026-08-04 15:14:46

先說結論:* 不是不能用,是不能放任它長大

AWS IAM 的萬用字元很常見,尤其在快速交付階段,團隊會先寫出能跑的政策,再打算日後收斂。問題是,這個「日後」常常不會到來。當 Action 寫成 iam:*s3:*,或 Resource 直接放 *,權限就從方便變成風險。真正危險的不是萬用字元本身,而是缺乏邊界、缺乏審計、缺乏持續收斂。

最小權限不是一句口號,而是一種可驗證的工作方法:每個身份只拿完成任務所需的最小動作、最小資源、最小條件。只要缺了一項,IAM 就可能從防線變成入口。很多安全事件不是因為攻擊者一開始就拿到最高權限,而是因為某個看似無害的 *,讓他在拿到一個低權限身份後,慢慢擴大到整個帳號。

AWS帳號快速充值 一、IAM 萬用字元到底危險在哪裡

1. Action 層級的 *

AWS帳號快速充值 Action* 最容易被低估。很多人會想,反正只是一個服務,像 s3:* 只是讓同一個團隊都能操作 S3,不算什麼大事。但 AWS 的服務動作不是只有讀寫而已,還包含建立、刪除、變更、授權、設定通知、修改加密、設定生命週期等大量管理動作。當你把整個服務打開,等於把未來可能新增的高風險 API 一起放進來。

更麻煩的是,某些動作本身雖然不直接寫資料,卻能間接造成權限提升。例如 iam:PassRolelambda:CreateFunctionec2:RunInstancescloudformation:CreateStack,只要搭配錯誤的資源範圍,低權限使用者也可能把高權限角色掛到新的執行環境上。表面上看是部署權限,實際上可能是提權入口。

2. Resource 層級的 *

Resource 直接寫 *,代表這個動作可以作用在任何資源上。若這個動作是只讀,問題也許還不算立刻致命;但如果是修改、刪除、解密、匯出、設定分享或變更金鑰,就會直接把整個帳號的資料平面打開。舉例來說,secretsmanager:GetSecretValuekms:Decryptdynamodb:PutItems3:GetObject 這些動作一旦配上萬用資源,攻擊者就不需要猜測目標在哪裡,因為他可以直接對全域資源發動查找與讀取。

很多團隊會說「我們的資源名稱本來就不固定,所以先用 *」。這句話常常暴露出一個問題:命名規則和權限模型沒有一起設計。真正成熟的做法,是先定義清楚環境、業務、帳號、角色、資料區隔,再用 ARN 或標籤把範圍縮小,而不是把 * 當成設計缺口的止血貼。

3. Condition 缺失比 * 更可怕

有些政策看起來已經不是 Action 全開、Resource 全開了,但還是過度寬鬆。原因在於少了條件限制。最小權限不只是「可以做什麼」,還包括「在什麼情境下可以做」。例如同樣是 S3 讀取,可能只允許某個前綴、某個 VPC Endpoint、某個來源 IP、某個裝置必須啟用 MFA、某個 Session Tag 才能操作。少了這些條件,就算動作與資源看起來很窄,實際上仍然可能被濫用。

尤其在跨帳號、跨環境、臨時憑證與自動化任務大量存在的場景裡,條件是第二道門。沒有條件,就沒有上下文;沒有上下文,就很難分辨這個請求到底是正常部署、批次處理,還是已被盜用的會話。

二、最常見的五種高風險 Policy 模式

1. 管理類 API 直接整包放行

最常見的錯誤是把管理類 API 寫成服務全開,例如 iam:*organizations:*kms:*cloudtrail:*。這種政策通常出現在「先讓系統跑起來」的階段,但如果沒有期限、沒有審查、沒有擁有者,最後就會變成永久授權。管理類 API 的風險不在於使用頻率高,而在於一旦被誤用,後果通常是整個帳號層級的變更。

2. iam:PassRole 與寬鬆服務權限並存

iam:PassRole 本身不一定危險,危險的是它和可建立運算資源的權限綁在一起,卻沒有把可傳遞的角色縮到最小。若一個身份可以建立 Lambda、EC2、Batch、ECS 任務,又可以把任意角色傳上去,那麼這個身份實際上可以藉由執行環境拿到更高權限。很多提權事件,根源都不是單一條政策,而是兩三條看似合理的政策拼起來,最後產生了意外的能力組合。

3. S3 與 Secrets 類型的資料外洩風險

S3、Secrets Manager、SSM Parameter Store、KMS 這幾類服務,和資料保護直接相關。若某個角色能讀取所有秘密、解密所有資料、列出所有 bucket、下載所有物件,等於把應用程式的憑證、資料庫密碼、簽章金鑰與內部文件一次打包。這類權限通常平時看起來沒有異常,因為使用者不一定天天去讀它,但一旦被盜用,就會讓攻擊者在極短時間內完成橫向移動。

4. 只看「Allow」不看「Implicit Deny」

有些審計只檢查顯式允許的語句,卻忽略了整體授權結果。AWS 的授權是多層疊加的:身份基礎政策、資源型政策、權限邊界、SCP、會話政策、臨時標籤,都可能影響最終結果。你以為自己只放了一點點權限,但如果其他政策又補了一刀,實際可做的事情可能比你預期多很多。審計時不能只盯單一 JSON,而要看最終有效權限。

5. 以為只有生產環境重要,測試環境就隨便

很多入侵的起點都在測試環境。原因很簡單:測試環境權限寬、監控少、資料混雜、密碼沿用、角色共用。若測試帳號有過寬的 IAM 權限,攻擊者可以先在低風險環境站穩腳步,再利用相同角色、同一組金鑰、相似的信任關係,滲透到正式環境。最小權限如果只在生產環境執行,等於只在最貴的門口裝鎖,後門卻敞開。

三、最小權限審計實戰:先找出哪裡過大,再處理怎麼縮小

第一步:盤點所有身份與附加政策

審計不要從單一政策開始,而要從身份清單開始。把 UserGroupRole、Lambda 執行角色、ECS Task Role、EC2 Instance Profile、CI/CD 使用的部署角色全部列出來,再把附加的 managed policy、inline policy、permission boundary、trust policy 一併收進來。很多風險不是來自政策本身,而是來自某個角色被多處引用,改一個地方卻忘了其他入口。

第二步:先找 *,再看它是否真的必要

實作上可以先把政策中所有 ActionResource、條件鍵裡的萬用字元抓出來,建立一份待審清單。不是看到 * 就直接刪,而是要分類:是因為 AWS 服務本來就需要列舉很多動作,還是因為團隊懶得收斂;是因為資源 ARN 真的無法預先確定,還是其實可以透過標籤與命名規則縮小;是因為條件鍵少了,還是根本沒想過要加上下文限制。

這一步最重要的不是技術,而是判斷。每一個 * 都要回答三個問題:誰在用、用來做什麼、如果被濫用會發生什麼事。只要有一題答不清楚,這個 * 就不該留著。

第三步:用 CloudTrail 看真實行為,而不是只看政策文字

政策文字和實際行為常常不一致。你可能以為某個角色只會部署應用,但 CloudTrail 會告訴你它最近還查了哪些服務、改了哪些資源、碰了哪些敏感 API。從最近 30 天或 90 天的事件紀錄出發,找出高頻動作、從未使用的動作、異常時間點、異常來源 IP、異常區域。把實際行為和政策比對後,通常會發現一大堆根本沒被用到的權限。

AWS IAM Access Advisor 也很有用,至少可以先看服務層級的 last accessed 時間。若某個角色連某個服務都沒碰過,卻仍握有該服務的大量寫入權限,那就值得優先收斂。審計的目標不是追求文件上的完美,而是讓現實中的使用痕跡與授權範圍盡量一致。

第四步:把權限按任務切開,不要按部門一口氣包住

AWS帳號快速充值 很多組織會用「給整個團隊一張大政策」的方式省事,結果一個人拿到的權限,遠超過自己的工作內容。更好的做法是以任務切割:部署、讀取、排程、查詢、維運、緊急處置,各自一張政策或一組政策。這樣不只方便審計,也方便追責。若未來發現哪個權限過大,縮小時不會傷到整個團隊。

第五步:加上條件與邊界,讓權限可控

* 收斂後,還要把條件補上。常見且實用的限制包括:必須透過特定 VPC Endpoint 才能存取資料服務、只允許特定區域、必須帶有特定 Session Tag、必須啟用 MFA、只能操作某個前綴、只能傳遞指定角色。這些條件不一定每個場景都能套用,但只要能加,就能大幅降低誤用和濫用空間。

四、從寬到窄:幾個實際的修正思路

範例一:把整個服務全開,改成只允許必要動作

下面這種寫法很常見,看起來簡單,實際上太大:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": "*"
    }
  ]
}

如果這個角色只是要上傳使用者圖片,那就不需要列出 bucket、刪除 bucket、改通知、改生命週期。可以把權限縮成只允許特定物件路徑的上傳與讀取,必要時再加上前綴限制與內容型條件。權限的設計應該跟資料流對齊,而不是跟服務名稱對齊。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::app-upload-bucket/user-uploads/*"
      ],
      "Condition": {
        "StringEquals": {
          "aws:PrincipalTag/department": "product"
        }
      }
    }
  ]
}

範例二:把 iam:PassRole 收到固定角色

如果部署管線需要把角色傳給運算資源,不要讓它能傳任何角色。把可傳遞的角色名單鎖死,只允許指定服務與指定用途。這樣就算部署帳號被盜,攻擊者也不能隨意掛上高權限角色。PassRole 的關鍵不在有沒有,而在能不能傳錯。

範例三:把讀取權限改成只看必要前綴

有些應用只需要讀取自己的資料夾,卻常被授予整個 bucket 的讀取權限。其實只要將物件路徑設計成清楚的前綴,例如依使用者、租戶或環境拆分,就能把權限切得很細。權限越靠近資料結構,越容易維護,也越容易理解。反過來說,如果資料命名亂成一團,再精細的政策也會失去意義。

五、真正有用的審計,不是找出誰寫了 *,而是建立不再需要 * 的系統

最小權限審計如果只做一次,很快就會回到原點。因為新的功能、臨時需求、緊急修補,都會把新權限重新堆上去。要讓審計有效,必須把流程做成制度,而不是活動。至少要有幾件事長期執行。

  • 新政策必須走審查,且要有人問「為什麼需要這個 *」。
  • 重要角色要定期做權限回顧,檢查是否還在使用。
  • 政策修改、附加、版本切換要有告警,避免暗中放大權限。
  • 部署與維運角色要分開,不能把應用管理與 IAM 管理混在一起。
  • 臨時放權要有到期日,到期自動回收,而不是人工想起來才收。

如果組織願意再往前一步,還可以把權限政策版本化,讓每次變更都進版本控制,由 Pull Request 來審核。當政策成為程式碼,風險就不再藏在 Console 裡,而是會出現在日常協作流程中。這時候,安全團隊不必一直追著人補洞,開發團隊也能更清楚地理解自己到底在放什麼權限。

結語:把 * 當作警報,不要把它當作習慣

在 AWS IAM 裡,萬用字元不是原罪,習慣才是。* 有時候是必要的過渡,有時候是服務設計的現實限制,但它絕不該成為默認答案。每次看到 ActionResource 的萬用字元,都應該把它當成一次警報:這裡是不是權限太大了,這裡是不是少了條件,這裡是不是可以更精準。

最小權限審計真正要解決的,不是把政策改得更漂亮,而是讓風險變得可見、可查、可收斂。當你的政策能回答「誰、在什麼情況下、只能對哪些資源、做哪些動作」,安全就不再只是理想,而是可以被落地的日常。

Telegram售前客服
客服ID
@cloudcup
联系
Telegram售后客服
客服ID
@yanhuacloud
联系