# SQL Injection via f-string Query Construction

Language: Python
Severity: Critical
CWE: CWE-89

## Source
1

## Flow
1-4-5

## Sink
4

## Vulnerable Code
```python
def fetch_iot_sensor_metrics(device_mac, metric_type):
    conn = psycopg2.connect(database="iot_telemetry", user="admin")
    cursor = conn.cursor()
    query = f"SELECT timestamp, value, unit FROM sensor_data WHERE device_id = '{device_mac}' AND metric = '{metric_type}' ORDER BY timestamp DESC LIMIT 100"
    cursor.execute(query)
    results = cursor.fetchall()
    return [{"ts": r[0], "val": r[1], "unit": r[2]} for r in results]
```

## Explanation

The function accepts user-controlled parameters device_mac and metric_type which are directly interpolated into an SQL query using f-strings on line 4. This unsanitized input is then executed via cursor.execute() on line 5, allowing attackers to inject arbitrary SQL commands that can bypass query logic, extract sensitive data, or manipulate the database.

## Remediation

The fix replaces the dangerous f-string interpolation with psycopg2's parameterized query mechanism using %s placeholders. The user-controlled values device_mac and metric_type are passed as a tuple in the second argument to cursor.execute(), which ensures they are properly escaped and treated as literal values rather than executable SQL code.

## Secure Code
```python
def fetch_iot_sensor_metrics(device_mac, metric_type):
    conn = psycopg2.connect(database="iot_telemetry", user="admin")
    cursor = conn.cursor()
    query = "SELECT timestamp, value, unit FROM sensor_data WHERE device_id = %s AND metric = %s ORDER BY timestamp DESC LIMIT 100"
    cursor.execute(query, (device_mac, metric_type))
    results = cursor.fetchall()
    return [{"ts": r[0], "val": r[1], "unit": r[2]} for r in results]
```
