Exemplo n.º 1
0
def get_body_start(request):
    """ Get the starting index of the request body

    @param request: The target request
    @type  request: Request

    @return: The starting index; -1 if not found
    @rtype:  Int or -1 on failure

    """
    # search for the first of these patterns in the request definition
    body_start_pattern_dict = primitives.restler_static_string('{')
    body_start_pattern_array = primitives.restler_static_string('[')

    dict_index = -1
    array_index = -1

    try:
        dict_index = request.definition.index(body_start_pattern_dict)
    except Exception:
        pass

    try:
        array_index = request.definition.index(body_start_pattern_array)
    except Exception:
        pass

    if dict_index == -1 or array_index == -1:
        # If one of the indices is -1 then it wasn't found, return the other
        return max(dict_index, array_index)
    # Return the lowest index / first character found in body.
    return min(dict_index, array_index)
Exemplo n.º 2
0
    def get_fuzzing_blocks(self, config):
        """ Returns the fuzzing request blocks per the config

        @return: The list of request blocks
        @rtype : List[str]

        """
        # default value
        default_value = config.get_default_value(
            self.tag, primitives.FUZZABLE_BOOL
        )
        default_value = str(default_value).lower()

        if not self.is_fuzzable():
            return [primitives.restler_static_string(default_value)]

        if not config.merge_fuzzable_values:
            return [primitives.restler_fuzzable_bool(default_value)]

        # get the set of fuzzable variables
        fuzzable_values_raw = config.get_fuzzable_values(
            self.tag, primitives.FUZZABLE_BOOL
        )

        fuzzable_values = [
            str(value) for value in fuzzable_values_raw
        ]

        # merge default + fuzzable values
        fuzzable_group = config.cleanup_fuzzable_group(
            default_value, fuzzable_values
        )
        return [(primitives.FUZZABLE_GROUP, fuzzable_group)]
Exemplo n.º 3
0
    def set_id_values_for_create_once_dynamic_objects(self,
                                                      dynamic_object_values,
                                                      rendered_sequence):
        """ Sets the ID values for specified dynamic object values in the request definition.
        The function iterates through the definition and replaces the variable
        names specified in the @param dynamic_object_values dictionary with
        the values associated with them. That variable is then removed as a consumer
        for this request because that variable will now be replaced with what can
        be thought of as a static_string (not dynamic).

        @param dynamic_object_values: Dictionary of dynamic object names and values
        @type  dynamic_object_values: Dict
        @param rendered_sequence: The rendered create-once sequence that was sent to create the dynamic objects
        @type  rendered_sequence: RenderedSequence

        @return: None
        @rtype : None

        """
        for i, line in enumerate(self.definition):
            var_name = self._get_var_name_from_definition_line(line)
            if var_name and var_name in dynamic_object_values:
                self._definition[i] =\
                    primitives.restler_static_string(dynamic_object_values[var_name])
                # Remove the variable from consumers, because the reader has
                # been removed from the definition.
                if var_name in self._consumes:
                    self._consumes.remove(var_name)
        self._create_once_requests += rendered_sequence.sequence.sent_request_data_list
Exemplo n.º 4
0
    def fuzz_body_blocks(self, config) -> list:
        """ Fuzz the value of interpreted body blocks

        @param config: PayloadBodyChecker specific configuration data (can be None)
        @type  config: Dict

        @return: The fuzzed request blocks
        @rtype : List[str]

        """
        # Set the config
        self._config = FuzzingConfig(config)
        # Get the fuzzing blocks
        blocks = self._schema.get_fuzzing_blocks(self._config)

        if self._config.fuzz_strategy == 'restler':
            return [blocks]

        acc = ''
        sets = []

        for block in blocks:
            primitive_type = block[0]
            value = block[1]
            if len(block) > 2:
                quoted = block[2]

            # accumulate
            if primitive_type == primitives.STATIC_STRING:
                if quoted:
                    value = f'"{value}"'
                acc += str(value)

            # fuzzable values
            elif primitive_type == primitives.FUZZABLE_GROUP:
                choices = [f'{acc}{choice}' for choice in value]
                sets.append(choices)
                acc = ''

            # not supported yet
            else:
                logger.raw_network_logging(f'Cannot fuzz type {primitive_type}')
                return blocks

        # tailing static string
        sets.append([acc])

        import engine.fuzzing_parameters.fuzzing_utils as fuzzing_utils
        # compose
        if self._config.fuzz_strategy == 'EX':
            pool = fuzzing_utils.get_product_exhaust(sets, self._config.max_combination)
        elif self._config.fuzz_strategy == 'D1':
            pool = fuzzing_utils.get_product_linear_fair(sets, self._config.max_combination)
        else:
            pool = fuzzing_utils.get_product_linear_bias(sets, self._config.max_combination)

        strs = [''.join(p) for p in pool]
        outs = [[primitives.restler_static_string(string)] for string in strs]
        return outs
