<p>kubeadmは、ブートストラップトークンを削除する前にログに記録する場合があります</p>

作成日 2020年09月11日  ·  3コメント  ·  ソース: kubernetes/kubeadm

これを提出する前に、kubeadmの問題でどのキーワードを検索しましたか?

tokenerror

これはバグレポートですか、それとも機能リクエストですか?

_セキュリティ_レポート

概要:

kubeadmdeleteコマンドは、ブートストラップトークンIDまたは完全なトークンのいずれかを入力として受け取ります。 入力が単なるIDであるか完全なトークンであるかを判断する前に、 kubeadmklogを使用して入力をログに記録します。 削除が失敗した場合、トークンは有効なままになります。 ログにアクセスできる攻撃者は、ログを使用して、クラスターの作成やノードの既存のクラスターへの参加など、ブートストラップトークンを必要とするアクションを実行する可能性があります。

Kubernetesバージョン:

脆弱なコードはkubernetes1.19に存在します。 klogへの呼び出しを含む特定の行は、2019-03-24に最後に編集されました。

詳細:

脆弱なコードは、 github.com/kubernetesリポジトリのファイルkubernetes/cmd/kubeadm/app/cmd/token.go 423行目にあります。関数全体は次のとおりです。

// RunDeleteTokens removes a bootstrap tokens from the server.
func RunDeleteTokens(out io.Writer, client clientset.Interface, tokenIDsOrTokens []string) error {
    for _, tokenIDOrToken := range tokenIDsOrTokens {
        // Assume this is a token id and try to parse it
        tokenID := tokenIDOrToken
        klog.V(1).Infof("[token] parsing token %q", tokenIDOrToken) // POTENTIAL LEAK HERE
        if !bootstraputil.IsValidBootstrapTokenID(tokenIDOrToken) {
            // Okay, the full token with both id and secret was probably passed. Parse it and extract the ID only
            bts, err := kubeadmapiv1beta2.NewBootstrapTokenString(tokenIDOrToken)
            if err != nil {
                return errors.Errorf("given token %q didn't match pattern %q or %q",
                    tokenIDOrToken, bootstrapapi.BootstrapTokenIDPattern, bootstrapapi.BootstrapTokenIDPattern)
            }
            tokenID = bts.ID
        }

        tokenSecretName := bootstraputil.BootstrapTokenSecretName(tokenID)
        klog.V(1).Infof("[token] deleting token %q", tokenID)
        if err := client.CoreV1().Secrets(metav1.NamespaceSystem).Delete(context.TODO(), tokenSecretName, metav1.DeleteOptions{}); err != nil {
            return errors.Wrapf(err, "failed to delete bootstrap token %q", tokenID)
        }
        fmt.Fprintf(out, "bootstrap token %q deleted\n", tokenID)
    }
    return nil
}

そして、その関数を(同じファイル内で)呼び出すkubeadmコマンドの定義は次のとおりです。

    deleteCmd := &cobra.Command{
        Use:                   "delete [token-value] ...",
        DisableFlagsInUseLine: true,
        Short:                 "Delete bootstrap tokens on the server",
        Long: dedent.Dedent(`
            This command will delete a list of bootstrap tokens for you.

            The [token-value] is the full Token of the form "[a-z0-9]{6}.[a-z0-9]{16}" or the
            Token ID of the form "[a-z0-9]{6}" to delete.
        `),
        RunE: func(tokenCmd *cobra.Command, args []string) error {
            if len(args) < 1 {
                return errors.Errorf("missing subcommand; 'token delete' is missing token of form %q", bootstrapapi.BootstrapTokenIDPattern)
            }
            kubeConfigFile = cmdutil.GetKubeConfigPath(kubeConfigFile)
            client, err := getClientset(kubeConfigFile, dryRun)
            if err != nil {
                return err
            }

            return RunDeleteTokens(out, client, args)
        },
    }

影響:

ログからブートストラップトークンを取得した攻撃者は、それを使用してkubeadm認証し、新しいクラスターを作成したり、ノードを既存のクラスターに参加させたりする可能性があります。 攻撃者は、 kubeadmを使用して他のアクションを実行することもできます。たとえば、他のトークンの一覧表示や削除などです。

追加情報:

私はこの脆弱性をHackerOneに報告しましたが、攻撃の複雑さと重大度が低いことに基づいて、これは公に報告および修正できると考えているとのことです。

修正を実装するkubernetesのPRを開きました: https

aresecurity kincleanup prioritbacklog

全てのコメント3件

kubeadmのdeleteコマンドは、ブートストラップトークンIDまたは完全なトークンのいずれかを入力として受け取ります。 入力が単なるIDであるか完全なトークンであるかを判断する前に、kubeadmはklogを使用して入力をログに記録します。 削除が失敗した場合、トークンは有効なままになります。 ログにアクセスできる攻撃者は、ログを使用して、クラスターの作成やノードの既存のクラスターへの参加など、ブートストラップトークンを必要とするアクションを実行する可能性があります。

こんにちは。問題をログに記録していただきありがとうございます。 このようなログを読み取るには、適切な権限が必要です。ログはルートアクセス下にあるか、ブートストラップトークンよりも高いアクセス権を持つ特定のグループに与えられていると思います。

また:

  • トークンが有効な形式の場合、 kubeadm token delete実行中に--v=>1を有効にする必要があります
  • トークンはデフォルトで24時間後に期限切れになります

PRの改善はほとんど問題ないと思いますが、そのような攻撃は複雑であるため、古いリリース(<1.20)にバックポートするべきではないと思います。

私は@ neolit123にバックポートしないことに同意します(本当に特定のニーズがない限り)
修正のWRT、ログからTokenIDを削除するために+1します

https://github.com/kubernetes/kubernetes/pull/94727がマージされたため終了し
ありがとう

このページは役に立ちましたか?
0 / 5 - 0 評価