No failed login limit #1709

Open
opened 2026-04-24 23:55:40 +02:00 by adam · 8 comments
Owner

Originally created by @sevenlayercookie on GitHub (Feb 4, 2024).

Describe the issue

It is possible to submit any number of failed login requests without limit, and without rate limit. This makes Audiobookshelf susceptible to brute force login methods.

as @nichwall noted, this appears to have broken in v2.6.0 with OIDC implementation.

related issue: #2533 no auth log entries.

Steps to reproduce the issue

  1. Submit incorrect password as many times as you like.
  2. Login with your normal password immediately afterward without being locked out.

Audiobookshelf version

V2.7.2

How are you running audiobookshelf?

Docker

Originally created by @sevenlayercookie on GitHub (Feb 4, 2024). ### Describe the issue It is possible to submit any number of failed login requests without limit, and without rate limit. **This makes Audiobookshelf susceptible to brute force login methods.** as @nichwall noted, this appears to have broken in v2.6.0 with OIDC implementation. related issue: #2533 no auth log entries. ### Steps to reproduce the issue 1. Submit incorrect password as many times as you like. 2. Login with your normal password immediately afterward without being locked out. ### Audiobookshelf version V2.7.2 ### How are you running audiobookshelf? Docker
adam added the bug label 2026-04-24 23:55:40 +02:00
Author
Owner

@Sapd commented on GitHub (Feb 4, 2024):

Probably was removed during the Auth/passport rerwite.

I think instead of implementing that directly, better would be a middleware:
https://www.npmjs.com/package/express-slow-down

Advantage is, it could be also used against other public API endpoints.

Also one should be able to turn it off. Some people like to user other means. Also some don't forward the Client IPs from their reverse proxies (which is at some architectures even by design). If the default suggestion is used it probably it is not needed to be configurable:

windowMs: 5 * 60 * 1000, // 5 minutes
	delayAfter: 5, // Allow 5 requests per 5 minutes.
	delayMs: (hits) => hits * 250

Because this way it does not block completely but adds a delay of 250ms. Should be enough to make every brute force attempt too slow, but still work with other configurations without forwarded IPs.

@Sapd commented on GitHub (Feb 4, 2024): Probably was removed during the Auth/passport rerwite. I think instead of implementing that directly, better would be a middleware: https://www.npmjs.com/package/express-slow-down Advantage is, it could be also used against other public API endpoints. ~Also one should be able to turn it off. Some people like to user other means. Also some don't forward the Client IPs from their reverse proxies (which is at some architectures even by design).~ If the default suggestion is used it probably it is not needed to be configurable: ``` windowMs: 5 * 60 * 1000, // 5 minutes delayAfter: 5, // Allow 5 requests per 5 minutes. delayMs: (hits) => hits * 250 ``` Because this way it does not block completely but adds a delay of 250ms. Should be enough to make every brute force attempt too slow, but still work with other configurations without forwarded IPs.
Author
Owner

@bytebone commented on GitHub (Feb 6, 2024):

No need to solve problems the complicated way. Just fix the logging component so that IPs of unsuccessful login attempts are in logfiles, and let users figure out how to handle this with fail2ban / crowdsec / whatever else.

I would much rather ban IPs that are consistently trying to bruteforce usernames / passwords, than allowing them to slowly but surely chip away at the login form.

@bytebone commented on GitHub (Feb 6, 2024): No need to solve problems the complicated way. Just fix the logging component so that IPs of unsuccessful login attempts are in logfiles, and let users figure out how to handle this with fail2ban / crowdsec / whatever else. I would much rather ban IPs that are consistently trying to bruteforce usernames / passwords, than allowing them to slowly but surely chip away at the login form.
Author
Owner

@plague-doctor commented on GitHub (Nov 14, 2024):

To enhance our security posture against brute-force attacks, I've integrated AudiobookShelf with crowdsec . This addition specifically addresses the challenge of protecting against unauthorised access attempts through repeated login failures.

The AudiobookShelf collection now actively monitors and mitigates potential threats, ensuring a more robust defence against malicious actors attempting to gain unauthorised access to our systems through brute-force methods.

@plague-doctor commented on GitHub (Nov 14, 2024): To enhance our security posture against brute-force attacks, I've integrated AudiobookShelf with [crowdsec](https://www.crowdsec.net) . This addition specifically addresses the challenge of protecting against unauthorised access attempts through repeated login failures. The AudiobookShelf [collection](https://app.crowdsec.net/hub/author/plague-doctor/collections/audiobookshelf) now actively monitors and mitigates potential threats, ensuring a more robust defence against malicious actors attempting to gain unauthorised access to our systems through brute-force methods.
Author
Owner

@Guruleenyc commented on GitHub (Apr 10, 2025):

Has anyone got fail2ban jail and filter working for audiobookshelf yet?