Exemplo n.º 5
0
    def _send_each_example(self, request):
        """ Substitutes each example into the request and sends it
        """
        def _send_request(request_to_send):
            self._log(
                "Sending example request: \n"
                f"{request_to_send.definition}",
                print_to_network_log=False)
            seq = self._sequence + Sequence(request_to_send)
            response, _ = self._render_and_send_data(seq, request_to_send)

            code = response.status_code
            self._log(f"Status Code: {code}", print_to_network_log=False)
            if code not in status_codes:
                status_codes[code] = 0
            status_codes[code] += 1

            # Check to make sure a bug wasn't uncovered while executing the sequence
            if response and response.has_bug_code():
                self._print_suspect_sequence(seq, response)
                BugBuckets.Instance().update_bug_buckets(
                    seq,
                    code,
                    origin=self.__class__.__name__,
                    hash_full_request=True)

        status_codes = {}

        # Send new request for each body example
        for example in request.examples.body_examples:
            blocks = example.get_blocks()
            new_request = substitute_body(request, blocks)
            if new_request:
                _send_request(new_request)
            else:
                self._log(
                    f"Failed to substitute body for request {request.endpoint}."
                )
        # Send new request for each query example.
        # For now don't try to match these up with body examples.
        # There will soon be IDs associated with the examples, so they can be matched.
        for example in request.examples.query_examples:
            q_blocks = []
            for idx, query in enumerate(example.queries):
                q_blocks += query.get_blocks()
                if idx < len(example) - 1:
                    # Add the query separator
                    q_blocks.append(primitives.restler_static_string('&'))
            new_request = substitute_query(request, q_blocks)
            if new_request:
                _send_request(new_request)
            else:
                self._log('Failed to substitute query')

        self._log("Results:")
        for code in status_codes:
            self._log(f"{code}: {status_codes[code]}")
        self._log("\n", print_to_network_log=False)
Exemplo n.º 6
0
    def get_fuzzing_blocks(self, config):
        """ Returns the fuzzing request blocks of this member

        @return: The list of request blocks
        @rtype : List[str]

        """
        return [primitives.restler_static_string(f'"{self._name}":')] +\
               self._value.get_fuzzing_blocks(config)
Exemplo n.º 7
0
    def get_blocks(self):
        """ Gets the request blocks for the Query Parameter.

        @return: Request blocks representing the format: key=ParamObject
        @rtype : List[str]

        """
        key = primitives.restler_static_string(f'{self._key}=')
        return [key] + self._content.get_blocks(FuzzingConfig())
Exemplo n.º 8
0
    def get_blocks(self, config=None):
        """ Gets request blocks for the Member Parameters.

        @return: Request blocks representing the format: "key":value
        @rtype : List[str]

        """
        return [primitives.restler_static_string(f'"{self._name}":')] +\
               self._value.get_blocks(config)
Exemplo n.º 9
0
    def get_blocks(self, config=None):
        """ Gets the request blocks for this value param.

        @return: A request block containing the value of the param
        @rtype : List[str]

        """
        if self._custom:
            return[primitives.restler_custom_payload(self._content)]
        return [primitives.restler_static_string(self._content)]
