aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.71k stars 3.93k forks source link

aws-cloudfront: SecretValue not resolved inside Fn.base64() passed to FunctionCode #21980

Open kennu opened 2 years ago

kennu commented 2 years ago

Describe the bug

When creating a CloudFront Function for simple HTTP basic authentication, you can insert a SecretValue into the inline FunctionCode. But if you wrap the SecretValue into Fn.base64(), the actually deployed value is not the resolved SecretValue, but a base64-encoded reference string that looks like {{resolve:secretsmanager:....

In the case of HTTP basic auth, we need to pass a base64-encoded value that contains username:password, where username and password come from Secrets Manager. The workaround is to do the base64-encoding at runtime inside the CloudFront function, but it would be clearer to encode it at deployment time with Fn.base64().

Expected Behavior

Passing a SecretValue wrapped with Fn.base64() should resolve into the base64-encoded secret value.

Current Behavior

Passing a SecretValue wrapped with Fn.base64() is deployed as a base64-encoded unresolved {{resolve:secretsmanager:... string.

Reproduction Steps

Untested quick reference code:

const username = SecretValue.secretsManager(props.secretName, { jsonField: 'username' }).unsafeUnwrap();
const password = SecretValue.secretsManager(props.secretName, { jsonField: 'password' }).unsafeUnwrap();
const authValue = `${username }:${password }`;
const basicAuthFunction = new CloudFrontFunction(this, 'BasicAuthFunction', {
  code: FunctionCode.fromInline(`
    ...
    if (event.request.headers.authorization && event.request.headers.authorization.value === '${Fn.base64(authValue)}')
    ...
    `),
});

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.40.0 (build 56ba2ab)

Framework Version

No response

Node.js Version

v16.13.1

OS

Windows 11 WSL2

Language

Typescript

Language Version

No response

Other information

No response

gsi-eric commented 6 months ago

I have the same issue with python.

        credentials = secret.secret_value_from_json("username").unsafe_unwrap() + ":" + secret.secret_value_from_json("password").unsafe_unwrap()
        # encode_credentials = base64.b64encode((f'{credentials}').encode()).decode('utf-8')
        encode_credentials = credentials

        # print(encode_credentials)
        amplify_app_distribution = cloudfront.Distribution(
            self,
            "CloudFrontWaf",
            default_behavior=cloudfront.BehaviorOptions(
                origin=origins.HttpOrigin(
                    domain_name="main.donai8981bye2.amplifyapp.com",
                    custom_headers={
                        "Authorization": "Basic " + funtions.base64(encode_credentials)
                    },
                ),
                viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
            ),
            price_class=cloudfront.PriceClass.PRICE_CLASS_ALL,
            web_acl_id=amplify_web_acl.attr_arn,
        )