Skip to content

extra_patterns are matched on the application thread, so a nested-quantifier pattern stalls the caller #2235

Description

@dsfaccini

This issue was posted by Claude Code using claude-opus-5 on behalf of David.

Description

Patterns supplied via ScrubbingOptions.extra_patterns are compiled into the scrubbing regex and run over attribute values. MessageValueCleaner.clean_value is called during message formatting at span-creation time, so this runs on the application's own thread, not on the exporter thread.

A user pattern with nested quantifiers therefore turns an attribute value into a stall of the calling code:

import time, logfire

logfire.configure(
    send_to_logfire=False,
    scrubbing=logfire.ScrubbingOptions(extra_patterns=[r'(a+)+$']),
)

payload = 'a' * 26 + '!'          # e.g. a field from an incoming request
t0 = time.perf_counter()
logfire.info('user said {msg}', msg=payload)
print(f'{(time.perf_counter() - t0) * 1000:.0f} ms')

Measured on logfire==4.40.0, Python 3.13.3, macOS:

input length time
16 13 ms
20 183 ms
24 3.0 s
26 17.8 s
27 (through logfire.info) 28.3 s

Growth is exponential, so a slightly longer value stalls the thread indefinitely.

The 18 entries in DEFAULT_PATTERNS are all linear and are not affected — the exposure comes only from user-supplied patterns. But the value being matched is frequently attacker-influenced (a request field, a header, a form value), so a well-meaning pattern turns instrumentation into a denial-of-service vector against the instrumented application itself.

Suggested fix

At minimum, document the risk on ScrubbingOptions.extra_patterns — nothing currently warns that user patterns run synchronously on the application thread against untrusted input.

Beyond that: rejecting obvious nested-quantifier shapes at configure time would catch the common cases cheaply. A full guarantee is not reachable with re.

Versions

logfire==4.40.0, Python 3.13.3, macOS.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions