Skip to content

DSML gateway: cap the number of operations per batchRequest, a compare on userPassword costs a password verification #843

Description

@vharseko

Split out of the review of #835.

What happens

#835 (issue #825) capped the number of batchRequest elements per SOAP body, closing bind amplification: every element costs its own connection and bind. It deliberately does not cap the number of operations inside a single batchRequest, so one POST on one bind is still an amplifier.

Under the new defaults (ldap.dsml.batchrequests.max=1, ldap.dsml.request.maxsize=10485760) a single body still holds on the order of 90k <compareRequest> elements asserting userPassword. A compare against an attribute stored under a salted password scheme (PBKDF2, bcrypt, …) triggers the same deliberately slow password verification as a bind, so the ratio between what the client sends and what the directory server computes stays high — it just runs on one authenticated connection instead of many binds.

Reachability under the stock configuration: the default global ACI "Self entry read" grants compare on userPassword to ldap:///self, so any authenticated user can drive the compare amplifier against their own entry under default ACIs. Moreover, the web.xml shipped with the gateway suggests cn=Directory Manager as the ldap.userdn example — a gateway deployed that way binds as a root DN, bypasses ACIs entirely, and the amplifier becomes reachable pre-authentication.

Where

opendj-dsml-servlet/src/main/java/org/opends/dsml/protocol/DSMLServlet.java, the for (DsmlMessage request : list) loop in doPost() which executes batchRequest.getBatchRequests() one by one.

Suggested fix, and why it is not a one-liner

A configurable cap on the number of operations accepted per batchRequest (a web.xml context-param next to ldap.dsml.batchrequests.max), rejecting the excess with a notAttempted errorResponse, would mirror the #835 approach. But unlike the per-body cap — where DSMLv2 describes a single batchRequest per SOAP body and the second and later elements never worked before #811 anyway — large batches of operations are a designed use of DSMLv2 (bulk provisioning), so a low default would break legitimate clients. The decision to make is the default: a generous cap, or unlimited-unless-configured.

The gateway is not deployed by default, so this is hardening rather than an exposure in a stock installation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementjavaPull requests that update java codesecuritySecurity fixes / CodeQL code-scanning alerts

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions