moto icon indicating copy to clipboard operation
moto copied to clipboard

Moto Server allows deploying invalid CFN templates

Open jabalazs opened this issue 10 months ago • 1 comments

Running moto v5.0.28

Replication Steps

  1. Run moto_server
  2. Deploy an invalid template:
$ aws --endpoint-url http://127.0.0.1:5000 cloudformation create-stack --stack-name test-stack --template-body file://template.json

where template.json is:

{
  "Resources": {
    "MyTopic": {
      "Type": "AWS::SNS::Topic",
      "Properties": {
        "TopicName": "MySNSTopic",
        "asdfasdf": true,
        "qweqweqwe": true
      },
      "Foo": {"Bar": 0}
    }
  }
}
  1. The template gets successfully deployed:
$ aws --endpoint-url http://127.0.0.1:5000 cloudformation get-template --stack-name test-stack
{
    "TemplateBody": {
        "Resources": {
            "MyTopic": {
                "Type": "AWS::SNS::Topic",
                "Properties": {
                    "TopicName": "MySNSTopic",
                    "asdfasdf": true,
                    "qweqweqwe": true
                },
                "Foo": {
                    "Bar": 0
                }
            }
        }
    }
}

Expectation

When trying to deploy an invalid template we should get an error. For example running cfn-lint returns:

$ cfn-lint template.json
E3002 Additional properties are not allowed ('asdfasdf' was unexpected)
final_template.json:7:9

E3002 Additional properties are not allowed ('qweqweqwe' was unexpected)
final_template.json:8:9

E3001 Additional properties are not allowed ('Foo' was unexpected)
final_template.json:10:7

Trying to deploy this template to a real account returns

An error occurred (ValidationError) when calling the UpdateStack operation: Invalid template resource property 'Foo'

Additional info

If I modify the template slightly by removing the top-level Foo:

{
  "Resources": {
    "MyTopic": {
      "Type": "AWS::SNS::Topic",
      "Properties": {
        "TopicName": "MySNSTopic",
        "asdfasdf": true,
        "qweqweqwe": true
      }
    }
  }
}

and try to deploy the stack to a real account, the CLI doesn't return an error anymore, but the creation is triggered and fails with the following CREATE_FAILED event:

{
    "StackId": "arn:aws:cloudformation:us-east-1:<accountid>:stack/test-stack/f1ce07b0-e894-11ef-a9bd-0affcc3fac61",
    "EventId": "MyTopic-CREATE_FAILED-2025-02-11T16:26:31.105Z",
    "StackName": "test-stack",
    "LogicalResourceId": "MyTopic",
    "PhysicalResourceId": "",
    "ResourceType": "AWS::SNS::Topic",
    "Timestamp": "2025-02-11T16:26:31.105000+00:00",
    "ResourceStatus": "CREATE_FAILED",
     "ResourceStatusReason": "Resource handler returned message: \"Model validation failed (#: extraneous key [asdfasdf] is not permitted)\" (RequestToken: bb2ea196-a4c5-c177-a4df-d21016441acd, HandlerErrorCode: InvalidRequest)",
            "ResourceProperties": "{\"asdfasdf\":\"true\",\"qweqweqwe\":\"true\",\"TopicName\":\"MySNSTopic\"}"
}

jabalazs avatar Feb 11 '25 14:02 jabalazs

Hi @jabalazs, thanks for raising this.

The first issue should be a simple enhancement. We already use the cfn_lint library when the user explicitly calls validate_template - it makes sense to also call this validation when creating a stack.

The second, to validate the supplied parameters, is probably also doable. The botocore library already lists all parameters for each request, so we should be able to extract that information. This is just a bit more work, as I don't think we have anything in place for that yet.

PR's are welcome, if you want to take a stab at either and/or both!

bblommers avatar Feb 15 '25 12:02 bblommers