AI Pentesting

CVE-2026-71510: Blind Search Leaks Dolibarr Salaries Copy

Amartya | CodeAnt AI Code Review Platform
Sonali Sood

Founding GTM, CodeAnt AI

CVSS 6.5 · Authorization oracle → blind disclosure (CWE-863 / CWE-200) · Fixed in Dolibarr 24.0.0

You can't see the salary column anywhere on screen, but the search box will happily answer one question over and over: is this person's salary above 50,000, yes or no? Ask a couple dozen smart questions and you've read the exact number without the system ever showing it to you.

The attack in six steps

  1. The user list has a search filter: you can narrow it by a column's value.

  2. It's safe from SQL injection: the obvious attack was checked, and it holds.

  3. The unasked question: which columns may you filter on?: the answer was any of them, including salary and the password hash. (this is the break)

  4. Those columns are stripped from the reply: so you never actually see the value.

  5. But "filter salary above X" returns a row, or nothing: that single yes/no is a leak.

  6. Binary-search the answers to the exact number: salaries recovered blind, plus a case-folded image of the hash. → blind disclosure.

There's a whole class of secret you can steal without the system ever showing it to you. You don't need it to hand over the value. You only need it to answer yes-or-no questions about that value, honestly, as many times as you like. Twenty good questions are enough to pin down almost any number.

This is what a search box did when it kept answering exactly those questions about columns it was supposed to keep hidden, salaries, and even the stored password verifier, letting a low-privilege account read them precisely, blind, without the system ever displaying a single one.

It's the most subtle finding in the set, because nothing here looks broken. No error, no leak on the screen, no obvious hole. Just a search filter answering a question it should have refused to consider, and a textbook case of the kind of sensitive data exposure that a straightforward vulnerability scan sails right past: the feature isn't injectable, the response doesn't show the field, and the authorization logic still lets a low-privilege user interrogate it anyway.

The obvious attack, and the one underneath it

The user list has a search filter, so you can narrow the list by a column's value. The reflex is to test it for injection: can you break out of the query and run your own? We checked, and the answer was no. On that front it is safe, and a lot of reviews would stop there satisfied.

The second, quieter question is not about breaking the query at all. It is about authorization: which columns are you even allowed to filter on? The answer turned out to be all of them, including the salary fields and the password verifier that the results are so careful never to display.

This is where security testing has to go beyond checking whether an endpoint returns the expected response. A penetration test also needs to ask whether a low-privilege user can use an otherwise legitimate feature to access information they are not authorized to interrogate.

Turning a filter into a yes/no oracle

Those columns are stripped from what comes back, so you never see a salary in the list. But you can still filter on one. And a filter you can apply to a hidden column is a question the system will answer: ask it to show everyone whose salary is above fifty thousand, and either a matching row comes back or it doesn't. Row or no row. Yes or no.

That single bit is the whole leak. Ask "above 50,000?": no. "above 25,000?": yes. "above 37,000?": and so on, each question halving the range that's left. In a couple of dozen questions you have squeezed the exact figure out of a value the screen never showed you. Point the same technique at the stored password verifier and you can walk it out piece by piece.

The honest part: what it is not

A responsible finding has to say where the danger stops, and we were careful to. The password material you can recover this way is not a usable key to log in with: Dolibarr stores it in a form it will not accept back as a login, and the recovered image is case-folded rather than exact. So this is a serious disclosure, real salaries, real hidden fields, read blind, but it is not, by itself, account takeover. We tested that boundary, confirmed it held, and wrote the disproof into the report so a reviewer could see we had actually checked rather than assumed.

That distinction matters for trust. It is easy to inflate a finding by implying the worst. It is more useful, and more credible, to show exactly how far it goes and exactly where it stops.

Why it's easy to miss, and what closes it

This is the kind of hole endpoint-by-endpoint testing walks straight past. The filter isn't injectable. The response doesn't leak. Nothing throws an error. The only thing wrong is that a question was allowed which never should have been, and you only see it if you ask, of a search feature, not "can I break this," but "which fields am I permitted to ask about."

What actually closes this

The fix in 24.0.0 restricts which columns the filter will accept, so hidden fields can no longer be interrogated through the back door of a yes/no search. The broader lesson is to treat a filter as an authorization surface, not just an injection surface. Every column you let a caller filter on is a column you're willing to answer questions about, one bit at a time, which is exactly the kind of side channel attack that never shows up as a single dramatic failure, only as a feature quietly answering questions it was never supposed to entertain.

This is also why real security testing services have to look past individual endpoints. The issue here was never an injection flaw, the query was safe the whole way through. It was the interaction between filtering, authorization, and which fields a search feature is willing to reason about, and that interaction is exactly the kind of behavior that deeper application security testing surfaces, not a scanner running down a checklist of known payloads.

The fix

Upgrade to Dolibarr 24.0.0. That closes this finding. Want to know where your own app disagrees with itself? Start with a free CodeAnt pentest.

Back to all nine findings in the Dolibarr research series

FAQs

Start Your 14-Day Free Trial

AI code reviews, security and quality trusted by modern engineering teams.

Table of Content
No headings found on page
Ship clean & secure code faster

Get Pentest Report

NO CC REQUIRED