aws-cloudformation / aws-cloudformation/cloudformation-coverage-roadmap

`\x1B` in Reason field of custom resources can break stack (The response contains control characters or otherwise invalid characters)

Open
#1,601 0 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
No language data
Stars
1.1k
Forks
62
PR merge metrics
No merged PRs in 30d

Description

### Name of the resource

Other

### Resource Name

_No response_

### Issue Description

The `Reason` field of a custom resource can make a stack somewhat unusable for a while when it contains `\x1B`. Trying to get events or drift results in "The response contains control characters or otherwise invalid characters".

![image](https://user-images.githubusercontent.com/1156773/233218726-846c9a9f-a438-4b70-a4e1-96ce693b6afb.png)

CDK also fails with the same message in a loop.

![image](https://user-images.githubusercontent.com/1156773/233218914-384b11ac-90e9-4a47-9b6c-587444094ab2.png)

The stack can still be updated and deleted. If it gets updated enough times, it seems like the bad event goes out of scope and the UI starts working again. CDK still fails tracking deployment for me, but hopefully will start working soon without having to delete the stack and start over.

### Expected Behavior

I would expect the `Reason` field to be either filtered or protected against unsupported values. Ideally it's just filtered and those unsupported characters are ignored or the reason completely removed. But if that doesn't make sense, `ResponseURL` should at least return some kind of error so the problem surfaces in a more manageable way.

### Observed Behavior

When the `Reason` field of a custom resource contains invalid characters, no stack events can be viewed at all. The custom resource event can't be viewed. Any other past or future event can't be viewed. I have also noticed stack drift detection doesn't work.

### Test Cases

I first observed that when I tried to create a custom resource that builds a Docker image in CodeBuild. When the build failed, I took the output from `docker build` and put the last few lines into the `Reason` field of my custom resource. Since `docker build` uses terminal escape codes, the `Reason` field ended up including the scape code. That turned the stack unusable.

Here is a simplified version of the CDK code used:

```
import * as cdk from 'aws-cdk-lib';
import { aws_lambda as lambda } from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class CfnBugStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);

const l = new lambda.Function(this, 'MyFunction', {
code: lambda.Code.fromInline(`
exports.handler = async function(event) {
console.log('request:', JSON.stringify(event, null, 2));
const responseBody = JSON.stringify({
Status: 'FAILED',
Reason: Buffer.from('MG0bWzkxbSsgbXYgRlVORElORy55bWwgL2N1c3RvbS1kaXIKG1swbVJlbW92aW5nIGludGVybWVkaWF0ZSBjb250YWluZXIgYzFlNGYxNTI0ZTExCiAtLS0+IDY2YjFlNWNjYzVlOApTdGVwIDE5LzIwIDogQ09QWSA=', 'base64').toString('utf-8'),
PhysicalResourceId: 'ok',
StackId: event.StackId,
RequestId: event.RequestId,
LogicalResourceId: event.LogicalResourceId,
NoEcho: false,
});

const parsedUrl = require('url').parse(event.ResponseURL);
const requestOptions = {
hostname: parsedUrl.hostname,
path: parsedUrl.path,
method: 'PUT',
headers: {
'content-type': '',
'content-length': responseBody.length,
},
};

return new Promise((resolve, reject) => {
try {
const request = require('https').request(requestOptions, resolve);
request.on('error', reject);
request.write(responseBody);
request.end();
} catch (e) {
reject(e);
}
});
}
`),
runtime: lambda.Runtime.NODEJS_16_X,
handler: 'index.handler',
});

new cdk.CustomResource(this, 'CustomResource', {
serviceToken: l.functionArn,
});
}
}

const app = new cdk.App();
new CfnBugStack(app, 'CfnBugStack');
```

### Other Details

_No response_

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the custom-resource response through ResponseURL with an ESC character in the Reason field, then inspect how CloudFormation processes that value into stack events, drift results, and CDK tracking. Done means invalid control characters are safely handled or rejected with a manageable error, with coverage for the reported custom-resource scenario.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws
Domain
cloud, infrastructure
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.