Skip to content

ldap: reject control characters in URL-decoded filter values - #22524

Closed
anupamme wants to merge 3 commits into
curl:masterfrom
anupamme:fix-repo-curl-ldap-filter-injection-v002
Closed

anupamme wants to merge 3 commits into
curl:masterfrom
anupamme:fix-repo-curl-ldap-filter-injection-v002

Conversation

@anupamme

@anupamme anupamme commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

I've updated the PR. The original approach was wrong: lud_filter holds a complete LDAP filter expression, so rejecting LDAP metacharacters like (, ), |, &, * would break valid filters, and a parenthesis-balance check is not equivalent to RFC 4515 escaping.

This version fixes the concrete issue at the right layer: control characters (bytes < 0x20) in per cent-encoded filter values are now rejected at URL-decode time via REJECT_CTRL, before the string is stored in lud_filter. The previous ad-hoc validator in ldap_do is removed entirely.

Changes

  • lib/ldap.c: change REJECT_ZEROREJECT_CTRL in ldap_url_parse2_low when URL-decoding the filter component; remove the post-parse validator from ldap_do

Why this is the right place

Curl_urldecode() already supports REJECT_CTRL (used elsewhere in the codebase), which rejects decoded bytes < 0x20. Applying it to the filter decode catches per cent-encoded control characters (%01, %0a, etc.) as they enter the filter string — before they reach ldap_search_s. This is a minimal, targeted fix with a clear justification and no impact on valid LDAP filter syntax.

Automated security fix generated by OrbisAI Security
@testclutch

Copy link
Copy Markdown

Analysis of PR #22524 at 3c2bb276:

Test 2501 failed, but it has been 12.7% flaky lately, so it's probably NOT a fault of the PR. Note that this test has failed in 2 different CI jobs (the link just goes to one of them). Note that this CI job has had a number of other flaky tests recently (3, to be specific) so it may be that this failure is rather a systemic issue with this job and not with this specific PR.

Test ../../tests/http/test_06_eyeballs.py::TestEyeballs::test_06_02_h3_only failed, which has NOT been flaky recently, so there could be a real issue in this PR. Note that this test has failed in 2 different CI jobs (the link just goes to one of them).

Test ../../tests/http/test_21_resolve.py::TestResolve::test_21_14_dnsd_servfail_uncached[DoH] failed, which has NOT been flaky recently, so there could be a real issue in this PR. Note that this test has failed in 2 different CI jobs (the link just goes to one of them).

Generated by Testclutch

Replace the ad-hoc parenthesis/metacharacter validator in ldap_do with
REJECT_CTRL at the URL-decode layer in ldap_url_parse2_low. This rejects
percent-encoded control characters (bytes < 0x20) when the filter string
is decoded from the LDAP URL, which is the correct place to enforce this.

The previous validator incorrectly rejected valid LDAP filter syntax
characters such as '(', ')', '|', '&', '*', and '!' which are meaningful
operators per RFC 4515.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@anupamme anupamme changed the title harden: the ldap_do function in lib/ldap in ldap.c ldap: reject control characters in URL-decoded filter values Aug 10, 2026

@bagder bagder left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems reasonable, apart from the minor nit

Comment thread lib/ldap.c Outdated
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@bagder bagder closed this in a61f2f9 Aug 10, 2026
@bagder

bagder commented Aug 10, 2026

Copy link
Copy Markdown
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

3 participants