@Guruleenyc commented on GitHub (Apr 10, 2025): Has anyone got fail2ban jail and filter working for audiobookshelf yet?
Author
Owner

@sevenlayercookie commented on GitHub (Apr 10, 2025):

Has anyone got fail2ban jail and filter working for audiobookshelf yet?

I ended going for crowdsec because it's more sophisticated. It was complicated to set up because I use Cloudflare tunnels so Linux firewall doesn't apply. So I ended up setting crowdsec to parse my Caddy logs for Audiobookshelf subdomain for suspicious traffic and then crowdsec tells
Caddy to block further traffic from that IP address.

I haven't used fail2ban, but I imagine that aspect of setup is similar.

@sevenlayercookie commented on GitHub (Apr 10, 2025): > Has anyone got fail2ban jail and filter working for audiobookshelf yet? I ended going for crowdsec because it's more sophisticated. It was complicated to set up because I use Cloudflare tunnels so Linux firewall doesn't apply. So I ended up setting crowdsec to parse my Caddy logs for Audiobookshelf subdomain for suspicious traffic and then crowdsec tells Caddy to block further traffic from that IP address. I haven't used fail2ban, but I imagine that aspect of setup is similar.
Author
Owner

@CTalvio commented on GitHub (Jul 2, 2025):

@Guruleenyc

Setting up fail2ban to watch any arbitrary log file is not difficult. You can find fairly simple guides for how to set up custom jails. If you have access to the log, and a regex string that matches with log entries for failed logins, you're set. Here's the filter I wrote for my system just now:

# Filter for audiobookshelf 
[Definition]
failregex = ^.*\[Auth\] Failed login attempt for username \\".*\\" from ip <HOST> \(.*\)

If you need to create one in the future, you can do that by doing a few incorrect logins yourself, then finding them in the log. Copy that section of the log into a regex tester like this one and tweak your way to a regex string that will match with a failed login line. Replace the the section of the line with the ip with <HOST> and you have a failregex for fail2ban.

@CTalvio commented on GitHub (Jul 2, 2025): @Guruleenyc Setting up fail2ban to watch any arbitrary log file is not difficult. You can find fairly simple guides for how to set up custom jails. If you have access to the log, and a regex string that matches with log entries for failed logins, you're set. Here's the filter I wrote for my system just now: ``` # Filter for audiobookshelf [Definition] failregex = ^.*\[Auth\] Failed login attempt for username \\".*\\" from ip <HOST> \(.*\) ``` If you need to create one in the future, you can do that by doing a few incorrect logins yourself, then finding them in the log. Copy that section of the log into a regex tester like [this one](regexr.com) and tweak your way to a regex string that will match with a failed login line. Replace the the section of the line with the ip with `<HOST>` and you have a failregex for fail2ban.
Author
Owner

@plague-doctor commented on GitHub (Jul 16, 2025):

@advplyr
The latest version introduced a new logging mechanism, which also altered how authentication-related issues are logged. Instead of the original "[Auth] ..." prefix, it now uses "[LocalAuth] ..." in the log files.

Could we please revert to using "[Auth]" again? Many of us rely on tools like fail2ban or Crowdsec, which depend on specific log patterns to detect and block brute-force attacks. The current change is causing these systems to fail silently, as they can no longer recognise the log entries.

This is a minor adjustment that would restore compatibility with existing security mechanisms. Without reverting, all currently configured tools would effectively stop working, leaving our systems vulnerable.

@plague-doctor commented on GitHub (Jul 16, 2025): @advplyr The latest version introduced a new logging mechanism, which also altered how authentication-related issues are logged. Instead of the original "[Auth] ..." prefix, it now uses "[LocalAuth] ..." in the log files. Could we please revert to using "[Auth]" again? Many of us rely on tools like fail2ban or Crowdsec, which depend on specific log patterns to detect and block brute-force attacks. The current change is causing these systems to fail silently, as they can no longer recognise the log entries. This is a minor adjustment that would restore compatibility with existing security mechanisms. Without reverting, all currently configured tools would effectively stop working, leaving our systems vulnerable.
Author
Owner

@DerLeole commented on GitHub (Jan 26, 2026):

Has anything been done regarding @plague-doctor 's last message?

As far as I can see, the lastest version of the audiobookshelf parser on crowdsec still uses the [Auth] notation, while the lastest version of audiobookshelf still uses [LocalAuth]?

Is that change permanent @advplyr ? Then an update to the crowdsec parser might be in order?

@DerLeole commented on GitHub (Jan 26, 2026): Has anything been done regarding @plague-doctor 's last message? As far as I can see, the lastest version of the audiobookshelf parser on crowdsec still uses the [Auth] notation, while the lastest version of audiobookshelf still uses [LocalAuth]? Is that change permanent @advplyr ? Then an update to the crowdsec parser might be in order?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/audiobookshelf#1709