#7669·checkov

CKV_AWS_24, CKV_AWS_25 and CKV_AWS_260 silently skip a security group when FromPort resolves to a non-integer

Author: zfLQ2qx2Created Sep 4, 2026Updated Sep 12, 2026

Describe the issue

AbsSecurityGroupUnrestrictedIngress.range() calls int(rule['FromPort']) without guarding it. When FromPort is a Ref to a parameter whose resolved value is not an integer, the call raises ValueError, the framework logs it and moves on, and the check produces no result at all. It is not reported as failed, passed or skipped, so the scan is green on a rule nobody checked.

CKV_AWS_24 (port 22), CKV_AWS_25 (port 3389) and CKV_AWS_260 (port 80) all inherit range(), so one unparsable port disables all three on that resource.

evaluate-variables: true makes this easy to hit, because a parameter with Default: '' is substituted into the property. An empty string is a normal way to spell an optional parameter in CloudFormation.

Examples

.checkov.yaml:

yaml
evaluate-variables: true

repro.yaml:

yaml
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  IngressPort:
    Type: String
    Default: ''
Resources:
  Group:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: 'repro'
      VpcId: 'vpc-00000000'
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: !Ref IngressPort
          ToPort: !Ref IngressPort
          CidrIp: '0.0.0.0/0'

checkov --framework cloudformation --config-file .checkov.yaml -f repro.yaml:

[ERROR]  Failed to run check CKV_AWS_24 on /repro.yaml:AWS::EC2::SecurityGroup.Group
Traceback (most recent call last):
  File ".../checkov/common/checks/base_check.py", line 68, in run
    check_result["result"] = self.scan_entity_conf(entity_configuration, entity_type)
  File ".../checkov/cloudformation/checks/resource/base_resource_check.py", line 33, in scan_entity_conf
    return self.scan_resource_conf(conf)
  File ".../checkov/cloudformation/checks/resource/aws/AbsSecurityGroupUnrestrictedIngress.py", line 39, in scan_resource_conf
    if self.range(rule):
  File ".../checkov/cloudformation/checks/resource/aws/AbsSecurityGroupUnrestrictedIngress.py", line 50, in range
    if int(rule['FromPort']) <= int(self.port) <= int(rule['ToPort']):
ValueError: invalid literal for int() with base 10: ''

Same traceback for CKV_AWS_25 and CKV_AWS_260. Results:

Passed checks: 0, Failed checks: 1, Skipped checks: 0

The one failure is CKV_AWS_23. The three port checks are absent from every count.

Version

checkov 3.3.16, python 3.13, alpine.

Additional context

scan_resource_conf already gates on the types of FromPort and ToPort matching, but str and str passes that gate for any pair of strings. A guard in range() that returns CheckResult.UNKNOWN (or has range() report that it could not decide) would keep the resource in the report instead of dropping it. Failing loudly would also be an improvement over the current behaviour, since today the only signal is a log line on stderr that a CI job is likely to discard.

A resource-level suppression is a workaround, and it at least makes the gap visible: # checkov:skip=CKV_AWS_24:reason on the resource turns the three missing results into three reported as skipped.