# XML Entity Expansion (Billion Laughs)

Language: Python
Severity: High
CWE: CWE-776

## Source
9

## Flow
9-11

## Sink
11

## Vulnerable Code
```python
import xml.etree.ElementTree as ET
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/iot/device/config', methods=['POST'])
def update_device_config():
    config_xml = request.data.decode('utf-8')
    try:
        root = ET.fromstring(config_xml)
        device_id = root.find('device_id').text
        settings = {child.tag: child.text for child in root.find('settings')}
        return jsonify({'status': 'success', 'device': device_id, 'applied': settings})
    except ET.ParseError:
        return jsonify({'error': 'Invalid XML format'}), 400
```

## Explanation

The code uses xml.etree.ElementTree to parse untrusted XML input without disabling entity expansion. This allows attackers to craft malicious XML with recursive entity definitions (Billion Laughs attack) that exponentially expand in memory, causing denial of service through resource exhaustion.

## Remediation

The fix replaces the standard `xml.etree.ElementTree` module with `defusedxml.ElementTree`, which provides protection against XML entity expansion attacks (Billion Laughs), external entity attacks (XXE), and other XML-based exploits by disabling DTD processing and entity expansion by default.

## Secure Code
```python
import defusedxml.ElementTree as ET
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/iot/device/config', methods=['POST'])
def update_device_config():
    config_xml = request.data.decode('utf-8')
    try:
        root = ET.fromstring(config_xml)
        device_id = root.find('device_id').text
        settings = {child.tag: child.text for child in root.find('settings')}
        return jsonify({'status': 'success', 'device': device_id, 'applied': settings})
    except ET.ParseError:
        return jsonify({'error': 'Invalid XML format'}), 400
```
