Skip to content

Commit

Permalink
v2: refactoring all meta (#50)
Browse files Browse the repository at this point in the history
* unify-metas

* add_init

* AwsEc2SecurityGroup

* cloudtrail

* fix-resources

* fix-resources

* impact

* outputs

* outputs

* access-layer

* fix-html

* readme

* redame

* readme

* outputs

* fixes

* encryption

* status

* fixes

* readme

* readme

* more

* readme

* score

* more

* imgs

* docs

* readme
  • Loading branch information
gabrielsoltz authored Nov 5, 2023
1 parent bf15152 commit 28fde90
Show file tree
Hide file tree
Showing 92 changed files with 6,423 additions and 6,282 deletions.
16 changes: 8 additions & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ repos:
args:
[
"--exclude",
"lib/metachecks/checks/__init__.py",
"lib/context/resources/__init__.py",
"--in-place",
"--remove-all-unused-imports",
"--remove-unused-variable",
Expand All @@ -55,7 +55,7 @@ repos:
- id: flake8
args:
[
"--exclude=lib/metachecks/checks/__init__.py",
"--exclude=lib/context/resources/__init__.py,lib/config/configuration.py",
"--ignore=E501,W503,W605,E203",
"lib/",
]
Expand All @@ -79,12 +79,12 @@ repos:
language: system
files: '.*\.py'

- id: trufflehog
name: TruffleHog
description: Detect secrets in your data.
entry: bash -c 'docker run -v "$(pwd):/workdir" -i --rm trufflesecurity/trufflehog:latest git file:///workdir --only-verified --fail'
language: system
stages: ["commit", "push"]
# - id: trufflehog
# name: TruffleHog
# description: Detect secrets in your data.
# entry: bash -c 'docker run -v "$(pwd):/workdir" -i --rm trufflesecurity/trufflehog:latest git file:///workdir --only-verified --fail'
# language: system
# stages: ["commit", "push"]

- id: bandit
name: bandit
Expand Down
1,018 changes: 380 additions & 638 deletions README.md

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions metachecks.md → docs/context.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# MetaChecks
# Context Development

The ResourceType defines the MetaChecks to be executed. When there is an AWS Security Hub finding for an S3 Bucket (ResourceType: AwsS3Bucket), all the MetaChecks available for that resource will execute and be added as extra information under the ARNs resource.

Expand All @@ -8,7 +8,7 @@ The ResourceType defines the MetaChecks to be executed. When there is an AWS Sec

## How it works

MetaChecks works this way:
Context works this way:

1. Connect to the account where the resource lives assuming the provided role (`--mh-assume-role`)
2. Describe the resource using describe functions
Expand All @@ -30,7 +30,7 @@ If you want to add MetaChecks for a ResourceType that has not yet been defined i
from lib.AwsHelpers import get_boto3_client
from lib.metachecks.checks.Base import MetaChecksBase
from lib.metachecks.checks.MetaChecksHelpers import IamHelper
from lib.context.resources.MetaChecksHelpers import IamHelper
class Metacheck(MetaChecksBase):
Expand Down Expand Up @@ -81,7 +81,7 @@ def _get_bucket_acl(self):
from lib.AwsHelpers import get_boto3_client
from lib.metachecks.checks.Base import MetaChecksBase
from lib.metachecks.checks.MetaChecksHelpers import IamHelper
from lib.context.resources.MetaChecksHelpers import IamHelper
class Metacheck(MetaChecksBase):
Expand Down
127 changes: 67 additions & 60 deletions docs/imgs/diagram-metahub.drawio

Large diffs are not rendered by default.

Binary file added docs/imgs/diagram-metahub.drawio-v200.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/imgs/html-dashboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/imgs/html-export-small.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Binary file added docs/imgs/metahub-terminal.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 0 additions & 41 deletions lib/AwsHelpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,47 +112,6 @@ def get_account_alias(logger, aws_account_number, role_name=None, profile=None):
return aliases


def get_account_alternate_contact(
logger, aws_account_number, role_name=None, alternate_contact_type="SECURITY"
):
logger.info("Getting alternate contact for account {}".format(aws_account_number))
# https://docs.aws.amazon.com/accounts/latest/reference/using-orgs-trusted-access.html
# https://aws.amazon.com/blogs/mt/programmatically-managing-alternate-contacts-on-member-accounts-with-aws-organizations/
alternate_contact = ""
local_account = get_account_id(logger)
if aws_account_number != local_account and not role_name:
logger.warning(
"Can't get alternate contact for account {}, not --mh-assume-role provided".format(
aws_account_number
)
)
return alternate_contact
if role_name and aws_account_number:
sess = assume_role(logger, aws_account_number, role_name)
else:
sess = None
account_client = get_boto3_client(logger, "account", "us-east-1", sess)
try:
alternate_contact = account_client.get_alternate_contact(
AccountId=aws_account_number, AlternateContactType=alternate_contact_type
).get("AlternateContact")
except (NoCredentialsError, ClientError, EndpointConnectionError):
try:
alternate_contact = account_client.get_alternate_contact(
AlternateContactType=alternate_contact_type
).get("AlternateContact")
except (NoCredentialsError, ClientError, EndpointConnectionError) as e:
if e.response["Error"]["Code"] == "ResourceNotFoundException":
logger.info("No alternate contact found")
else:
logger.warning(
"Error getting alternate contact for account {}: {}".format(
aws_account_number, e
)
)
return alternate_contact


def get_boto3_client(logger, service, region, sess, profile=None):
if sess:
return sess.client(service_name=service, region_name=region)
Expand Down
67 changes: 65 additions & 2 deletions lib/config/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,73 @@
# Default filters for Security Hub findings, not implemented yet
# sh_default_filters = {"RecordState": ["ACTIVE"], "WorkflowStatus": ["NEW"]}

# MetaChecks configurations
# Impact Checks Configurations

# List of AWS accounts ids that are trusted and not considered as external. This is used in the is_principal_external MetaCheck for policies.
# List of AWS accounts ids that are trusted and not considered as external.
# This is used in check untrusted_principal for policies.
trusted_accounts = []

# Dangereous IAM actions that should be considered as a finding if used in a policy
dangereous_iam_actions = [
"iam:CreatePolicyVersion",
"iam:SetDefaultPolicyVersion",
"iam:PassRole",
"iam:CreateAccessKey",
"iam:CreateLoginProfile",
"iam:UpdateLoginProfile",
"iam:AttachUserPolicy",
"iam:AttachGroupPolicy",
"iam:AttachRolePolicy",
"iam:PutGroupPolicy",
"iam:PutRolePolicy",
"iam:PutUserPolicy",
"iam:AddUserToGroup",
"iam:UpdateAssumeRolePolicy",
]

# Days to consider a resource (key) unrotated
days_to_consider_unrotated = 90

# Environment Tags Definition
# tag_ENVIRONMENT = {"TAG-KEY": ["TAG-VALUE1", "TAG-VALUE1", "TAG-VALUE3"]}
tags_production = {
"Environment": ["Production", "production", "prd"],
"Env": ["production"],
"environment": ["prd"],
}
tags_staging = {
"Environment": ["Staging", "staging", "stg"],
"Env": ["stg"],
"environment": ["stg"],
}
tags_development = {
"Environment": ["Development", "development", "dev"],
"Env": ["dev"],
"environment": ["dev"],
}

# Severity Values for Impact Findings Scores Calculation
findings_severity_value = {
"CRITICAL": 4,
"HIGH": 3,
"MEDIUM": 1,
"LOW": 0.5,
"INFORMATIONAL": 0,
}

# Output Configurations

# Columns
# You can define the columns that will be displayed in the output HTML, CSV AND XLSX.
# You can also use `--output-config-columns` and `--output-tags-columns` to override these values.
# If you want all fields as columns, comment the following lines.
config_columns = ["public"]
tag_columns = ["Name", "Owner"]
account_columns = ["AccountAlias"]
impact_columns = ["score", "exposure", "access", "encryption", "status", "environment"]

# Decide if you want to output as part of the findings the whole json resource policy
output_resource_policy = True


path_yaml_impact = "lib/config/impact.yaml"
106 changes: 31 additions & 75 deletions lib/config/impact.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,119 +5,75 @@
# Values: List of values for this property
# - Name: Name of the value
# Score: Score for this value
# Match Criteria: List of match criteria to apply to this value
# - [MetaChecks|MetaTags|MetaAccount]: List of Meta* to apply to this value
# - Key: Value to match
# - Key: Value to match

attachment:
status:
weight: 10
values:
- attached:
score: 1
matchs:
- metachecks:
- "is_attached": True
- unattached:
- not-attached:
score: 0
matchs:
- metachecks:
- "is_attached": False

status:
weight: 5
values:
- running:
score: 1
matchs:
- metachecks:
- "is_running": True
- not-running:
score: 0
matchs:
- metachecks:
- "is_running": False
- unknown:
score: 0

network:
exposure:
weight: 1
values:
- public:
- effectively-public:
score: 1
matchs:
- metachecks:
- "is_public": True
- private:
- restricted-public:
score: 0.4
- unknown-public:
score: 0
- unrestricted-private:
score: 0.5
- restricted:
score: 0
- unknown:
score: 0
matchs:
- metachecks:
- "is_public": False

policy:
access:
weight: 1
values:
- unrestricted:
score: 1
matchs:
- metachecks:
- "is_unrestricted": True
- untrusted-principal:
score: 0.8
- unrestricted-principal:
score: 0.5
- cross-account-principal:
score: 0.5
- unrestricted-actions:
score: 0.5
- dangerous-actions:
score: 0.5
- restricted:
score: 0
matchs:
- metachecks:
- "is_unrestricted": False

key:
weight: 1
values:
- not-rotated:
score: 1
matchs:
- metachecks:
- "is_unrotated": True
- rotated:
- unknown:
score: 0
matchs:
- metachecks:
- "is_unrotated": False

encryption:
weight: 0.1
values:
- unencrypted:
score: 1
matchs:
- metachecks:
- "is_encrypted": False
- encrypted:
score: 0
matchs:
- metachecks:
- "is_encrypted": True
- unknown:
score: 0

environment:
weight: 1
values:
- production:
score: 1
matchs:
- metatags:
- "Environment": "Production"
- "Environment": "production"
- metaaccount:
- "alias": "production"
- staging:
score: 0.3
matchs:
- metatags:
- "Environment": "Staging"
- "Environment": "staging"
- metaaccount:
- "alias": "staging"
- development:
score: 0
matchs:
- metatags:
- "Environment": "Development"
- "Environment": "development"
- metaaccount:
- "alias": "development"
- unknown:
score: 0
Loading

0 comments on commit 28fde90

Please sign in to comment.