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

CouchDB v3.4.1 return 403 on GET /_session with a wrong password #5315

Open
H--o-l opened this issue Oct 21, 2024 · 5 comments
Open

CouchDB v3.4.1 return 403 on GET /_session with a wrong password #5315

H--o-l opened this issue Oct 21, 2024 · 5 comments

Comments

@H--o-l
Copy link

H--o-l commented Oct 21, 2024

Description

This morning I upgraded one node of my CouchDB cluster node to v3.4.1 while the two other nodes of the cluster are still on CouchDB v3.3.3.

Since then, I have had multiple exceptions on my backend related to users using the wrong password and CouchDB returning an HTTP status 403 instead of the usual HTTP status 401.

Usually, I catch the 401 to return a nice message to users so they can understand what's wrong. But since the update, for some users (not all users and I don't know why on these users specifically) CouchDB returns an unexpected 403 on the GET /_session. This has pushed me to create a temporary urgent release where I catch both the 401 and the 403 to return a nice error in both cases.

The CouchDB documentation for v3.4.1 is explicit: the route should only return HTTP 200 or HTTP 401, not HTTP 403.

Steps to Reproduce

I don't know for sure, I wasn't able to code a reproducer, it happens only on my production servers. There is something on the production cluster that makes the case appear:

  • maybe it's the fact of having one node on v3.4.1 and the two others on v3.3.3?
  • maybe it's something user-specific? But I don't know what specificities to look at.

Expected Behaviour

GET /_session should always return HTTP 200 or HTTP 401, never HTTP 403.

Your Environment

  • CouchDB version used: v3.4.1 and v3.3.3. The error occurs only on GET /_session made on the v3.4.1 node.
  • Browser name and version: NA
  • Operating system and version: NA

Additional Context

I don't know, you tell me!

@iilyak
Copy link
Contributor

iilyak commented Oct 21, 2024

This is a feature added recently https://github.com/apache/couchdb/blob/main/rel/overlay/etc/default.ini#L1074. Probably the API docs need to be updated.

\cc @rnewson

@rnewson
Copy link
Member

rnewson commented Oct 21, 2024

