Skip to content

fix(dav): return 401 instead of 503 for disabled user login attempts#58804

Open
boris324 wants to merge 1 commit intonextcloud:masterfrom
boris324:fix/disabled-user-login-error-level
Open

fix(dav): return 401 instead of 503 for disabled user login attempts#58804
boris324 wants to merge 1 commit intonextcloud:masterfrom
boris324:fix/disabled-user-login-error-level

Conversation

@boris324
Copy link
Copy Markdown

@boris324 boris324 commented Mar 9, 2026

Fixes #22758

When a disabled user's device tries to sync via WebDAV, the LoginException was caught by the generic Exception handler in Auth::check(), causing a 503 ServiceUnavailable logged at error/fatal level. This spams logs when disabled users have devices that keep trying to sync.

This PR catches LoginException specifically and returns 401 NotAuthenticated instead, logging at info level since a disabled user attempting login is expected behavior, not a server error.

When a disabled user's device tries to sync via WebDAV, a LoginException
was caught by the generic Exception handler in Auth::check(), resulting
in a 503 ServiceUnavailable response logged at error level. This caused
constant fatal errors in logs for disabled users whose devices continue
to attempt sync.

Catch LoginException specifically and return 401 NotAuthenticated instead,
logging at info level since this is expected behavior.

Fixes nextcloud#22758
@boris324 boris324 requested a review from a team as a code owner March 9, 2026 12:14
@boris324 boris324 requested review from ArtificialOwl, leftybournes, nfebe and sorbaugh and removed request for a team March 9, 2026 12:14
@kesselb kesselb requested a review from Copilot March 9, 2026 16:29
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adjusts the DAV authentication error handling so that disabled-user login attempts (and other LoginExceptions) result in a 401 NotAuthenticated instead of being treated as a server-side 503 ServiceUnavailable, reducing unnecessary high-severity log noise during repeated sync attempts.

Changes:

  • Catch OC\User\LoginException in OCA\DAV\Connector\Sabre\Auth::check() and convert it into Sabre\DAV\Exception\NotAuthenticated while logging at info level.
  • Add a unit test covering the LoginExceptionNotAuthenticated behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
apps/dav/lib/Connector/Sabre/Auth.php Adds a LoginException catch to return 401 NotAuthenticated instead of 503 ServiceUnavailable.
apps/dav/tests/unit/Connector/Sabre/AuthTest.php Adds a unit test asserting LoginException is mapped to NotAuthenticated.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +113 to +115
} catch (LoginException $e) {
Server::get(LoggerInterface::class)->info($e->getMessage(), ['exception' => $e]);
throw new NotAuthenticated($e->getMessage(), 0, $e);
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

When a LoginException bubbles up from validateUserPass()/auth(), the PHP session may still be open (validateUserPass() does not close the session on LoginException). This catch block converts the exception but doesn't close the session either, which can keep the session lock held longer than necessary and potentially slow down concurrent requests. Call $this->session->close() (ideally in a finally or at least before logging/throwing) on this path as well.

Copilot uses AI. Check for mistakes.
Comment on lines +114 to +115
Server::get(LoggerInterface::class)->info($e->getMessage(), ['exception' => $e]);
throw new NotAuthenticated($e->getMessage(), 0, $e);
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

Propagating the LoginException message to the client (via NotAuthenticated) can reveal account state (e.g. disabled vs. non-existent/wrong password), enabling user/account enumeration over WebDAV. Consider returning a generic NotAuthenticated message (consistent with other auth failures) while logging the detailed reason server-side.

Copilot uses AI. Check for mistakes.
@joshtrichards
Copy link
Copy Markdown
Member

There may be room for improving the logging/log level, but I believe the 50x versus 401 may be related to a (additional?) safeguard preventing inadvertent date deletion client-side... though I may be misremembering.

@github-actions
Copy link
Copy Markdown
Contributor

Hello there,
Thank you so much for taking the time and effort to create a pull request to our Nextcloud project.

We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process.

Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6

Thank you for contributing to Nextcloud and we hope to hear from you soon!

(If you believe you should not receive this message, you can add yourself to the blocklist.)

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Disabled users throw constant fatal frror in logs: ServiceUnavailable + LoginException

3 participants