vault write auth/aws/role

Without this restriction, we could simply trigger a request to a server under our control and return a fake caller identity. Depending on the database backend, this secret could be a static user-password combination, a short lived client certificate or even a dynamically created credential pair. 'sub': 'arn:aws:iam::superprivileged-aws-accountXYZ'. Lets take a look.

That way, instances that have them will be able to authenticate against Vault. Like most companies, we have used the default instance user (ec2-user, ubuntu, etc) and a master key to log into a running instance. * at least be one bound parameter should be specified on the role. If you did not do this when creating them, you can easily add them in the AWS Console. Without any change to the Vault codebase, this could severely degrade the security of this authentication mechanism from one moment to another. By enabling and configuring the. token_meta_client_arn arn:aws:sts::362381645759:assumed-role/chef-qa/i-01ab34829fee925fd In both cases, the Vault server now has access to a public key that can verify the signature of the JWT: customClaims := &gcputil.CustomJWTClaims{}, if err = jwtVal.Claims(key, baseClaims, customClaims); err != nil {, if err = validateBaseJWTClaims(baseClaims, loginInfo.RoleName); err != nil {. This mechanism makes it possible to pre-sign a request and forward it to another party to allow a limited form of impersonation. For example, AWS might decide to put STS behind a load balancing frontend, which uses the Host header for routing decisions. We can now use our OIDP to sign a JWT that contains an arbitrary GetCallerIdentityResponse as part of its subject claim. Login to the UI with a root token or other token that can create any policies. If verification succeeds, Vault fills out the loginInfo struct that is later used to grant or deny access. The only requirement is that the attacker knows the name of an privileged AWS role in the target Vault server. Looking at the buildHttpRequest method, two approaches come to mind: The code for calculating targetUrl targetUrl := fmt.Sprintf("%s/%s", endpoint, parsedUrl.RequestURI()) doesn't look very robust against URL parsing issues. Now simply use the token to sign-in to Vault: curl --request POST --data '{"role": "my-gce-role", "jwt" : "."}'. "SubjectFromWebIdentityToken":"arn:aws:iam::superprivileged-aws-accountXYZ"}. Ill go into the exact layout of this request later in the post, but for now just assume that the request allows Vault to verify the AWS IAM role of the caller. You can enable and test Vault's AWS auth method following the steps below. An end-to-end attack against a vulnerable configuration will look like this: Create a service account in a GCP project you control and generate a private key using gcloud: gcloud iam service-accounts keys create key.json --iam-account sa-name@project-id.iam.gserviceaccount.com. Use your own AWS account to register an OID IdP -> AWS IAM role mapping. When the lambda function executes, it authenticates to Vault by sending a request to the, API endpoint. If the AWS ARN/UserID in our fake GetCallerIdentityResponse has privileges on the Vault server we get a valid session token back, which we can use to interact with the Vault server to fetch some secrets. You will need to use the Vault CLI. In contrast to service account tokens, this token is signed by an, . We will now illustrate how to use the iam method, by providing two examples. Finally, both discussed vulnerabilities demonstrate how difficult it is to write secure software. Even though Vault will always create a HTTPS request pointing at the hardcoded endpoint, the attacker has full control over the. Rotating old or compromised database credentials is straightforward and can be centrally enforced. This means that calling, with a (JSON encoded) server response such as, {abc : xzy}, This brings us really close to our goal of spoofing an arbitrary caller identity: We just need to find a STS action that reflects attacker controlled text as part of its API response. While the OIDC provider setup adds some complexity, we end up with a nice authentication bypass for arbitrary AWS enabled roles. This means that calling parseGetCallerIdentityResponse with a (JSON encoded) server response such as {abc : xzy} will succeed and return an (empty) CallerIdentityResponse structure. The Vault server sends the pre-signed requests to the STS host and extracts the AWS IAM information out of the result. Connect to your instance with SSH. It can be used as a shared password manager for human users, but its feature set is optimized for API based access by other services. , you can create a mapping between certain IAM users or roles to Vault roles. token_meta_auth_type iam parseGetCallerIdentityResponse is called on every response received from STS as long as the status code is 200. Create a service account in a GCP project you control and generate a private key using gcloud: gcloud iam service-accounts keys create key.json --iam-account, sa-name@project-id.iam.gserviceaccount.com, Sign a JWT with a fake compute_engine claim describing an existing and privileged VM.

. See. claim that lists details about the instance, which are processed as part of the auth process: JWT has a number of design choices that make it very prone to implementation errors (see. Create a minimal OIDC IdP. There is an easy to miss problem with this code: Vault never enforces or verifies that the STS response is actually XML encoded. token_duration 768h If you're using Lambdas, then inferencing isn't something you should use. For the aws auth backend to work, it needs to have a couple of additional privileges. token_meta_client_user_id AROAJTX274TFBJ6ZFA3YC, You can authenticate from a qa instance with: Of course, there is a reason why the authentication works as described: AWS IAM doesnt have a straightforward way of proving a services identity to other non-AWS services. This means we are not limited to pre-signing requests to GetCallerIdentity and can create requests to any action of the. It then calls submitCallerIdentity to forward the request to the STS server and to fetch and parse the result in parseGetCallerIdentityResponse: func submitCallerIdentityRequest(ctx context.Context, maxRetries int, method, endpoint string, parsedUrl *url.URL, body string, headers http.Header) (*GetCallerIdentityResult, error) {, request := buildHttpRequest(method, endpoint, parsedUrl, body, headers), retryableReq, err := retryablehttp.FromRequest(request), response, err := retryingClient.Do(retryableReq), responseBody, err := ioutil.ReadAll(response.Body), callerIdentityResponse, err := parseGetCallerIdentityResponse(string(responseBody)), return nil, fmt.Errorf("error parsing STS response"), return &callerIdentityResponse.GetCallerIdentityResult[0], nil, func buildHttpRequest(method, endpoint string, parsedUrl *url.URL, body string, headers http.Header) *http.Request {, targetUrl := fmt.Sprintf("%s/%s", endpoint, parsedUrl.RequestURI()), request, err := http.NewRequest(method, targetUrl, strings.NewReader(body)). for the (canonicalized) request using the caller's secret access key and attach this signature to the request. token_meta_canonical_arn arn:aws:iam::362381645759:role/chef-dev the disallow_reauthentication is set to true so that the instance can only authenticate once. The policies will give members of the teams full control (create, read, update, delete, list) over their team secrets and also ensure that they can access them in the Vault UI. Repeat the above steps for the path qa/secrets. Imagine that you have an AWS Lambda function and want to give it access to a database password stored in Vault. i limit the default session time to 15 minutes (and that still may be longer than it needs to be) and usee the bound_* parameters to limit authentication to specific regions in specific acounts. You could use point a Vault client against your server after setting VAULT_ADDR and VAULT_TOKEN or just run the following commands on your Vault server after SSHing to it.

token_meta_inferred_entity_id n/a This blog post describes two authentication vulnerabilities in HashiCorp Vault, a cloud-native software for secret management. accordingly"],"auth":{"client_token":"s.Kx3bUNw6wEc5bbkrKBiGW6WL","accessor":"TBRh0hvfd4FkYEAyFrUE3i2P","policies":["default","dev","prod"],"token_policies":["default","dev","prod"]. We can now use our OIDP to sign a JWT that contains an arbitrary GetCallerIdentityResponse as part of its subject claim. A popular example use case is to give clients the ability to upload a file to S3 without giving them access to credentials with write permissions. News and updates from the Project Zero team at Google. Sending a request to this action with a valid signed JWT will return the. With vault configured to allow ec2 instances to authenticate and pull secrets, we now need to write a user_data script to take advantage of the access. Otherwise, you will receive an error. Recently I began working on a project to change how we log into our instances in AWS. It will reduce the need to have pre-built AMIs for every single application we have in an autoscaling group. As its name implies, GetCallerIdentity returns details about the IAM role or user whose credentials were used to call the API. As the attacker can just use a service account in their own project, it is straightforward to just grant this permission to the GCP identity Vault is running under or even allUsers. Interfacing with Vault requires authentication and Vault supports role-based access control to govern access to stored secrets. i updated the iam role that was attached to my vault instance with the following: The first statement adds some additional permissions that vault uses to validate the instance that is authenticating. For the iam mechanism, the client signs the token directly. token_meta_inferred_aws_region n/a A vault client that wants to, authenticate, creates a signed token to prove its identity and sends it to the vault, server to get a session token back. Enter "dev" as the policy name and paste the text from dev-policy.hcl into the policy field. Similar to its AWS counterpart, the auth method supports two different authentication mechanisms: mechanism supports arbitrary service accounts and can be used from services such as App Engine or Cloud Functions. The root cause seems to be the merging of two separate authentication flows into a single code path in the parseAndValidateJwt function, which makes it difficult to reason about all security requirements when writing or reviewing the code. The server-side part of this flow is implemented in pathLoginUpdate in builtin/credential/aws/path_login.go: func (b *backend) pathLoginUpdateIam(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {, method := data.Get("iam_http_request_method"). In addition to the normal JWT claims (sub, aud, iat, exp), the tokens returned from the metadata server also contains a special. i dont want to install vault on every node, so i use curl to access the vault server. STS supports 8 different actions, but none gives us the ability to completely control the response. However, tricks like embedding a fake userinfo (, https://sts.amazonaws.com/:foo@example.com/test. ) Finding a reflected parameter that is not constrained to alpha-numeric characters turns out to be tricky. You should then make sure that you added the role tag to your instance and followed all of the above steps correctly. For authentication, it supports pluggable. the attacker gets a valid session token back. This will create a mapping between a vault role named dbclient and the AWS IAM role lambda-role. In practice, only project_id, zone and instance_name are verified and need to be set to valid values. After ruling out the easy way forward, we still have another approach available: Vault does not restrict our URL query parameters. You could use a different domain for the iam_server_id_header_value and header_value, but they should match each other. token_duration 768h While Vault was clearly developed with security in mind and profits from the memory safety and high quality standard library of its implementation language Go, I was still able to identify two critical vulnerabilities in its unauthenticated attack surface.

The token information displayed below If everything goes as planned STS will reflect the token subject as part of its JSON encoded response. token_policies [default dev] auth is built on top of an AWS API method called. If we follow the control flow of the gce method to the end we can see that Vault uses loginInfo.GceMetadata as part of its auth decision in pathGceLogin if two conditions are met: The VM described in the metadata section needs to exist. vault login -method=aws role=dev-role. (string), bodyRaw, err := base64.StdEncoding.DecodeString(bodyB64), headers := data.Get("iam_request_headers"). The issue here is that no check enforces that a token signed by an arbitrary service account doesnt contain GCE compute_engine claims. On the AWS side, the only think that I needed to do was update my Vault IAM role and add an additional role in each of my accounts. token_meta_inferred_aws_region us-east-1 If this approach fails, the Vault server extracts the Subject (sub) claim from the supplied token. Both vulnerabilities (CVE-2020-16250/16251) were addressed by HashiCorp and are fixed in Vault versions 1.2.5, 1.3.8, 1.4.4 and 1.5.1 released in August. token_meta_inferred_entity_id i-07b2ff4cc60049f47. These issues can lead to an authentication bypass in configurations that use the, auth methods, and demonstrate the type of issues you can find in modern cloud-native software. this role includes the first statement from above that allows vault to validate the instance that is authenticating.

Third-party services cant easily verify pre-signed requests and AWS IAM doesnt offer any standard signing primitives that could be used to implement certificate based authentication or JWTs. again. that takes care of most of the busy work around JWT creation and serialization. This is verified using the ServiceAccount GCP API which requires the iam.serviceAccounts.get permission in the project hosting the service account. Both vulnerabilities (, were addressed by HashiCorp and are fixed in Vault versions 1.2.5, 1.3.8, 1.4.4 and 1.5.1 released in, Interfacing with Vault requires authentication and Vault supports role-based access control to govern access to stored secrets. See here for a simple proof-of-concept script that takes care of most of the details. Depending on the database backend, this secret could be a static user-password combination, a short lived client certificate or even a, However, this operational simplicity is only possible because of hidden complexity in the AWS iam auth method. This can be done with the Vault UI or CLI. Cannot retrieve contributors at this time. read access requires that somebody know that path of the secret they want to pull. The function extracts HTTP method, URL, body and headers out of the supplied request body which is stored in data. Using a central secret storage like Vault offers security benefits such as centralized auditing, enforced credentials rotation or encrypted data storage. Packer. This boils down to generating a RSA key pair, creating an OIDC discovery.json and key.json document and hosting the json files on a web server (see, register an OID IdP -> AWS IAM role mapping. As mentioned above, all of this code is shared between the iam and gce auth methods. We are interested in the iam mechanism, which is the recommended variant and also used in our previous Lambda example. Similar to its AWS counterpart, the auth method supports two different authentication mechanisms: iam and gce. Our goal is to trick Vaults submitCallerIdentityRequest function into returning an attacker controlled caller identity. Even with memory-safe languages, strong cryptography primitives, static analysis and large fuzzing infrastructure, some issues can only be discovered by manual code review and an attacker mindset. token_accessor ca210b40-745e-9804-c25f-f21392f2e3dc

It first parses the token without verifying the signature and passes the decoded token into the, "unable to get public key for signed JWT: %v". ) Configure the AWS Auth Method Using the ec2 Method, Create EC2 instances with the dev and qa roles, Configure the AWS Auth Method Using the iam Method. We will use the iam method in the next section.

For instance, add "AWS": "arn:aws:iam::362381645759:root" to the Trust Relationship of the VaultAccess role in the other account. First, create two IAM roles, chef-dev and chef-qa. So something like http://:8200. In my experience, tricky vulnerabilities like this often exist where developers have to interact with external systems and services. can now be used to grant the dbclient role access to the database secret.

Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message, $vault write auth/aws/role/dev-role auth_type=iam policies=dev max_ttl=1h. The function uses the Golang standard XML library to decode an XML response into a GetCallerIdentityResponse structure and returns an error if decoding fails. is already stored in the token helper.

Also do export VAULT_ADDR= including the port. There is an easy to miss problem with this code: Vault never enforces or verifies that the STS response is actually XML encoded. You should run the command shown from a directory containing your SSH key or provide a path to the key.

Serialize a request to it while including an. Vaults aws auth method supports two different authentication mechanisms internally: mechanism, which is the recommended variant and also used in our previous Lambda example. It fetches a signed token by sending a request to the instance identity endpoint of the GCP metadata server. However, tricks like embedding a fake userinfo (https://sts.amazonaws.com/:foo@example.com/test) and similar ideas do not work against the robust Go URL parser. I have a bunch of lambdas in different accounts that would like to auth against this role. Unfortunately, this doesnt provide us with an ability to know what person on the team logged in, only that the default user did. If authentication succeeds, Vault returns a short-lived API token for the, role back to the lambda function. Putting HTTP request forwarding into the unauthenticated external attack surface of a security product requires strong confidence in the implementation and the underlying HTTP libraries. For infrastructure that runs on a supported cloud provider, using the provider's IAM platform for authentication is a logical choice. If you are not sure how, select your instance in the AWS Console and click the Connect button. We can test if everything is setup correctly by sending a direct request to the STS AssumeRoleWithWebIdentity action using the (signed) token from step 3 and the RoleArn used in step 2: 'https://sts.amazonaws.com/?DurationSeconds=900&Action=AssumeRoleWithWebIdentity&Version=2011-06-15&RoleSessionName=web-identity-federation&RoleArn=arn:aws:iam::XZY::YOUR-OIDC-ROLE&WebIdentityToken=YOURTOKEN'. token b19de968-a73c-54f8-a513-a1d4b15bdb48 provisioning al4 disappeared

Sitemap 23

vault write auth/aws/role

This site uses Akismet to reduce spam. rustic chalk paint furniture ideas.