Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ services:
--providers.docker=true
--providers.docker.network=default
--experimental.plugins.captcha-protect.modulename=github.com/libops/captcha-protect
--experimental.plugins.captcha-protect.version=v1.12.4
--experimental.plugins.captcha-protect.version=v1.12.5
volumes:
- /var/run/docker.sock:/var/run/docker.sock:z
- /CHANGEME/TO/A/HOST/PATH/FOR/STATE/FILE:/tmp/state.json:rw
Expand Down Expand Up @@ -130,7 +130,7 @@ services:
| `protectFileExtensions` | `[]string` | `""` | Comma-separated file extensions to protect. By default, your protected routes only protect html files. This is to prevent files like CSS/JS/img from tripping the rate limit. |
| `protectHttpMethods` | `[]string` | `"GET,HEAD"` | Comma-separated list of HTTP methods to protect against |
| `exemptIps` | `[]string` | `privateIPs` | CIDR-formatted IPs that should never be challenged. Private IP ranges are always exempt. |
| `exemptUserAgents` | `[]string` | `""` | Comma-separated list of case-insensitive user agent **prefixes** to never challenge. e.g. `exemptUserAgents: edge` would never challenge useragents like "Edge/12.4 ..." |
| `exemptUserAgents` | `[]string` | `""` | Comma-separated list of case-insensitive user agent substrings to never challenge. For example, `exemptUserAgents: YandexBot` exempts user agents containing `YandexBot`. |
| `challengeURL` | `string` | `"/challenge"` | URL where challenges are served. This will override existing routes if there is a conflict. Setting to blank will have the challenge presented on the same page that tripped the rate limit. |
| `challengeTmpl` | `string` | `"./challenge.tmpl.html"`| Path to the Go HTML template for the captcha challenge page. |
| `challengeStatusCode` | `int` | `200` | HTTP Response status code to return when serving a challenge |
Expand Down
4 changes: 2 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -858,8 +858,8 @@ protected:

func (bc *CaptchaProtect) isGoodUserAgent(ua string) bool {
ua = strings.ToLower(ua)
for _, agentPrefix := range bc.config.ExemptUserAgents {
if strings.HasPrefix(ua, agentPrefix) {
for _, agentSubstring := range bc.config.ExemptUserAgents {
if strings.Contains(ua, agentSubstring) {
return true
}
}
Expand Down
7 changes: 4 additions & 3 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -615,10 +615,11 @@ func TestIsGoodUserAgent(t *testing.T) {
ua string
expected bool
}{
{"Matching first prefix", []string{"Mozilla", "Google"}, "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", true},
{"Matching second prefix", []string{"Bing", "Edge"}, "Edge/12.0", true},
{"Matching first substring", []string{"Mozilla", "Google"}, "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", true},
{"Matching second substring", []string{"Bing", "Edge"}, "Edge/12.0", true},
{"Matching substring within user agent", []string{"YandexBot"}, "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)", true},
{"Case insensitive", []string{"bing", "Edge"}, "BING/12.0", true},
{"No matching prefix", []string{"Mozilla", "Google"}, "Safari/537.36", false},
{"No matching substring", []string{"Mozilla", "Google"}, "Safari/537.36", false},
{"Empty user agent", []string{"Mozilla", "Google"}, "", false},
{"Empty exempt list", []string{}, "Mozilla/5.0", false},
}
Expand Down