2022-12-31 10:22:38 +01:00
|
|
|
package security
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2024-01-02 09:48:34 +01:00
|
|
|
"net/http"
|
|
|
|
"time"
|
|
|
|
|
2022-12-31 10:22:38 +01:00
|
|
|
"github.com/gin-gonic/gin"
|
2023-01-30 19:59:42 +01:00
|
|
|
"github.com/twofas/2fas-server/internal/common/logging"
|
|
|
|
"github.com/twofas/2fas-server/internal/common/rate_limit"
|
2022-12-31 10:22:38 +01:00
|
|
|
)
|
|
|
|
|
2024-01-02 09:48:34 +01:00
|
|
|
const defaultAPIBandwidthAbuseThreshold = 100
|
2022-12-31 10:22:38 +01:00
|
|
|
|
2024-01-02 09:48:34 +01:00
|
|
|
func IPAbuseAuditMiddleware(rateLimiter rate_limit.RateLimiter, rateLimitValue int) gin.HandlerFunc {
|
2022-12-31 10:22:38 +01:00
|
|
|
return func(c *gin.Context) {
|
|
|
|
clientIp := c.ClientIP()
|
|
|
|
|
|
|
|
key := fmt.Sprintf("security.api.ip_bandwidth_audit.%s", clientIp)
|
|
|
|
|
2024-01-02 09:48:34 +01:00
|
|
|
limitValue := rateLimitValue
|
|
|
|
if limitValue == 0 {
|
|
|
|
limitValue = defaultAPIBandwidthAbuseThreshold
|
|
|
|
}
|
2022-12-31 10:22:38 +01:00
|
|
|
rate := rate_limit.Rate{
|
|
|
|
TimeUnit: time.Minute,
|
2024-01-02 09:48:34 +01:00
|
|
|
Limit: limitValue,
|
2022-12-31 10:22:38 +01:00
|
|
|
}
|
|
|
|
|
2024-01-02 09:48:34 +01:00
|
|
|
limitReached := rateLimiter.Test(c, key, rate)
|
2022-12-31 10:22:38 +01:00
|
|
|
|
|
|
|
if limitReached {
|
|
|
|
logging.WithFields(logging.Fields{
|
|
|
|
"type": "security",
|
|
|
|
"uri": c.Request.URL.String(),
|
|
|
|
"ip": c.ClientIP(),
|
2024-01-02 09:48:34 +01:00
|
|
|
}).Warning("API potentially abused by Client IP, blocking")
|
|
|
|
c.AbortWithStatus(http.StatusTooManyRequests)
|
2022-12-31 10:22:38 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|