agree, the docs need updating. what a chore :(

@H--o-l
Copy link
Author

H--o-l commented Oct 21, 2024

OK, understood, thanks. What about the changelog, did the change appear inside it? Because I read it carefully before doing the update and I haven't noticed that change. It would have avoided inconvenience for my users if I had been able to notice it before the update.

@rnewson
Copy link
Member

rnewson commented Oct 21, 2024

The new lockout support was documented in the changelog (https://docs.couchdb.org/en/stable/whatsnew/3.4.html), but we (I) didn't update the api docs to list 403 as a possibility for all endpoints, we'll sort that out.

@H--o-l
Copy link
Author

H--o-l commented Oct 21, 2024

OK, my bad, thanks for the answer. I let you see then, and you can close the issue when you want 👍

H--o-l added a commit to H--o-l/aiocouch that referenced this issue Oct 23, 2024
Since CouchDB v3.4.0, there has been a new "Lockout" feature, i.e., a rate limit
on tuples (IP, login) after multiple authentication failures. It's highlighted
in the release note: https://docs.couchdb.org/en/stable/whatsnew/3.4.html#id4
(see the second to last bullet point).

As the following upstream discussion shows, this CouchDB feature adds a new case
of HTTP 403 possible on all routes:
apache/couchdb#5315 (comment)

This commit catch the 403 on all routes. As some route were already catching 403
for other reasons, the exception message on these route is changed from their
previous message to `"Access forbidden: {reason}"` where `reason` is either the
`reason` returned by CouchDB in the JSON body of the answer, or if it doesn't
exist, by the `message` of aiohttp ClientResponseError.

I manually tested a non-stream route with `await couchdb.info()`, it returns the
following:

```
> await couchdb.info()
...
aiocouch.exception.UnauthorizedError: Invalid credentials
> await couchdb.info()  # <=== Lockout
...
aiocouch.exception.ForbiddenError: Access forbidden: Account is temporarily
locked due to multiple authentication failures
```
H--o-l added a commit to H--o-l/aiocouch that referenced this issue Oct 23, 2024
Since CouchDB v3.4.0, there has been a new "Lockout" feature, i.e., a rate limit
on tuples (IP, login) after multiple authentication failures. It's highlighted
in the release note: https://docs.couchdb.org/en/stable/whatsnew/3.4.html#id4
(see the second to last bullet point).

As the following upstream discussion shows, this CouchDB feature adds a new case
of HTTP 403 possible on all routes:
apache/couchdb#5315 (comment)

This commit catches the 403 on all routes. As some routes were already catching
403 for other reasons, the exception message on these routes is changed from
their previous message to `"Access forbidden: {reason}"` where `reason` is
either the `reason` returned by CouchDB in the JSON body of the answer, or if
it doesn't exist, by the `message` of aiohttp ClientResponseError.

I manually tested a non-stream route with `await couchdb.info()`, it returns the
following:

```
> await couchdb.info()
...
aiocouch.exception.UnauthorizedError: Invalid credentials
> await couchdb.info()  # <=== Lockout
...
aiocouch.exception.ForbiddenError: Access forbidden: Account is temporarily
locked due to multiple authentication failures
```
H--o-l added a commit to H--o-l/aiocouch that referenced this issue Oct 23, 2024
Since CouchDB v3.4.0, there has been a new "Lockout" feature, i.e., a rate limit
on tuples (IP, login) after multiple authentication failures. It's highlighted
in the release note: https://docs.couchdb.org/en/stable/whatsnew/3.4.html#id4
(see the second to last bullet point).

As the following upstream discussion shows, this CouchDB feature adds a new case
of HTTP 403 possible on all routes:
apache/couchdb#5315 (comment)

This commit catches the 403 on all routes. As some routes were already catching
403 for other reasons, the exception message on these routes is changed from
their previous message to `"Access forbidden: {reason}"` where `reason` is
either the `reason` returned by CouchDB in the JSON body of the answer, or if
it doesn't exist, by the `message` of aiohttp ClientResponseError.

I manually tested a non-stream route with `await couchdb.info()`, it returns the
following:

```
> await couchdb.info()
...
aiocouch.exception.UnauthorizedError: Invalid credentials
> await couchdb.info()  # <=== Lockout
...
aiocouch.exception.ForbiddenError: Access forbidden: Account is temporarily
locked due to multiple authentication failures
```
H--o-l added a commit to H--o-l/aiocouch that referenced this issue Oct 23, 2024
Since CouchDB v3.4.0, there has been a new "Lockout" feature, i.e., a rate limit
on tuples (IP, login) after multiple authentication failures. It's highlighted
in the release note: https://docs.couchdb.org/en/stable/whatsnew/3.4.html#id4
(see the second to last bullet point).

As the following upstream discussion shows, this CouchDB feature adds a new case
of HTTP 403 possible on all routes:
apache/couchdb#5315 (comment)

This commit catches the 403 on all routes. As some routes were already catching
403 for other reasons, the exception message on these routes is changed from
their previous message to `"Access forbidden: {reason}"` where `reason` is
either the `reason` returned by CouchDB in the JSON body of the answer, or if
it doesn't exist, by the `message` of aiohttp ClientResponseError.

I manually tested a non-stream route with `await couchdb.info()`, it returns the
following:

```
> await couchdb.info()
...
aiocouch.exception.UnauthorizedError: Invalid credentials
> await couchdb.info()  # <=== Lockout
...
aiocouch.exception.ForbiddenError: Access forbidden: Account is temporarily
locked due to multiple authentication failures
```
H--o-l added a commit to H--o-l/aiocouch that referenced this issue Oct 23, 2024
Since CouchDB v3.4.0, there has been a new "Lockout" feature, i.e., a rate limit
on tuples (IP, login) after multiple authentication failures. It's highlighted
in the release note: https://docs.couchdb.org/en/stable/whatsnew/3.4.html#id4
(see the second to last bullet point).

As the following upstream discussion shows, this CouchDB feature adds a new case
of HTTP 403 possible on all routes:
apache/couchdb#5315 (comment)

This commit catches the 403 on all routes. As some routes were already catching
403 for other reasons, the exception message on these routes is changed from
their previous message to `"Access forbidden: {reason}"` where `reason` is
either the `reason` returned by CouchDB in the JSON body of the answer, or if
it doesn't exist, by the `message` of aiohttp ClientResponseError.

I manually tested a non-stream route with `await couchdb.info()`, it returns the
following:

```
> await couchdb.info()
...
aiocouch.exception.UnauthorizedError: Invalid credentials
> await couchdb.info()  # <=== Lockout
...
aiocouch.exception.ForbiddenError: Access forbidden: Account is temporarily
locked due to multiple authentication failures
```
H--o-l added a commit to H--o-l/aiocouch that referenced this issue Oct 29, 2024
Since CouchDB v3.4.0, there has been a new "Lockout" feature, i.e., a rate limit
on tuples (IP, login) after multiple authentication failures. It's highlighted
in the release note: https://docs.couchdb.org/en/stable/whatsnew/3.4.html#id4
(see the second to last bullet point).

As the following upstream discussion shows, this CouchDB feature adds a new case
of HTTP 403 possible on all routes:
apache/couchdb#5315 (comment)

This commit catches the 403 on all routes. As some routes were already catching
403 for other reasons, the exception message on these routes is changed from
their previous message to `"Access forbidden: {reason}"` where `reason` is
either the `reason` returned by CouchDB in the JSON body of the answer, or if
it doesn't exist, by the `message` of aiohttp ClientResponseError.

I manually tested a non-stream route with `await couchdb.info()`, it returns the
following:

```
> await couchdb.info()
...
aiocouch.exception.UnauthorizedError: Invalid credentials
> await couchdb.info()  # <=== Lockout
...
aiocouch.exception.ForbiddenError: Access forbidden: Account is temporarily
locked due to multiple authentication failures
```

Closes metricq#55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants