Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
actions = make_list(self.stmt["Action"])
elif "NotAction" in self.stmt:
actions = make_list(self.stmt["NotAction"])
else:
self.add_finding(
"Statement contains neither Action nor NotAction",
severity.MALFORMED,
location={"string": self.stmt},
)
return False
# Check Resource exists and save the list of resources for later
if "Resource" in self.stmt and "NotResource" in self.stmt:
self.add_finding(
"Statement contains both Resource and NotResource",
severity.MALFORMED,
location={"string": self.stmt},
)
return False
if "Resource" in self.stmt:
resources = make_list(self.stmt["Resource"])
elif "NotResource" in self.stmt:
resources = make_list(self.stmt["NotResource"])
else:
self.add_finding(
"Statement contains neither Resource nor NotResource",
severity.MALFORMED,
location={"string": self.stmt},
)
return False
location={"string": resource},
)
continue
elif parts[0] != "arn":
has_malformed_resource = True
self.add_finding(
'Malformed resource, should start with "arn:"',
severity.MALFORMED,
location={"string": resource},
)
continue
elif parts[1] not in ["aws", "aws-cn", "aws-us-gov", "aws-iso", "*", ""]:
has_malformed_resource = True
self.add_finding(
"Malformed resource, unexpected resource partition",
severity.MALFORMED,
location={"string": resource},
)
continue
# The service is in parts[2]
elif not is_valid_region(parts[3]):
has_malformed_resource = True
self.add_finding(
"Malformed resource, region expected to be of form like us-east-1",
severity.MALFORMED,
location={"string": resource},
)
elif not is_valid_account_id(parts[4]):
has_malformed_resource = True
self.add_finding(
"Unknown Effect used. Effect must be either Allow or Deny",
severity.MALFORMED,
location={"string": self.stmt},
)
return False
if effect == "Allow":
self.effect_allow = True
else:
self.effect_allow = False
# Check Action
if "Action" in self.stmt and "NotAction" in self.stmt:
self.add_finding(
"Statement contains both Action and NotAction",
severity.MALFORMED,
location={"string": self.stmt},
)
return False
if "Action" in self.stmt:
actions = make_list(self.stmt["Action"])
elif "NotAction" in self.stmt:
actions = make_list(self.stmt["NotAction"])
else:
self.add_finding(
"Statement contains neither Action nor NotAction",
severity.MALFORMED,
location={"string": self.stmt},
)
return False
severity.INVALID,
location={"string": self.version},
)
elif self.version != "2012-10-17":
# TODO I should have a check so that if an older version is being used,
# and a variable is detected, it should be marked as higher severity.
self.add_finding(
"Older version used. Variables will not be allowed.",
severity.LOW,
location={"string": self.version},
)
# Check Statements
if "Statement" not in self.policy_json:
self.add_finding(
"Policy does not contain a Statement element", severity.MALFORMED
)
return False
stmts_json = make_list(self.policy_json["Statement"])
for stmt_json in stmts_json:
stmt = Statement(stmt_json)
self.statements.append(stmt)
if not self.is_valid:
# Do not continue. Further checks will not work with invalid statements.
return False
# Look for bad patterns
self.check_for_bad_patterns()
return True
def analyze(self):
"""
Returns False if this policy is so broken that it couldn't be analyzed further.
On True, it may still have findings.
In either case, it will create Findings if there are any.
"""
# Check no unknown elements exist
for element in self.policy_json:
if element not in ["Version", "Statement", "Id"]:
self.add_finding(
"Policy contains an unknown element",
severity.MALFORMED,
location={"string": element},
)
return False
# Check Version
if "Version" not in self.policy_json:
self.add_finding(
"Policy does not contain a Version element", severity.MALFORMED
)
return False
self.version = self.policy_json["Version"]
if self.version not in ["2012-10-17", "2008-10-17"]:
self.add_finding(
"Unknown Version used. Version must be either 2012-10-17 or 2008-10-17",
severity.INVALID,