404

[ Avaa Bypassed ]




Upload:

Command:

botdev@18.218.25.144: ~ $
"""
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: MIT-0
"""
import copy
from functools import reduce  # pylint: disable=redefined-builtin

import regex as re

from cfnlint.rules import CloudFormationLintRule, RuleMatch


class SubNeeded(CloudFormationLintRule):
    """Check if a substitution string exists without a substitution function"""

    id = "E1029"
    shortdesc = "Sub is required if a variable is used in a string"
    description = "If a substitution variable exists in a string but isn't wrapped with the Fn::Sub function the deployment will fail."
    source_url = "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html"
    tags = ["functions", "sub"]

    exceptions = ["TemplateBody"]

    def __init__(self):
        """Init"""
        super().__init__()
        self.config_definition = {"custom_excludes": {"default": "", "type": "string"}}
        self.configure()
        self.subParameterRegex = re.compile(r"(\$\{[A-Za-z0-9_:\.]+\})")

    def _match_values(self, cfnelem, path):
        """Recursively search for values matching the searchRegex"""
        values = []
        if isinstance(cfnelem, dict):
            for key in cfnelem:
                pathprop = path[:]
                pathprop.append(key)
                values.extend(self._match_values(cfnelem[key], pathprop))
        elif isinstance(cfnelem, list):
            for index, item in enumerate(cfnelem):
                pathprop = path[:]
                pathprop.append(index)
                values.extend(self._match_values(item, pathprop))
        else:
            # Leaf node
            if isinstance(cfnelem, str):  # and re.match(searchRegex, cfnelem):
                for variable in re.findall(self.subParameterRegex, cfnelem):
                    values.append(path + [variable])

        return values

    def match_values(self, cfn):
        """
        Search for values in all parts of the templates that match the searchRegex
        """
        results = []
        results.extend(self._match_values(cfn.template, []))
        # Globals are removed during a transform.  They need to be checked manually
        results.extend(self._match_values(cfn.template.get("Globals", {}), []))
        return results

    def _api_exceptions(self, value):
        """Key value exceptions"""
        parameter_search = re.compile(r"^\$\{stageVariables\..*\}$")
        return re.match(parameter_search, value)

    def _variable_custom_excluded(self, value):
        """User-defined exceptions for variables, anywhere in the file"""
        custom_excludes = self.config["custom_excludes"]
        if custom_excludes:
            custom_search = re.compile(custom_excludes)
            return re.match(custom_search, value)
        return False

    def match(self, cfn):
        matches = []

        refs = cfn.get_valid_refs()
        getatts = cfn.get_valid_getatts()

        # Get a list of paths to every leaf node string containing at least one ${parameter}
        parameter_string_paths = self.match_values(cfn)
        # We want to search all of the paths to check if each one contains an 'Fn::Sub'
        for parameter_string_path in parameter_string_paths:
            # Get variable
            var = parameter_string_path[-1]

            # Step Function State Machine has a Definition Substitution that allows usage of special variables outside of a !Sub
            # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-stepfunctions-statemachine-definitionsubstitutions.html

            if "DefinitionString" in parameter_string_path:
                modified_parameter_string_path = copy.copy(parameter_string_path)
                index = parameter_string_path.index("DefinitionString")
                modified_parameter_string_path[index] = "DefinitionSubstitutions"
                modified_parameter_string_path = modified_parameter_string_path[
                    : index + 1
                ]
                modified_parameter_string_path.append(var[2:-1])
                if reduce(
                    lambda c, k: c.get(k, {}),
                    modified_parameter_string_path,
                    cfn.template,
                ):
                    continue

            # Exclude variables that match custom exclude filters, if configured
            # (for third-party tools that pre-process templates before uploading them to AWS)
            if self._variable_custom_excluded(var):
                continue

            # Exclude literals (https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html)
            if var.startswith("${!"):
                continue

            var_stripped = var[2:-1].strip()

            # If we didn't find an 'Fn::Sub' it means a string containing a ${parameter} may not be evaluated correctly
            if (
                not "Fn::Sub" in parameter_string_path
                and parameter_string_path[-2] not in self.exceptions
            ):
                if (
                    var_stripped in refs or var_stripped in getatts
                ) or "DefinitionString" in parameter_string_path:
                    # Remove the last item (the variable) to prevent multiple errors on 1 line errors
                    path = parameter_string_path[:-1]
                    message = f'Found an embedded parameter "{var}" outside of an "Fn::Sub" at {"/".join(map(str, path))}'
                    matches.append(RuleMatch(path, message))

        return matches

Filemanager

Name Type Size Permission Actions
__pycache__ Folder 0755
Base64.py File 1.72 KB 0644
Cidr.py File 11.94 KB 0644
DynamicReferenceSecureString.py File 5.72 KB 0644
FindInMap.py File 11.25 KB 0644
FindInMapKeys.py File 3.89 KB 0644
GetAtt.py File 6.05 KB 0644
GetAz.py File 2.76 KB 0644
If.py File 1.45 KB 0644
ImportValue.py File 2.45 KB 0644
Join.py File 8.63 KB 0644
Length.py File 3.31 KB 0644
Not.py File 978 B 0644
Ref.py File 1.02 KB 0644
RefExist.py File 1.26 KB 0644
RefInCondition.py File 1.36 KB 0644
RelationshipConditions.py File 5.35 KB 0644
Select.py File 4.41 KB 0644
Split.py File 3.11 KB 0644
Sub.py File 9.49 KB 0644
SubNeeded.py File 5.48 KB 0644
SubNotJoin.py File 2 KB 0644
SubParametersUsed.py File 1.4 KB 0644
SubUnneeded.py File 1.27 KB 0644
ToJsonString.py File 1.75 KB 0644
__init__.py File 106 B 0644