Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 2 commits into from
Apr 10, 2024
Merged

Conversation

blizzz
Copy link
Member

@blizzz blizzz commented Mar 20, 2024

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 come-nc, max-nextcloud, a team, ArtificialOwl and sorbaugh and removed request for a team March 20, 2024 11:32
@blizzz
Copy link
Member Author

blizzz commented Mar 20, 2024

/backport to stable28

@blizzz
Copy link
Member Author

blizzz commented Mar 20, 2024

/backport to stable27

apps/user_ldap/lib/Command/CheckUser.php Dismissed Show dismissed Hide dismissed
@max-nextcloud
Copy link
Contributor

/backport! to stable28

@max-nextcloud
Copy link
Contributor

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

Copy link
Contributor

@come-nc come-nc left a comment

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
Copy link
Member Author

blizzz commented Mar 21, 2024

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
Copy link
Member Author

blizzz commented Mar 21, 2024

cf. https://github.com/nextcloud/server/blob/master/apps/user_ldap/lib/Access.php#L252 and https://github.com/nextcloud/server/blob/master/apps/user_ldap/lib/Access.php#L1600

P.S.: putting it differently, when using it in the search filter, the backslash has to be escaped, what we default to, cf. https://www.rfc-editor.org/rfc/rfc2254#page-5

@come-nc
Copy link
Contributor

come-nc commented Mar 21, 2024

@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
Copy link
Member Author

blizzz commented Mar 21, 2024

@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
Copy link
Contributor

@come-nc come-nc left a comment

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
Copy link
Member Author

blizzz commented Apr 5, 2024

@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
Copy link
Member Author

blizzz commented Apr 5, 2024

/backport to stable29

@come-nc
Copy link
Contributor

come-nc commented Apr 8, 2024

@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
Copy link
Member Author

blizzz commented Apr 8, 2024

@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
Copy link
Member Author

blizzz commented Apr 8, 2024

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

@come-nc
Copy link
Contributor

come-nc commented Apr 8, 2024

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
Copy link
Member Author

blizzz commented Apr 10, 2024

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
168 checks passed
@blizzz blizzz deleted the fix/noid/ldap-check-user-escape branch April 10, 2024 10:02
@blizzz
Copy link
Member Author

blizzz commented Apr 10, 2024

/backport! to stable28

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.

3 participants