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)
- 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".

CDK also fails with the same message in a loop.

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
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