rastray 0.15.0

Blazing-fast static analysis CLI for security, dependency, and performance audits.
# RSTR-PTH-001 — Flask `send_file(request.*)`

## Summary

A Flask handler calls `send_file` (or `send_from_directory` with the
path on the wrong argument) using a path derived directly from
request input. An attacker submits `../../etc/passwd` and the server
happily reads and returns that file.

## Severity

`High`.

## Languages

Python (Flask / Quart).

## What rastray flags

```python
@app.route('/download')
def download():
    return send_file(request.args['path'])         # ← flagged
```

```python
@app.route('/file')
def file():
    return send_file(f'./uploads/{request.args["name"]}')   # ← flagged
```

## What rastray deliberately does *not* flag

- `send_from_directory(safe_dir, secure_filename(name))` (the
  documented safe form).
- `send_file(...)` with a constant path.

## How to fix it

Use `send_from_directory` with `werkzeug.utils.secure_filename`:

```python
from flask import send_from_directory
from werkzeug.utils import secure_filename

@app.route('/file/<name>')
def file(name):
    return send_from_directory(
        directory='./uploads',
        path=secure_filename(name),
    )
```

For multi-tenant uploads, also confirm the resolved path stays inside
the intended base directory:

```python
import os
base = os.path.realpath('./uploads')
target = os.path.realpath(os.path.join(base, secure_filename(name)))
if not target.startswith(base + os.sep):
    abort(404)
```

`secure_filename` only strips path separators and a handful of unsafe
chars — the `realpath` check catches symlink shenanigans.

## References

- [Flask: send_file / send_from_directory]https://flask.palletsprojects.com/en/stable/api/#flask.send_from_directory
- [OWASP Path Traversal Cheat Sheet]https://owasp.org/www-community/attacks/Path_Traversal
- [CWE-22]https://cwe.mitre.org/data/definitions/22.html