Exemplo n.º 10
0
    def get_blocks(self, config=None):
        """ Gets request blocks for the String Parameters.

        @return: A request block containing the string
        @rtype : List[str]

        """
        if self._is_custom:
            return [primitives.restler_custom_payload(self._content, quoted=True)]
        return [primitives.restler_static_string(self._content, quoted=True)]
Exemplo n.º 11
0
    def get_blocks(self, config=None):
        """ Gets request blocks for Object Leaf Parameters

        @return: Request block
        @rtype : List[str]

        """
        formalized_content = self._content.replace("'", '"')
        formalized_content = formalized_content.replace('u"', '"')

        return [primitives.restler_static_string(formalized_content)]
Exemplo n.º 12
0
    def _get_blocks(self, values_blocks):
        """ Returns list of request blocks associated with this array

        @param values_blocks: The array's values' blocks retrieved during
                               traversal of this array

        @return: The list of request blocks associated with this array
        @rtype : List[str]

        """
        blocks = []

        blocks.append(primitives.restler_static_string('['))

        for idx, value_blocks in enumerate(values_blocks):
            blocks += value_blocks

            if idx != (len(values_blocks) - 1):
                blocks.append(primitives.restler_static_string(','))

        blocks.append(primitives.restler_static_string(']'))
        return blocks
Exemplo n.º 13
0
    def _get_blocks(self, members_blocks: list) -> list:
        """ Returns list of request blocks associated with this object

        @param members_blocks: The object's members' blocks retrieved during
                               traversal of this object

        @return: The list of request blocks associated with this object
        @rtype : List[str]

        """
        blocks = []

        blocks.append(primitives.restler_static_string('{'))

        for idx, member_blocks in enumerate(members_blocks):
            blocks += member_blocks

            if idx != (len(members_blocks) - 1):
                blocks.append(primitives.restler_static_string(','))

        blocks.append(primitives.restler_static_string('}'))
        return blocks
Exemplo n.º 14
0
    def get_fuzzing_blocks(self, config):
        """ Returns the fuzzing request blocks per the config

        @return: The list of request blocks
        @rtype : List[str]

        """

        # helper function to sanitize raw object string
        def formalize_object_value(raw_object):
            object_str = str(raw_object)
            object_tmp = object_str.replace("'", '"')
            object_tmp = object_tmp.replace('u"', '"')
            try:
                test_object = json.loads(object_tmp)
                if str(test_object) == raw_object:
                    return object_tmp
            except Exception:
                return '{ "fuzz" : false }'

            return object_str

        # default value
        default_value = config.get_default_value(self.tag,
                                                 primitives.FUZZABLE_OBJECT)
        default_value = formalize_object_value(default_value)

        # not fuzzalbe --> constant
        if not self.is_fuzzable():
            return [primitives.restler_static_string(default_value)]

        # fuzz as normal fuzzable object using wordbook
        if not config.merge_fuzzable_values:
            return [primitives.restler_fuzzable_object(default_value)]

        # get the set of fuzzable values
        fuzzable_values_raw = config.get_fuzzable_values(
            self.tag, primitives.FUZZABLE_OBJECT)

        fuzzable_values = [
            formalize_object_value(value) for value in fuzzable_values_raw
        ]

        # merge default + fuzzable values
        fuzzable_group = config.cleanup_fuzzable_group(default_value,
                                                       fuzzable_values)
        return [
            primitives.restler_fuzzable_group(FUZZABLE_GROUP_TAG,
                                              fuzzable_group)
        ]
Exemplo n.º 15
0
    def update_host(self):
        """ Updates the Host field for every request with the one specified in Settings

        @return: None
        @rtype : None

        """
        new_host_line = primitives.restler_static_string(f"{request_utilities.HOST_PREFIX}{Settings().host}\r\n")
        host_idx = self.get_host_index()
        if host_idx >= 0:
            self._definition[host_idx] = new_host_line
        else:
            # Host not in grammar, add it
            header_idx = self.header_start_index()
            if header_idx < 0:
                raise InvalidGrammarException
            self._definition.insert(header_idx, new_host_line)
