Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CEL(Common Expression Language)で書いた条件にマッチしたIAM ...

CEL(Common Expression Language)で書いた条件にマッチしたIAM Policyを見つける / iam-policy-finder

FUJIWARA Shunichiro

July 22, 2024
Tweet

More Decks by FUJIWARA Shunichiro

Other Decks in Technology

Transcript

  1. 自己紹介 @fujiwara (X/Twitter, GitHub, Bluesky) 面白法人カヤック SREチーム ISUCON 優勝 4回

    / 運営 (出題 )4回 github.com/kayac/ecspresso github.com/fujiwara/lambroll 最近の趣味はランニングと OSS
  2. [Action Required] Add Lambda ListTags permissions for users calling GetFunction

    API ある日 AWSからメールが Lambda GetFunction API の認証に変更に際し、お客様のアクションが必要になる可能 性があるため、ご連絡しております。 これまで、 ListTags API を明示的に使用する場合にのみ、 ListTags への権限が必要でし た。しかし、 GetFunction API 権限を持つプリンシパルにおいても、 GetFunction 呼び 出しにより出力されたタグ情報にはアクセスできました。 2024 年 7 月 27 日以降、 Lambda は GetFunction API を呼び出すプリンシパルに ListTags API に対する明示的な 許可権限が設定されたポリシーがある場合にのみタグデータを返すようになります。 GetFunction API を呼び出すロールに対して、拒否ポリシーが設定されているか、 ListTags API へのアクセスを明示的に許可するポリシーがない場合、 Lambda は GetFunction API 呼び出しへの応答でタグデータを返さなくなります。
  3. 要約すると (これまで ) Lambda GetFunction APIで lambda:ListTags がなくてもタグが取得できた (これから )

    lambda:ListTags 権限がないとタグが取得できなくなる このアカウントには lambda:GetFunction があるけど lambda:ListTags がないポリシーがあるよ 期日までに lambda:ListTags を許可しないとタグが取れなくなるよ! というお知らせ しかし 「どのポリシーが該当しているかは教えてくれない」 どうやって IAMポリシーを洗い出すか
  4. ぱっと AWS SDK Go でコードを書いた 1. GetAccountAuthorizationDetails APIでアカウント内の許可一覧を取得 User, Group,

    Role, Policy(AWSマネージドを含む ) 2. ポリシーの文字列に対して雑に評価 func detect(s string) bool { d, _ := url.QueryUnescape(s) // APIの結果はURL escapeされている l := strings.ToLower(d) // Actionは大文字小文字を区別しないので小文字に揃える return strings.Contains(l, `"lambda:getfunction"`) && !strings.Contains(l, `"lambda:listtags"`) } 3. できた!!
  5. ECSでもなんかメール来てる [要対応 ] IAM ポリシーを更新して明示的な ecs:TagResource の「許可」を追加してくだ さい ECSでも ecs:CreateCluster

    時に ecs:TagResource が必要になると言われている 特定の条件でポリシーを探したいことはこれからも多そう 評価式部分を汎用化したら使い回せるのでは ? この部分をハードコードではなく外部から与えれば … return strings.Contains(l, `"lambda:getfunction"`) && !strings.Contains(l, `"lambda:listtags"`)
  6. CELのいいところ 式評価を自作するのは大変 汎用言語 (Lua, JavaScript, mruby...)を組み込むと、なんでもできすぎる を持つと全てが釘に見える現象 チューリング完全な言語には停止問題がある (無限ループするかも ?)

    CELは非チューリング完全で式評価に特化、高速、安全に実行可能 Go, Java, C++に組み込み可能 GoogleCloud, Kubernetes, istioなどで既に実用されている 型あり (bool, int, uint, double, string, timestamp, duration...) 演算子 ! , && , || , == , != , > , < ... 文字列関数 matches (正規表現 ) startsWith ...
  7. CEL 式の例 // 数値の範囲チェック age >= 18 && age <

    65 // 文字列の前方一致や正規表現マッチ name.startsWith('Foo') name.matches('^Foo.*') // リスト内の要素に条件を満たすものがあるか roles.exists(role, role == 'admin') // 日付、時間の比較 request.date < timestamp('2023-12-31T23:59:59Z') timeout >= duration('10s') これらを組み合わせて評価した結果を任意の値 (boolだけではなく )で返せる
  8. 名前で検索する例 $ iam-policy-finder 'Name == "AmazonEC2FullAccess"' time=2024-07-18T17:37:13.110+09:00 level=INFO msg="starting scan"

    expr="Name == \"AmazonEC2FullAccess\"" filter=[] time=2024-07-18T17:37:26.272+09:00 level=INFO msg=found policy=AmazonEC2FullAccess versions="[v5 v4 v3 v2 v1]" attached=2 time=2024-07-18T17:37:33.377+09:00 level=INFO msg=finished found=5 scanned=975 Name : policy名
  9. JSONを文字列比較する例 「 Documentに "lambda:GetFunction" があり "lambda:ListTags" がない」 Document.matches('"lambda:[Gg]et[Ff]unction"') && !Document.matches('"lambda:[Ll]ist[Tt]ags"')

    Document : ポリシーの JSON文字列 matches : 文字列に対して正規表現マッチ IAM policy actionは 大文字小文字を区別しない (!!) ので同一視するために正規表現
  10. 正規化したポリシーを評価する例 「 s3:* を許可している」 Statement.exists(s, (s.Action.exists(a, a == "s3:*") &&

    s.Effect == "Allow")) Statement : 正規化した policy statement Action , Resource は文字列でもリストでも許されるのですべてリストに "Resource":"*" → "Resource":["*"] exists(要素, 式) : リストの要素を式で評価してどれかが真になれば真
  11. Actionを小文字に正規化して比較 s3:GetObject , s3:getobject , S3:getObject ...←全部同じ意味 CELには大文字小文字を変換したり無視して比較する方法が (デフォルトでは )ない

    --lc オプション 正規化時に Action要素を全部小文字にする 「 Actionに lambda:GetFunction があるが lambda:ListTags がない」 Statement.exists(s, ( s.Action.exists(a, a == "lambda:getfunction") && !s.Action.exists(a, a == "lambda:listtags") ) ) Document (JSON文字列 )は小文字になりません (ユーザー定義関数が作れるので今後追加予定 )
  12. ECSの件を早速調べてみた 「 ecs:CreateCluster があるが ecs:TagResource がないもの」 // ecs.cel Statement.exists(s, (

    s.Action.exists(a, a == "ecs:createcluster") && !s.Action.exists(a, a == "ecs:tagresouce") )) $ iam-policy-finder ecs.cel --dump --lc 式はファイルに書いてもよい --dump : 見つかったポリシー JSONを出力 --lc : Actionを小文字に正規化
  13. $ iam-policy-finder --lc ecs.cel --dump time=2024-07-18T18:02:23.881+09:00 level=INFO msg=found policy=AmazonEC2ContainerServiceforEC2Role versions="[v7

    v6 v5 v4 v3 v2 v1]" attached=1 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ecs:CreateCluster", "ecs:DeregisterContainerInstance", "ecs:DiscoverPollEndpoint", "ecs:Poll", "ecs:RegisterContainerInstance", "ecs:Submit*" ], "Resource": "*" } ] } AmazonEC2ContainerServiceforEC2Role ← AWSマネージドポリシー !!!!