Esempio n. 1
0
def create_filtered_path(path, query_params):
    if scout_config.value("uri_reporting") == "path":
        return path
    filtered_params = sorted([
        (
            text_type(key).encode("utf-8"),
            # Apply text_type again to cover the None case.
            text_type(filter_element(key, value)).encode("utf-8"),
        ) for key, value in query_params
    ])
    if not filtered_params:
        return path
    return path + "?" + urlencode(filtered_params)
Esempio n. 2
0
def wrapped_urlopen(wrapped, instance, args, kwargs):
    def _extract_method(method, *args, **kwargs):
        return method

    try:
        method = _extract_method(*args, **kwargs)
    except TypeError:
        method = "Unknown"

    try:
        url = text_type(instance._absolute_url("/"))
    except Exception:
        logger.exception("Could not get URL for HTTPConnectionPool")
        url = "Unknown"

    tracked_request = TrackedRequest.instance()
    with tracked_request.span(operation="HTTP/{}".format(method)) as span:
        span.tag("url", text_type(url))
        return wrapped(*args, **kwargs)
def create_filtered_path(path, query_params):
    if scout_config.value("uri_reporting") == "path":
        return path
    # We expect query_params to have keys and values both of strings, because
    # that's how frameworks build it. However sometimes application code
    # mutates this structure to use incorrect types before we read it, so we
    # have to cautiously make everything a string again. Ignoring the
    # possibilities of bytes or objects with bad __str__ methods because they
    # seem very unlikely.
    string_query_params = ((text_type(key), text_type(value))
                           for key, value in query_params)
    # Python 2 unicode compatibility: force all keys and values to bytes
    filtered_params = sorted(((
        key.encode("utf-8"),
        (b"[FILTERED]"
         if key.lower() in FILTER_PARAMETERS else value.encode("utf-8")),
    ) for key, value in string_query_params))
    if not filtered_params:
        return path
    return path + "?" + urlencode(filtered_params)
Esempio n. 4
0
def filter_element(key, value):
    """
    Filter an individual key/value element of sensitive content. If the
    value is a dictionary, recursively filter the keys in that dictionary.

    Can be used recursively on a dict with:

        filter_element('', {"foo": "bar"})
    """
    is_sensitive = text_type(key).lower() in FILTER_PARAMETERS

    if is_sensitive:
        filtered = "[FILTERED]"
    elif isinstance(value, dict):
        # Python 2 unicode compatibility: force all keys and values to bytes
        #
        # We expect query_params to have keys and values both of strings, because
        # that's how frameworks build it. However sometimes application code
        # mutates this structure to use incorrect types, or we are filtering a
        # different collection, so we have to cautiously make everything a string
        # again. Ignoring the possibilities of bytes or objects with bad __str__
        # methods because they seem very unlikely.
        filtered = {
            text_type(k): filter_element(k, v)
            for k, v in value.items()
        }
    elif isinstance(value, list):
        filtered = [filter_element("", v) for v in value]
    elif isinstance(value, set):
        filtered = {filter_element("", v) for v in value}
    elif isinstance(value, tuple):
        filtered = tuple([filter_element("", v) for v in value])
    elif value is None:
        filtered = value
    else:
        filtered = text_type(value)

    return filtered
Esempio n. 5
0
def wrapped_urlopen(wrapped, instance, args, kwargs):
    def _extract_method(method, *args, **kwargs):
        return method

    try:
        method = _extract_method(*args, **kwargs)
    except TypeError:
        method = "Unknown"

    try:
        url = text_type(instance._absolute_url("/"))
    except Exception:
        logger.exception("Could not get URL for HTTPConnectionPool")
        url = "Unknown"

    # Don't instrument ErrorMonitor calls
    if text_type(url).startswith(scout_config.value("errors_host")):
        return wrapped(*args, **kwargs)

    tracked_request = TrackedRequest.instance()
    with tracked_request.span(operation="HTTP/{}".format(method)) as span:
        span.tag("url", text_type(url))
        return wrapped(*args, **kwargs)