Exemplo n.º 16
0
def get_body_start(request):
    """ Get the starting index of the request body

    @param request: The target request
    @type  request: Request

    @return: The starting index; -1 if not found
    @rtype:  Int or -1 on failure

    """
    # search for this pattern in the request definition
    body_start_pattern = primitives.restler_static_string('{')

    try:
        body_start_index = request.definition.index(body_start_pattern)
        return body_start_index
    except Exception:
        return -1
Exemplo n.º 17
0
def get_query_start_end(request):
    """ Get the start and end index of a request's query

    @param request: The target request
    @type  request: Request

    @return: A tuple containing the start and end index of the query
    @rtype : Tuple(int, int) or (-1, -1) on failure

    """
    query_start_pattern = primitives.restler_static_string('?')
    query_end_str = ' HTTP'
    try:
        query_start_index = request.definition.index(query_start_pattern) + 1
        for idx, line in enumerate(request.definition[query_start_index + 1:]):
            if line[1].startswith(query_end_str):
                query_end_index = query_start_index + idx + 1
                return query_start_index, query_end_index
        else:
            return -1, -1
    except:
        return -1, -1
Exemplo n.º 18
0
            "Exception parsing response, data was not valid json: {}".format(
                error))

    try:
        temp_123 = str(data["name"])
    except Exception as error:
        pass

    if temp_123:
        dependencies.set_variable("_group_put_name", temp_123)


req_collection = requests.RequestCollection([])

request = requests.Request([
    primitives.restler_static_string("GET "),
    primitives.restler_static_string("/"),
    primitives.restler_static_string(" HTTP/1.1\r\n"),
    primitives.restler_static_string("Accept: application/json\r\n"),
    primitives.restler_static_string("Host: restler.unit.test.server.com\r\n"),
    primitives.restler_static_string("Content-Type: application/json\r\n"),
    primitives.restler_refreshable_authentication_token(
        "authentication_token_tag"),
    primitives.restler_static_string("\r\n")
],
                           requestId="/")
req_collection.add_request(request)

