Esempio n. 1
0
def redact(interaction, cassette):
    """Remove sensitive or environment-specific information from cassettes before they are saved.

    Parameters
    ----------
    interaction
    cassette

    Returns
    -------

    """

    url = interaction.data['request']['uri']
    host = urlsplit(url).netloc
    if Placeholder(placeholder='hostname.com',
                   replace=host) not in cassette.placeholders:
        cassette.placeholders.append(
            Placeholder(placeholder='hostname.com', replace=host))

    # Server name in Origin header may differ from hostname that was sent the request.
    for origin in interaction.data['response']['headers'].get('Origin', []):
        host = urlsplit(origin).netloc
        if host != '' and Placeholder(
                placeholder='hostname.com',
                replace=host) not in cassette.placeholders:
            cassette.placeholders.append(
                Placeholder(placeholder='hostname.com', replace=host))

    def add_placeholder(pattern, string, placeholder, group):
        if isinstance(string, bytes):
            pattern = pattern.encode('utf-8')
            # placeholder = placeholder.encode('utf-8')

        match = re.search(pattern, string)
        if match:
            # old_text = match.group(group).encode('utf-8') if isinstance(string, bytes) else match.group(group)
            old_text = match.group(group)
            cassette.placeholders.append(
                Placeholder(placeholder=placeholder, replace=old_text))

    add_placeholder(r"(?<=&password=)([^&]*)\b",
                    interaction.data['request']['body']['string'], '*****', 1)
    add_placeholder('(?<=access_token":")[^"]*',
                    interaction.data['response']['body']['string'],
                    '[redacted]', 0)

    for index, header in enumerate(interaction.data['request']['headers'].get(
            'Authorization', [])):
        # Betamax tries to replace Placeholders on all headers.  Mixed str/bytes headers will cause Betamax to break.
        if isinstance(header, bytes):
            header = header.decode('utf-8')
            interaction.data['request']['headers']['Authorization'][
                index] = header
        add_placeholder(r'(?<=Basic ).*', header, '[redacted]', 0)  # swat
        add_placeholder(r'(?<=Bearer ).*', header, '[redacted]', 0)  # sasctl
Esempio n. 2
0
    def add_placeholder(pattern, string, placeholder, group):
        if isinstance(string, bytes):
            pattern = pattern.encode('utf-8')

        match = re.search(pattern, string)
        if match:
            old_text = match.group(group)
            cassette.placeholders.append(
                Placeholder(placeholder=placeholder, replace=old_text))
Esempio n. 3
0
def scrub(interaction, current_cassette):
    request = interaction.data.get('request') or {}
    response = interaction.data.get('response') or {}

    # Exit early if the request did not return 200 OK because that's the
    # only time we want to look for tokens
    if not response or response['status']['code'] != 200:
        return

    for what in [r for r in [request, response] if r]:
        auths = what['headers'].get('Authorization') or []
        for auth in auths:
            current_cassette.placeholders.append(
                Placeholder(placeholder='**********', replace=auth))

        body_string = what['body']['string']
        try:
            dikt = json.loads(body_string)
        except:
            dikt = {k: v[0] for k, v in parse_qs(body_string).items()}
        for token in ['access_token', 'refresh_token']:
            if token in dikt:
                current_cassette.placeholders.append(
                    Placeholder(placeholder='**********', replace=dikt[token]))
Esempio n. 4
0
def sanitize_cookies(interaction, cassette):
    response = interaction.as_response()
    response_cookies = response.cookies
    request_cookies = dict()
    for cookie in (interaction.as_response().request.headers.get('Cookie') or '').split('; '):
        name, sep, val = cookie.partition('=')
        if sep:
            request_cookies[name] = val

    secret_values = set()
    for name in CLASSIFIED_COOKIES:
        potential_val = response_cookies.get(name)
        if potential_val:
            secret_values.add(potential_val)

        potential_val = request_cookies.get(name)
        if potential_val:
            secret_values.add(potential_val)

    for val in secret_values:
        cassette.placeholders.append(
            Placeholder(placeholder='<AUTH COOKIE>', replace=val)
        )
Esempio n. 5
0
def sanitize_cookies(interaction, cassette):
    response = interaction.as_response()
    response_cookies = response.cookies
    request_body = response.request.body or ''  # where secret values hide
    # the or '' is necessary above because sometimes response.request.body
    # is empty bytes, and that makes the later code complain.

    secret_values = set()
    for name in CLASSIFIED_COOKIES:
        potential_val = response_cookies.get(name)
        if potential_val:
            secret_values.add(potential_val)

        named_parameter_str = '&{}='.format(name)
        if (named_parameter_str in request_body
                or request_body.startswith(named_parameter_str[1:])):
            i = request_body.index(name) + len(name) + 1  # +1 for the = sign
            val = request_body[i:].split(',')[
                0]  # after the comma is another cookie
            secret_values.add(val)

    for val in secret_values:
        cassette.placeholders.append(
            Placeholder(placeholder='<AUTH COOKIE>', replace=val))
Esempio n. 6
0
def _sanitize_betamax_cookies(interaction, cassette):
    # TODO handle also request body occurence of __RequestVerificationToken
    response = interaction.as_response()
    response_cookies = response.cookies
    request_cookies = dict()
    for cookie in (interaction.as_response().request.headers.get("Cookie")
                   or "").split("; "):
        name, sep, val = cookie.partition("=")
        if sep:
            request_cookies[name] = val

    secret_values = set()
    for name in CLASSIFIED_COOKIES:
        potential_val = response_cookies.get(name)
        if potential_val:
            secret_values.add(potential_val)

        potential_val = request_cookies.get(name)
        if potential_val:
            secret_values.add(potential_val)

    for val in secret_values:
        cassette.placeholders.append(
            Placeholder(placeholder="<AUTH COOKIE>", replace=val))