Skip to content

fix(LDAP): escape DN on check-user#44350

Merged
blizzz merged 2 commits into
masterfrom
fix/noid/ldap-check-user-escape
Apr 10, 2024
Merged

fix(LDAP): escape DN on check-user#44350
blizzz merged 2 commits into
masterfrom
fix/noid/ldap-check-user-escape

Conversation

@blizzz

@blizzz blizzz commented Mar 20, 2024

Copy link
Copy Markdown
Member

Summary

the DN has to be escaped differently when used as a base and we were missing it here in the search method call in the check-user command.

Checklist

@blizzz blizzz added this to the Nextcloud 29 milestone Mar 20, 2024
@blizzz blizzz requested review from a team, ArtificialOwl, come-nc, max-nextcloud and sorbaugh and removed request for a team March 20, 2024 11:32
@blizzz

blizzz commented Mar 20, 2024

Copy link
Copy Markdown
Member Author

/backport to stable28

@blizzz

blizzz commented Mar 20, 2024

Copy link
Copy Markdown
Member Author

/backport to stable27

$user = $access->userManager->get($uid);
$avatarAttributes = $access->getConnection()->resolveRule('avatar');
$result = $access->search('objectclass=*', $user->getDN(), $attrs, 1, 0);
$baseDn = $this->helper->DNasBaseParameter($user->getDN());

Check notice

Code scanning / Psalm

PossiblyNullReference

Cannot call method getDN on possibly null value
@max-nextcloud

Copy link
Copy Markdown
Contributor

/backport! to stable28

@max-nextcloud

Copy link
Copy Markdown
Contributor

backporting right away to have a patch the customer can test.

@come-nc come-nc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So getDN does not return the raw dn but an escaped version?
Where is it escaped and how?

@blizzz

blizzz commented Mar 21, 2024

Copy link
Copy Markdown
Member Author

So getDN does not return the raw dn but an escaped version? Where is it escaped and how?

It is stored in an escaped way in the database. But when you use a DN as base parameter, it has to be differently encoded. It's all about the backslash.

@blizzz

blizzz commented Mar 21, 2024

Copy link
Copy Markdown
Member Author

@come-nc

come-nc commented Mar 21, 2024

Copy link
Copy Markdown
Contributor

@blizzz But I was sure we were using ldap_escape when using the dn (or anything really) in the search, with this system we may get double escaping.
It’s too late for changing this I suppose but it should be better documented.
https://github.com/nextcloud/server/blob/master/apps/user_ldap/lib/User/User.php#L365 does not specify that it’s escaped in any way.

@blizzz

blizzz commented Mar 21, 2024

Copy link
Copy Markdown
Member Author

@blizzz But I was sure we were using ldap_escape when using the dn (or anything really) in the search, with this system we may get double escaping. It’s too late for changing this I suppose but it should be better documented. https://github.com/nextcloud/server/blob/master/apps/user_ldap/lib/User/User.php#L365 does not specify that it’s escaped in any way.

The DN is escaped in Helper::sanitizeDN() and this is used for queries/filters.

When the DN is used as base DN for operations though, the backlash must not be escaped as \5c.

That is the difference.

P.S.: sanitizeDN() follows RFC 2253

@Altahrim Altahrim mentioned this pull request Mar 25, 2024
@skjnldsv skjnldsv mentioned this pull request Mar 28, 2024
81 tasks
@blizzz blizzz mentioned this pull request Apr 4, 2024
67 tasks
@blizzz blizzz requested a review from come-nc April 4, 2024 08:21

@come-nc come-nc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I still think this should be better documented.

the DN has to be escaped differently when used as a base and we were
missing it here in the search method call in the check-user command.

Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
@blizzz blizzz force-pushed the fix/noid/ldap-check-user-escape branch from c2c27e1 to 55d3a2a Compare April 5, 2024 14:47
Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
@blizzz

blizzz commented Apr 5, 2024

Copy link
Copy Markdown
Member Author

@come-nc I added a commit with the doc. Not in the user model though, because it returns only what it was being fed with. Is this acceptable?

@blizzz blizzz modified the milestones: Nextcloud 29, Nextcloud 30 Apr 5, 2024
@blizzz

blizzz commented Apr 5, 2024

Copy link
Copy Markdown
Member Author

/backport to stable29

@come-nc

come-nc commented Apr 8, 2024

Copy link
Copy Markdown
Contributor

@come-nc I added a commit with the doc. Not in the user model though, because it returns only what it was being fed with. Is this acceptable?

Yeah it helps. It still bugs me that we do not escape upon building the filter instead. I think we avoid double-escaping only because we do not apply escape when searching for group members, and we got lucky that uids never need escaping.
To be safe

$uid = $result[0];
should escape for instance, because it is later used raw in the filter, and the dn version is already escaped. Our internal code is not clear enough on what is escaped or not and that’s dangerous.

@blizzz

blizzz commented Apr 8, 2024

Copy link
Copy Markdown
Member Author

@come-nc I added a commit with the doc. Not in the user model though, because it returns only what it was being fed with. Is this acceptable?

Yeah it helps. It still bugs me that we do not escape upon building the filter instead. I think we avoid double-escaping only because we do not apply escape when searching for group members, and we got lucky that uids never need escaping. To be safe

$uid = $result[0];

should escape for instance, because it is later used raw in the filter, and the dn version is already escaped. Our internal code is not clear enough on what is escaped or not and that’s dangerous.

There is no double escape per se. It is only about the backslash that is expected in different forms when used in search filter compared to when used as base. As usage in filters is the common usage, that format was chosen to be saved in the DB.

@blizzz

blizzz commented Apr 8, 2024

Copy link
Copy Markdown
Member Author

P.S.: When is the raw uid used in a search filter? (Apart from override as uuid attribute)

@come-nc

come-nc commented Apr 8, 2024

Copy link
Copy Markdown
Contributor

P.S.: When is the raw uid used in a search filter? (Apart from override as uuid attribute)

$filter = $this->access->connection->ldapGroupMemberAssocAttr . '=' . $dn;
(following the line I posted earlier, $dn may be the uid there.)

@blizzz

blizzz commented Apr 10, 2024

Copy link
Copy Markdown
Member Author

P.S.: When is the raw uid used in a search filter? (Apart from override as uuid attribute)

$filter = $this->access->connection->ldapGroupMemberAssocAttr . '=' . $dn;

(following the line I posted earlier, $dn may be the uid there.)

Indeed. In those cases when a DN is not being used to reference members 😰 But a valid case nonetheless. This is not in scope for this PR though, and also it is nothing that can be crafted by a shady user.

@blizzz blizzz added 4. to release Ready to be released and/or waiting for tests to finish and removed 3. to review Waiting for reviews labels Apr 10, 2024
@blizzz blizzz merged commit e70cf9c into master Apr 10, 2024
@blizzz blizzz deleted the fix/noid/ldap-check-user-escape branch April 10, 2024 10:02
@blizzz

blizzz commented Apr 10, 2024

Copy link
Copy Markdown
Member Author

/backport! to stable28

@backportbot

This comment was marked as resolved.

@blizzz blizzz mentioned this pull request Jul 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

4. to release Ready to be released and/or waiting for tests to finish bug feature: ldap

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants