webrtc, hls: prevent brute-force attacks by waiting before sending responses (#2100)

This commit is contained in:
Alessandro Ros 2023-07-23 20:18:58 +02:00 committed by GitHub
parent 0137734294
commit 1fa53b49d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 29 additions and 5 deletions

View File

@ -7,6 +7,7 @@ import (
"net/http"
gopath "path"
"strings"
"time"
"github.com/gin-gonic/gin"
@ -14,6 +15,10 @@ import (
"github.com/bluenviron/mediamtx/internal/logger"
)
const (
hlsPauseAfterAuthError = 2 * time.Second
)
//go:embed hls_index.html
var hlsIndex []byte
@ -166,6 +171,10 @@ func (s *hlsHTTPServer) onRequest(ctx *gin.Context) {
remoteAddr := net.JoinHostPort(ip, port)
s.Log(logger.Info, "connection %v failed to authenticate: %v", remoteAddr, terr.message)
// wait some seconds to stop brute force attacks
<-time.After(hlsPauseAfterAuthError)
ctx.Writer.WriteHeader(http.StatusUnauthorized)
return
}

View File

@ -30,7 +30,7 @@ import (
)
const (
rtmpConnPauseAfterAuthError = 2 * time.Second
rtmpPauseAfterAuthError = 2 * time.Second
)
func pathNameAndQuery(inURL *url.URL) (string, url.Values, string) {
@ -367,7 +367,7 @@ func (c *rtmpConn) runRead(ctx context.Context, u *url.URL) error {
if res.err != nil {
if terr, ok := res.err.(*errAuthentication); ok {
// wait some seconds to stop brute force attacks
<-time.After(rtmpConnPauseAfterAuthError)
<-time.After(rtmpPauseAfterAuthError)
return terr
}
return res.err
@ -782,7 +782,7 @@ func (c *rtmpConn) runPublish(u *url.URL) error {
if res.err != nil {
if terr, ok := res.err.(*errAuthentication); ok {
// wait some seconds to stop brute force attacks
<-time.After(rtmpConnPauseAfterAuthError)
<-time.After(rtmpPauseAfterAuthError)
return terr
}
return res.err

View File

@ -17,7 +17,7 @@ import (
)
const (
rtspConnPauseAfterAuthError = 2 * time.Second
rtspPauseAfterAuthError = 2 * time.Second
)
type rtspConnParent interface {
@ -204,7 +204,7 @@ func (c *rtspConn) handleAuthError(authErr error) (*base.Response, error) {
}
// wait some seconds to stop brute force attacks
<-time.After(rtspConnPauseAfterAuthError)
<-time.After(rtspPauseAfterAuthError)
return &base.Response{
StatusCode: base.StatusUnauthorized,

View File

@ -10,6 +10,7 @@ import (
"regexp"
"strconv"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
@ -318,6 +319,10 @@ func (s *webRTCHTTPServer) onRequest(ctx *gin.Context) {
}
s.Log(logger.Info, "connection %v failed to authenticate: %v", remoteAddr, terr.message)
// wait some seconds to stop brute force attacks
<-time.After(webrtcPauseAfterAuthError)
ctx.Writer.WriteHeader(http.StatusUnauthorized)
return
}

View File

@ -23,6 +23,7 @@ import (
)
const (
webrtcPauseAfterAuthError = 2 * time.Second
webrtcHandshakeTimeout = 10 * time.Second
webrtcTrackGatherTimeout = 2 * time.Second
webrtcPayloadMaxSize = 1188 // 1200 - 12 (RTP header)

View File

@ -240,8 +240,12 @@ func (s *webRTCSession) runPublish() (int, error) {
})
if res.err != nil {
if _, ok := res.err.(*errAuthentication); ok {
// wait some seconds to stop brute force attacks
<-time.After(webrtcPauseAfterAuthError)
return http.StatusUnauthorized, res.err
}
return http.StatusBadRequest, res.err
}
@ -363,11 +367,16 @@ func (s *webRTCSession) runRead() (int, error) {
})
if res.err != nil {
if _, ok := res.err.(*errAuthentication); ok {
// wait some seconds to stop brute force attacks
<-time.After(webrtcPauseAfterAuthError)
return http.StatusUnauthorized, res.err
}
if strings.HasPrefix(res.err.Error(), "no one is publishing") {
return http.StatusNotFound, res.err
}
return http.StatusBadRequest, res.err
}