aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authorWilliam Hergès <william@herges.fr>2026-01-02 19:02:15 +0100
committerWilliam Hergès <william@herges.fr>2026-01-02 19:02:15 +0100
commit7f4bd0e1620cf1c5c66ef30f8c44d2d5adc659ee (patch)
tree8cd3e79b9304b76c37b12f2d65b1451c700e33ad /backend
parent7d4ec713ba76d7e787c9d787a38a96b81daf52dc (diff)
feat(backend): rate limit dumb attacker bot
Diffstat (limited to 'backend')
-rw-r--r--backend/data.go3
-rw-r--r--backend/router.go33
-rw-r--r--backend/storage/stats.go8
3 files changed, 36 insertions, 8 deletions
diff --git a/backend/data.go b/backend/data.go
index 3a8acf0..f7ba3b1 100644
--- a/backend/data.go
+++ b/backend/data.go
@@ -69,9 +69,6 @@ func (d *data) merge(cfg *Config, r *http.Request) {
d.Image = cfg.DefaultImage
}
if d.URL == "" {
- if !strings.HasPrefix(r.URL.Path, "/") {
- r.URL.Path = "/" + r.URL.Path
- }
d.URL = r.URL.Path
}
if d.Language == "" {
diff --git a/backend/router.go b/backend/router.go
index f4b5763..48ffe0a 100644
--- a/backend/router.go
+++ b/backend/router.go
@@ -12,6 +12,7 @@ import (
"net/http"
"os"
"path"
+ "regexp"
"strings"
"time"
@@ -89,6 +90,12 @@ func NewRouter(debug bool, cfg *Config, db *sql.DB, assets fs.FS) *chi.Mux {
}
r.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ if !strings.HasPrefix(r.RequestURI, "/") {
+ r.RequestURI = "/" + r.RequestURI
+ }
+ if !strings.HasPrefix(r.URL.Path, "/") {
+ r.URL.Path = "/" + r.URL.Path
+ }
next.ServeHTTP(w, r.WithContext(
setContext(r.Context(), r),
))
@@ -146,8 +153,21 @@ func NewRouter(debug bool, cfg *Config, db *sql.DB, assets fs.FS) *chi.Mux {
}(r.Context(), r)
})
})
+ // anti dumb attackers bot
+ phpUri := regexp.MustCompile(`/.+\.php(/.*)?`)
+ dotUri := regexp.MustCompile(`/(.*/)*\..*`)
+ r.Use(func(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ if phpUri.MatchString(r.RequestURI) || dotUri.MatchString(r.RequestURI) {
+ handleSus(w, r)
+ return
+ }
+ next.ServeHTTP(w, r)
+ })
+ })
- r.HandleFunc("/{file:[a-z]+}.txt", func(w http.ResponseWriter, r *http.Request) {
+ // txt files
+ r.Get("/{file:[a-z]+}.txt", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
cfg := ctx.Value(configKey).(*Config)
logger := GetLogger(ctx)
@@ -168,6 +188,17 @@ func NewRouter(debug bool, cfg *Config, db *sql.DB, assets fs.FS) *chi.Mux {
return r
}
+func handleSus(w http.ResponseWriter, r *http.Request) {
+ ctx := r.Context()
+ logger := GetLogger(ctx)
+ logger.Warn("sus request", "User-Agent", r.Header.Get("User-Agent"))
+ if rateLimit(ctx) {
+ http.Error(w, "Too many requests", http.StatusTooManyRequests)
+ return
+ }
+ notFound(w, r)
+}
+
// httpEmbedFS is an implementation of fs.FS, fs.ReadDirFS and fs.ReadFileFS helping to manage embed.FS for http server
type httpEmbedFS struct {
embed.FS
diff --git a/backend/storage/stats.go b/backend/storage/stats.go
index 345164e..f40c060 100644
--- a/backend/storage/stats.go
+++ b/backend/storage/stats.go
@@ -57,14 +57,11 @@ const HumanPageLoad = "/assets/styles.css"
func UpdateStats(ctx context.Context, r *http.Request, domain string) error {
target := r.URL.Path
- if !strings.HasPrefix(target, "/") {
- target = "/" + target
- }
if strings.HasPrefix(target, "/admin") {
return nil
}
ref := r.Header.Get("Referer")
- if ref == "" {
+ if len(ref) == 0 {
return nil
}
refUrl, err := url.Parse(ref)
@@ -72,6 +69,9 @@ func UpdateStats(ctx context.Context, r *http.Request, domain string) error {
return nil
}
ref = refUrl.Host
+ if len(ref) == 0 {
+ return nil
+ }
if ref == domain || ref == fmt.Sprintf("localhost:%d", 8000) {
ref = refUrl.Path
if !strings.HasPrefix(ref, "/") {