Exemple #1
0
def get_expanded_policy(policy):
    """
    Given a policy, expand the * Actions in IAM policy files to improve readability

    :param policy: dictionary containing valid AWS IAM Policy
    :return:
    """
    modified_policy = copy.deepcopy(policy)

    if isinstance(modified_policy["Statement"], dict):
        requested_actions = get_actions_from_statement(
            modified_policy["Statement"])
        expanded_actions = determine_actions_to_expand(requested_actions)
        if "NotAction" in modified_policy["Statement"]:
            if isinstance(modified_policy["Statement"]["NotAction"], list):
                modified_policy["Statement"]["NotAction"].clear()
                modified_policy["Statement"]["NotAction"].extend(
                    expanded_actions)
            elif isinstance(modified_policy["Statement"]["NotAction"], str):
                modified_policy["Statement"]["NotAction"] = []
            logger.warning(
                "NotAction is in the statement. Policy Sentry will expand any wildcard actions "
                "that are in the NotAction list, but it will not factor the NotAction actions into any analysis about "
                "whether or not the actions are allowed by the policy. "
                "If you are concerned about this, please review this specific policy manually."
            )
        elif "Action" in modified_policy["Statement"]:
            if isinstance(modified_policy["Statement"]["Action"], list):
                modified_policy["Statement"]["Action"].clear()
                modified_policy["Statement"]["Action"].extend(expanded_actions)
            elif isinstance(modified_policy["Statement"]["Action"], str):
                modified_policy["Statement"]["Action"] = []
    # Otherwise it will be a list of Sids
    elif isinstance(modified_policy["Statement"], list):
        for statement in modified_policy["Statement"]:
            requested_actions = get_actions_from_statement(statement)
            expanded_actions = determine_actions_to_expand(requested_actions)
            if "NotAction" in statement:
                if isinstance(statement["NotAction"], list):
                    statement["NotAction"].clear()
                    statement["NotAction"].extend(expanded_actions)
                elif isinstance(statement["NotAction"], str):
                    statement["NotAction"] = []
                logger.warning(
                    "NotAction is in the statement. Policy Sentry will expand any wildcard actions "
                    "that are in the NotAction list, but it will not factor the NotAction actions into any analysis "
                    "about whether or not the actions are allowed by the policy."
                    "If you are concerned about this, please review this specific policy manually."
                )
            elif "Action" in statement:
                if isinstance(statement["Action"], list):
                    statement["Action"].clear()
                elif isinstance(statement["Action"], str):
                    statement["Action"] = []
                statement["Action"].extend(expanded_actions)
    else:
        logger.critical(
            "Unknown error: The 'Statement' is neither a dict nor a list")
    return modified_policy
Exemple #2
0
def analyze_statement_by_access_level(statement_json, access_level):
    """
    Determine if a statement has any actions with a given access level.

    :param statement_json: a dictionary representing a statement from an AWS JSON policy
    :param access_level: The access level - either 'Read', 'List', 'Write', 'Tagging', or 'Permissions management'
    """
    requested_actions = get_actions_from_statement(statement_json)
    expanded_actions = determine_actions_to_expand(requested_actions)
    actions_by_level = remove_actions_not_matching_access_level(
        expanded_actions, access_level
    )
    return actions_by_level
Exemple #3
0
def analyze_statement_by_access_level(db_session, statement_json,
                                      access_level):
    """
    Determine if a statement has any actions with a given access level.

    :param db_session: SQLAlchemy database session
    :param statement_json: a dictionary representing a statement from an AWS JSON policy
    :param access_level: The normalized access level - either 'read', 'list', 'write', 'tagging', or 'permissions-management'
    """
    requested_actions = get_actions_from_statement(statement_json)
    expanded_actions = determine_actions_to_expand(db_session,
                                                   requested_actions)
    actions_by_level = remove_actions_not_matching_access_level(
        db_session, expanded_actions, access_level)
    return actions_by_level