Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions checkov/terraform/checks/resource/aws/IAMRoleMaxSessionDuration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from checkov.common.models.enums import CheckCategories, CheckResult
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck

MAX_SESSION_DURATION = 3600 # 1 hour in seconds


class IAMRoleMaxSessionDuration(BaseResourceCheck):
def __init__(self):
name = "Ensure IAM role max session duration does not exceed 1 hour"
id = "CKV_AWS_341"
supported_resources = ["aws_iam_role"]
categories = [CheckCategories.IAM]
super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)

def scan_resource_conf(self, conf):
"""
Looks for max_session_duration in aws_iam_role resources.
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role

The default value in AWS is 3600 seconds (1 hour).
Allowing sessions longer than 1 hour increases the blast radius
of a compromised credential.

Pass: max_session_duration is not set (defaults to 3600) or is <= 3600
Fail: max_session_duration is set to a value > 3600
"""
max_session_duration = conf.get("max_session_duration")

# not set — defaults to 3600, passes
if not max_session_duration:
return CheckResult.PASSED

# handle list wrapping from Terraform parser
if isinstance(max_session_duration, list):
max_session_duration = max_session_duration[0]

# skip if variable reference (can't evaluate at scan time)
if not isinstance(max_session_duration, int):
return CheckResult.UNKNOWN

if max_session_duration <= MAX_SESSION_DURATION:
return CheckResult.PASSED

return CheckResult.FAILED


scanner = IAMRoleMaxSessionDuration()
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import unittest
from pathlib import Path

from checkov.terraform.checks.resource.aws.IAMRoleMaxSessionDuration import scanner
from checkov.common.models.enums import CheckResult


class TestIAMRoleMaxSessionDuration(unittest.TestCase):

def test_success_no_max_session_duration(self):
"""Role with no max_session_duration set — defaults to 3600, should pass."""
resource_conf = {
"name": ["test_role"],
"assume_role_policy": ['{"Version":"2012-10-17"}'],
}
result = scanner.scan_resource_conf(conf=resource_conf)
self.assertEqual(result, CheckResult.PASSED)

def test_success_max_session_duration_3600(self):
"""Role with max_session_duration exactly 3600 — should pass."""
resource_conf = {
"name": ["test_role"],
"assume_role_policy": ['{"Version":"2012-10-17"}'],
"max_session_duration": [3600],
}
result = scanner.scan_resource_conf(conf=resource_conf)
self.assertEqual(result, CheckResult.PASSED)

def test_success_max_session_duration_1800(self):
"""Role with max_session_duration below 3600 — should pass."""
resource_conf = {
"name": ["test_role"],
"assume_role_policy": ['{"Version":"2012-10-17"}'],
"max_session_duration": [1800],
}
result = scanner.scan_resource_conf(conf=resource_conf)
self.assertEqual(result, CheckResult.PASSED)

def test_failure_max_session_duration_7200(self):
"""Role with max_session_duration of 7200 (2 hours) — should fail."""
resource_conf = {
"name": ["test_role"],
"assume_role_policy": ['{"Version":"2012-10-17"}'],
"max_session_duration": [7200],
}
result = scanner.scan_resource_conf(conf=resource_conf)
self.assertEqual(result, CheckResult.FAILED)

def test_failure_max_session_duration_43200(self):
"""Role with max_session_duration of 43200 (12 hours, AWS max) — should fail."""
resource_conf = {
"name": ["test_role"],
"assume_role_policy": ['{"Version":"2012-10-17"}'],
"max_session_duration": [43200],
}
result = scanner.scan_resource_conf(conf=resource_conf)
self.assertEqual(result, CheckResult.FAILED)

def test_unknown_variable_reference(self):
"""Role with max_session_duration as a variable reference — should be UNKNOWN."""
resource_conf = {
"name": ["test_role"],
"assume_role_policy": ['{"Version":"2012-10-17"}'],
"max_session_duration": ["${var.max_session_duration}"],
}
result = scanner.scan_resource_conf(conf=resource_conf)
self.assertEqual(result, CheckResult.UNKNOWN)


if __name__ == "__main__":
unittest.main()