# PYTHON-LANG-SEC-104: logging.config.listen() Eval Risk

> **Severity:** HIGH | **CWE:** CWE-95 | **OWASP:** A03:2021

- **Language:** Python
- **Category:** Python Core
- **URL:** https://codepathfinder.dev/registry/python/lang/PYTHON-LANG-SEC-104
- **Detection:** `pathfinder scan --ruleset python/PYTHON-LANG-SEC-104 --project .`

## Description

This rule detects calls to logging.config.listen(), which starts a socket server
that accepts logging configuration over the network. By default, the received
configuration is processed using logging.config.dictConfig() or
logging.config.fileConfig(), which can execute arbitrary Python code through
handler class references and filter callables.

An attacker who can connect to the listening port can send a configuration dict
that specifies a handler class like os.system, effectively achieving remote code
execution. Python's own documentation warns that "this function is useful for
updating logging configuration from a remote machine, but it is not secure."

The rule matches LoggingConfig.method("listen") and fires on any invocation.


## Vulnerable Code

```python
import uuid
import os
import re
import logging
import logging.config

# SEC-104: logging.config.listen
server = logging.config.listen(9999)
```

## Secure Code

```python
import logging
import logging.config

# SECURE: Use static configuration, not network-based
logging.config.dictConfig({
    'version': 1,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'INFO',
        },
    },
    'root': {
        'handlers': ['console'],
        'level': 'INFO',
    },
})

# If you need remote config updates, use a configuration management
# system (environment variables, config files) with proper access controls

```

## Detection Rule (Python SDK)

```python
from rules.python_decorators import python_rule
from codepathfinder import calls, QueryType

class LoggingConfig(QueryType):
    fqns = ["logging.config"]


@python_rule(
    id="PYTHON-LANG-SEC-104",
    name="logging.config.listen() Eval Risk",
    severity="HIGH",
    category="lang",
    cwe="CWE-95",
    tags="python,logging,listen,eval,code-execution,CWE-95",
    message="logging.config.listen() can execute arbitrary code via configuration. Restrict access.",
    owasp="A03:2021",
)
def detect_logging_listen():
    """Detects logging.config.listen() which evaluates received config."""
    return LoggingConfig.method("listen")
```

## How to Fix

- Remove logging.config.listen() from production code entirely
- Use static logging configuration via dictConfig() or fileConfig() loaded at startup
- If remote logging reconfiguration is needed, implement it through your application's authenticated API, not through logging.config.listen()
- Bind logging listeners to localhost only if they must exist, and restrict access via firewall rules
- Use Python 3.2+ verify parameter to provide a verification function that validates configs before applying

## Security Implications

- **Remote Code Execution via Configuration:** The listener accepts dictConfig-format payloads over TCP. A crafted config
can specify arbitrary Python callables as handler classes, filter functions,
or formatter factories. This executes code in the context of the application
process with its full permissions.

- **No Authentication by Default:** logging.config.listen() binds to a port with no authentication, encryption,
or access control. Any process that can connect to the port can send config.
On a server with a public IP, this is directly exploitable from the internet.

- **Privilege Escalation:** If the application runs as root or with elevated permissions, an attacker
who sends a malicious config gains those same permissions. In containerized
environments, this can lead to container escape.


## FAQ

**Q: Why is logging.config.listen() dangerous?**

It opens a TCP socket that accepts Python logging configuration dicts.
Those dicts can specify arbitrary Python callables as handler classes.
Anyone who connects to the port can send a config that executes code.


**Q: Can I use the verify parameter to make it safe?**

Python 3.2+ added a verify parameter that lets you provide a function to
validate incoming configs. This helps but is difficult to get right since
you'd need to whitelist safe handler classes and reject everything else.
Removing listen() entirely is safer.


**Q: Is this only a risk on internet-facing servers?**

No. Any process on the same network (or localhost) can connect. In cloud
environments with flat networks, a compromised adjacent service can reach
the listener. Defense in depth means not relying solely on network isolation.


**Q: How do I run this rule in CI/CD?**

Run: pathfinder ci --ruleset python/lang --project .


## References

- [CWE-95: Eval Injection](https://cwe.mitre.org/data/definitions/95.html)
- [Python logging.config.listen() documentation](https://docs.python.org/3/library/logging.config.html#logging.config.listen)
- [OWASP A03:2021 Injection](https://owasp.org/Top10/A03_2021-Injection/)

---

Source: https://codepathfinder.dev/registry/python/lang/PYTHON-LANG-SEC-104
Code Pathfinder — Open source, type-aware SAST with cross-file dataflow analysis
