Skip to content

Conversation

@automate9000
Copy link

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Description

When scanning Terraform JSON with --framework terraform_json, and that json contains a list, but does not contain a tab (just spaces), Checkov crashes with:

[MainThread  ] [ERROR]  Failed to invoke function /home/student/.local/lib/python3.10/site-packages/checkov/common/runners/runner_registry._parallel_run with (<checkov.terraform_json.runner.TerraformJsonRunner object at 0xffff8aaa96f0>, '/home/student/Documents/checkov/repo2', ['/tmp/tmpjhwzsu5i'], None, <checkov.runner_filter.RunnerFilter object at 0xffff8aac51e0>, True, None)
Traceback (most recent call last):
  File "/home/student/.local/lib/python3.10/site-packages/checkov/common/parallelizer/parallel_runner.py", line 72, in func_wrapper
    result = original_func(*item)
  File "/home/student/.local/lib/python3.10/site-packages/checkov/common/runners/runner_registry.py", line 836, in _parallel_run
    report = runner.run(
  File "/home/student/.local/lib/python3.10/site-packages/checkov/terraform_json/runner.py", line 87, in run
    self.definitions, self.definitions_raw, parsing_errors = create_definitions(file_paths)
  File "/home/student/.local/lib/python3.10/site-packages/checkov/terraform_json/utils.py", line 59, in create_definitions
    template, file_lines = parse(file_path)
  File "/home/student/.local/lib/python3.10/site-packages/checkov/terraform_json/parser.py", line 32, in parse
    template, template_lines = loads(file_path=file_path)
  File "/home/student/.local/lib/python3.10/site-packages/checkov/terraform_json/parser.py", line 77, in loads
    template = prepare_definition(template)
  File "/home/student/.local/lib/python3.10/site-packages/checkov/terraform_json/parser.py", line 89, in prepare_definition
    definition_new[block_type] = handle_block_type(block_type=block_type, blocks=blocks)
  File "/home/student/.local/lib/python3.10/site-packages/checkov/terraform_json/parser.py", line 97, in handle_block_type
    for block_name, config in blocks.items():
AttributeError: 'list' object has no attribute 'items'

I believe order of operations is at fault here https://github.com/bridgecrewio/checkov/blob/main/checkov/terraform_json/parser.py#L43 where only if yaml parsing fails (tab present) will it execute json_parse, allowing the dict to populate as expected by handle_block_type() - https://github.com/bridgecrewio/checkov/blob/main/checkov/terraform_json/parser.py#L97

To reproduce:

Fails:

{
    "provider": [
        {
            "aws": {
                "region": "us-west-2",
                "profile": null
            }
        }
    ]
}

Works:

{
    "provider": [
	    {
            "aws": {
                "region": "us-west-2",
                "profile": null
            }
        }
    ]
}

Fixes # (issue)

  • Add _normalize_provider_blocks_list() in checkov/terraform_json/parser.py to convert provider blocks that arrive as a list of dicts into the dict-of-lists shape handle_block_type() already expects.
  • Update prepare_definition() so that when block_type == BlockType.PROVIDER and blocks is a list, it normalizes via _normalize_provider_blocks_list() before calling handle_block_type().
  • Add a defensive guard in handle_block_type() so that if blocks is still a list for any reason, we log a debug message and return an empty result instead of raising an AttributeError.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my feature, policy, or fix is effective and works
  • New and existing tests pass locally with my changes

Comment on lines +101 to +103
if isinstance(blocks, list):
logger.debug("Unexpected list for block_type %s in handle_block_type: %r", block_type, blocks)
return result
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block is not necessary since in lines 89-91 it normalize to dict, no?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put this here for house keeping, incase you get drift later and the issues arises again, not required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants