bunkerity / bunkerity/bunkerweb
[BUG] Unban does not reset badbehavior counters, causing immediate re-ban on next matching status code
- Dominant language
- Python
- Stars
- 11k
- Forks
- 642
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 42
Description
### What happened?
Manually unbanning an IP via bwcli unban removes the active ban, but leaves the badbehavior plugin's underlying Redis counter (plugin_bad_behavior_) completely untouched at its pre-unban value. If that value is still at or above BAD_BEHAVIOR_THRESHOLD, the very next request matching BAD_BEHAVIOR_STATUS_CODES from that IP re-triggers an immediate ban, with no new accumulation of bad behavior required.
An explicit operator action to unban an IP should reset that IP's abuse-tracking state entirely, not just remove the resulting ban. As it stands, unban only removes the symptom (the ban) while leaving the cause (the counter) fully intact, so an IP can be unbanned and re-banned on its very next request.
### How to reproduce?
1. Confirm clean state: redis-cli GET plugin_bad_behavior_ returns (nil).
2. Generate real traffic matching a status code in BAD_BEHAVIOR_STATUS_CODES (401 in this case) until BAD_BEHAVIOR_THRESHOLD is reached and the IP is banned. Confirmed via error.log:
[BADBEHAVIOR] increased counter for IP (5/5) on server (status 401, scope global)
[BADBEHAVIOR] IP is banned for 1209600s (5/5) on server with scope global
3. Confirm counter value directly: redis-cli GET plugin_bad_behavior_ returns "5".
4. Run bwcli unban . Command reports success and the ban is lifted.
5. Immediately check the counter again: redis-cli GET plugin_bad_behavior_ still returns "5", unchanged.
6. Because the counter was never reset, only a single additional matching status code is needed to re-trigger the ban, not a fresh pattern of BAD_BEHAVIOR_THRESHOLD occurrences. One more request increments the counter past threshold and the IP is immediately re-banned:
[BADBEHAVIOR] increased counter for IP (6/5) on server (status 401, scope global)
[BADBEHAVIOR] IP is banned for 1209600s (6/5) on server with scope global
7. Confirmed via redis-cli GET plugin_bad_behavior_, now "6".
This is reproducible with any IP or service, not specific to a particular address, service, or network.
**Expected behavior**
bwcli unban should delete or zero the associated plugin_bad_behavior_ counter (and its metrics:badbehavior_* companions) in the same operation that removes the ban itself, so the IP's abuse-tracking state is genuinely cleared rather than persisting past an explicit operator unban.
As demonstrated above, the counter was completely unaffected by unban, it remained at the same value that had triggered the original ban. Because of this, re-banning did not require a fresh pattern of BAD_BEHAVIOR_THRESHOLD occurrences, a single additional matching status code was sufficient on its own to cross the (already-at-threshold) counter and trigger an immediate re-ban. This defeats the purpose of an explicit operator unban: the IP is nominally unbanned but is, in practice, still one ordinary request away from being banned again.
### Configuration file(s) (yaml or .env)
```YAML
USE_BAD_BEHAVIOR=yes
BAD_BEHAVIOR_STATUS_CODES=401 403 405 429 444
BAD_BEHAVIOR_THRESHOLD=5
BAD_BEHAVIOR_COUNT_TIME=21600
BAD_BEHAVIOR_BAN_TIME=1209600
USE_REDIS=yes
```
### Relevant log output
```shell
Clean state confirmed:
127.0.0.1:6379> GET plugin_bad_behavior_
(nil)
Counter climbing to threshold, IP banned:
[BADBEHAVIOR] increased counter for IP (5/5) on server (status 401, scope global), context: ngx.timer
[BADBEHAVIOR] IP is banned for 1209600s (5/5) on server with scope global, context: ngx.timer
Counter value confirmed before unban:
127.0.0.1:6379> GET plugin_bad_behavior_
"5"
Unban command run:
$ bwcli unban
✅ SUCCESS
IP has been unbanned globally
Counter value immediately after unban, unchanged:
127.0.0.1:6379> GET plugin_bad_behavior_
"5"
Next matching request after unban immediately re-bans:
[BADBEHAVIOR] increased counter for IP (6/5) on server (status 401, scope global), context: ngx.timer
[BADBEHAVIOR] IP is banned for 1209600s (6/5) on server with scope global, context: ngx.timer
Confirmed again directly:
127.0.0.1:6379> GET plugin_bad_behavior_
"6"
```
### BunkerWeb version
1.6.13
### What integration are you using?
Linux
### Linux distribution (if applicable)
Ubuntu 24.04
### Removed private data
- [x] I have removed all private data from the configuration file and the logs
### Code of Conduct
- [x] I agree to follow this project's Code of Conduct
Contributor guide
Assessment
This issue has not been assessed yet.