rastray 0.15.0

Blazing-fast static analysis CLI for security, dependency, and performance audits.
# RSTR-RDR-002 — Flask / Django redirect with request input

## Summary

A Python web handler redirects the browser to a URL taken directly
from request arguments. An attacker can craft a link such as
`https://yoursite/login?next=https://phish.example` — the victim sees
a trusted-looking link, clicks, and lands on the attacker's page after
the redirect.

## Severity

`Medium`. Open-redirects amplify phishing and frequently chain into
OAuth-flow takeovers when the redirect target receives a token.

## Languages

Python (Flask, Django).

## What rastray flags

```python
@app.route('/post-login')
def post_login():
    return redirect(request.args['next'])           # ← flagged
```

```python
def view(request):
    return HttpResponseRedirect(request.GET['next'])  # ← flagged
```

## What rastray deliberately does *not* flag

- `redirect(url_for('some_view'))` (named URLs).
- Redirects to literal strings.
- Redirects passed through `urlsafe_allowed_hosts(...)` or any helper
  that the rule cannot resolve.

## How to fix it

Validate the redirect target against an allow-list (relative paths or
trusted hosts):

```python
from urllib.parse import urlparse

ALLOWED_HOSTS = {'app.example.com', 'admin.example.com'}

def safe_redirect_target(raw: str) -> str:
    parsed = urlparse(raw)
    if not parsed.netloc:
        return raw                       # relative path — safe
    if parsed.netloc in ALLOWED_HOSTS:
        return raw                       # trusted external host
    return '/'                           # fall back to home

@app.route('/post-login')
def post_login():
    return redirect(safe_redirect_target(request.args.get('next', '/')))
```

Django ships an equivalent helper out of the box —
`django.utils.http.url_has_allowed_host_and_scheme` — use it on every
`next=` parameter.

## References

- [Django `url_has_allowed_host_and_scheme`]https://docs.djangoproject.com/en/stable/ref/utils/#django.utils.http.url_has_allowed_host_and_scheme
- [OWASP Unvalidated Redirects and Forwards Cheat Sheet]https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html
- [CWE-601]https://cwe.mitre.org/data/definitions/601.html