# SQL Injection via f-string in psycopg2 execute()

Language: Python
Severity: Critical
CWE: CWE-89

## Source
4

## Flow
4-6-7

## Sink
7

## Vulnerable Code
```python
import psycopg2

def fetch_iot_device_telemetry(device_mac, metric_type, conn):
    cursor = conn.cursor()
    time_window = "24 hours"
    query = f"SELECT timestamp, value, unit FROM sensor_data WHERE device_id = '{device_mac}' AND metric = '{metric_type}' AND timestamp > NOW() - INTERVAL '{time_window}' ORDER BY timestamp DESC"
    cursor.execute(query)
    telemetry = cursor.fetchall()
    cursor.close()
    return telemetry
```

## Explanation

The function parameters device_mac and metric_type are untrusted user inputs that are directly interpolated into an SQL query using f-strings on line 6. This unsanitized data is then executed via cursor.execute() on line 7, allowing attackers to inject arbitrary SQL commands.

## Remediation

The fix replaces the f-string interpolation with psycopg2's parameterized query mechanism using %s placeholders. The user-controlled values (device_mac, metric_type) and the time_window are passed as a tuple to cursor.execute(), which properly escapes and quotes them, preventing SQL injection.

## Secure Code
```python
import psycopg2

def fetch_iot_device_telemetry(device_mac, metric_type, conn):
    cursor = conn.cursor()
    time_window = "24 hours"
    query = "SELECT timestamp, value, unit FROM sensor_data WHERE device_id = %s AND metric = %s AND timestamp > NOW() - INTERVAL %s ORDER BY timestamp DESC"
    cursor.execute(query, (device_mac, metric_type, time_window))
    telemetry = cursor.fetchall()
    cursor.close()
    return telemetry
```