request = requests.Request([
    primitives.restler_static_string("GET "),
    primitives.restler_static_string("/"),
Exemplo n.º 19
0
            "Exception parsing response, data was not valid json: {}".format(
                error))

    try:
        temp_123 = str(data["name"])
    except Exception as error:
        pass

    if temp_123:
        dependencies.set_variable("_city_house_put_name", temp_123)


req_collection = requests.RequestCollection([])

request = requests.Request([
    primitives.restler_static_string("GET "),
    primitives.restler_static_string("/"),
    primitives.restler_static_string("city"),
    primitives.restler_static_string(" HTTP/1.1\r\n"),
    primitives.restler_static_string("Accept: application/json\r\n"),
    primitives.restler_static_string("Host: restler.unit.test.server.com\r\n"),
    primitives.restler_static_string("Content-Type: application/json\r\n"),
    primitives.restler_refreshable_authentication_token(
        "authentication_token_tag"),
    primitives.restler_static_string("\r\n")
],
                           requestId="/city")
req_collection.add_request(request)

request = requests.Request([
    primitives.restler_static_string("PUT "),
        # This is not an error, since some properties are not always returned
        pass


    # If no dynamic objects were extracted, throw.
    if not (temp_7262):
        raise ResponseParsingException("Error: all of the expected dynamic objects were not present in the response.")

    # Set dynamic variables
    if temp_7262:
        dependencies.set_variable("_stores_post_id", temp_7262)

req_collection = requests.RequestCollection([])
# Endpoint: /stores, method: Post
request = requests.Request([
    primitives.restler_static_string("POST "),
    primitives.restler_static_string("/"),
    primitives.restler_static_string("api"),
    primitives.restler_static_string("/"),
    primitives.restler_static_string("stores"),
    primitives.restler_static_string(" HTTP/1.1\r\n"),
    primitives.restler_static_string("Accept: application/json\r\n"),
    primitives.restler_static_string("Host: localhost:8888\r\n"),
    primitives.restler_static_string("\r\n"),
    
    {
        'post_send':
        {
            'parser': parse_storespost,
            'dependencies':
            [
Exemplo n.º 21
0
    def get_fuzzing_blocks(self, config):
        """ Returns the fuzzing request blocks per the config

        @return: The list of request blocks
        @rtype : List[str]

        """
        # default value
        default_value = config.get_default_value(
            self.tag, primitives.FUZZABLE_STRING, self._content
        )

        def not_like_string(val):
            """ Tests if a value seems to be some type other
            than a string (i.e. array, dict, bool, int) """

            if not val or not isinstance(val, str):
                return True

            if val[0] == '[' and val[-1] == ']':
                return True
            if val[0] == '{' and val[-1] == '}':
                return True
            if val.lower() == 'true' or val.lower() == 'false':
                return True

            try:
                v = int(val)
                return True
            except Exception:
                pass

            return False

        if self.is_unknown and not_like_string(default_value):
            # Try to get a new default value without a hint
            default_value = config.get_default_value(
                self.tag, primitives.FUZZABLE_STRING, hint=None
            )
            if not_like_string(default_value):
                return [primitives.restler_static_string(default_value, quoted=False)]

        if not self.is_fuzzable():
            return [primitives.restler_static_string(default_value, quoted=True)]

        # fuzz as normal fuzzable string
        if not config.merge_fuzzable_values:
            blocks = []
            blocks.append(primitives.restler_fuzzable_string(default_value), quoted=True)
            return blocks

        # get the set of fuzzable values
        fuzzable_values_raw = config.get_fuzzable_values(
            self.tag, primitives.FUZZABLE_STRING
        )

        fuzzable_values = [
            f'"{value}"' for value in fuzzable_values_raw
        ]

        # merge default + fuzzable values
        fuzzable_group = config.cleanup_fuzzable_group(
            f'"{default_value}"', fuzzable_values
        )
        return [(primitives.FUZZABLE_GROUP, fuzzable_group)]
    # If no dynamic objects were extracted, throw.
    if not (temp_7262):
        raise ResponseParsingException(
            "Error: all of the expected dynamic objects were not present in the response."
        )

    # Set dynamic variables
    if temp_7262:
        dependencies.set_variable("_stores__storeId__order_post_id", temp_7262)


req_collection = requests.RequestCollection([])
# Endpoint: /stores, method: Get
request = requests.Request([
    primitives.restler_static_string("GET "),
    primitives.restler_static_string("/"),
    primitives.restler_static_string("api"),
    primitives.restler_static_string("/"),
    primitives.restler_static_string("stores"),
    primitives.restler_static_string(" HTTP/1.1\r\n"),
    primitives.restler_static_string("Accept: application/json\r\n"),
    primitives.restler_static_string("Host: localhost:8888\r\n"),
    primitives.restler_refreshable_authentication_token(
        "authentication_token_tag"),
    primitives.restler_static_string("\r\n"),
],
                           requestId="/stores")
req_collection.add_request(request)

# Endpoint: /stores/{storeId}/order, method: Post
        raise ResponseParsingException(
            "Exception parsing response, data was not valid json: {}".format(
                error))

    try:
        temp_123 = str(data["name"])
    except Exception as error:
        pass

    if temp_123:
        dependencies.set_variable("_namespaceruletest_put_name", temp_123)


req_collection = requests.RequestCollection([])
request = requests.Request([
    primitives.restler_static_string("GET "),
    primitives.restler_static_string("/"),
    primitives.restler_static_string("city"),
    primitives.restler_static_string(" HTTP/1.1\r\n"),
    primitives.restler_refreshable_authentication_token(
        "authentication_token_tag"),
    primitives.restler_static_string("\r\n")
],
                           requestId="/city")
req_collection.add_request(request)

request = requests.Request([
    primitives.restler_static_string("PUT "),
    primitives.restler_static_string("/"),
    primitives.restler_static_string("city"),
    primitives.restler_static_string("/"),