authelia/internal/middlewares/timing_attack_delay_test.go
James Elliott 9a8c6602dd
fix(middlewares): smart delay on reset password (#2767)
This adds a smart delay on reset password attempts to prevent username enumeration. Additionally utilizes crypto rand instead of math rand. It also moves the timing delay functionality into its own handler func.
2022-01-21 10:46:13 +11:00

66 lines
2.2 KiB
Go

package middlewares
import (
"sync"
"testing"
"time"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/authelia/authelia/v4/internal/logging"
)
func TestTimingAttackDelayAverages(t *testing.T) {
execDuration := time.Millisecond * 500
oneSecond := time.Millisecond * 1000
durations := []time.Duration{oneSecond, oneSecond, oneSecond, oneSecond, oneSecond, oneSecond, oneSecond, oneSecond, oneSecond, oneSecond}
cursor := 0
mutex := &sync.Mutex{}
avgExecDuration := movingAverageIteration(execDuration, 10, false, &cursor, &durations, mutex)
assert.Equal(t, avgExecDuration, float64(1000))
execDurations := []time.Duration{
time.Millisecond * 500, time.Millisecond * 500, time.Millisecond * 500, time.Millisecond * 500,
time.Millisecond * 500, time.Millisecond * 500, time.Millisecond * 500, time.Millisecond * 500,
time.Millisecond * 500, time.Millisecond * 500, time.Millisecond * 500, time.Millisecond * 500,
}
current := float64(1000)
// Execute at 500ms for 12 requests.
for _, execDuration = range execDurations {
avgExecDuration = movingAverageIteration(execDuration, 10, true, &cursor, &durations, mutex)
assert.Equal(t, avgExecDuration, current)
// Should not dip below 500, and should decrease in value by 50 each iteration.
if current > 500 {
current -= 50
}
}
}
func TestTimingAttackDelayCalculations(t *testing.T) {
execDuration := 500 * time.Millisecond
avgExecDurationMs := 1000.0
expectedMinimumDelayMs := avgExecDurationMs - float64(execDuration.Milliseconds())
logger := logging.Logger().WithFields(logrus.Fields{})
for i := 0; i < 100; i++ {
delay := calculateActualDelay(logger, execDuration, avgExecDurationMs, 250, 85, false)
assert.True(t, delay >= expectedMinimumDelayMs)
assert.True(t, delay <= expectedMinimumDelayMs+float64(85))
}
execDuration = 5 * time.Millisecond
avgExecDurationMs = 5.0
expectedMinimumDelayMs = 250 - float64(execDuration.Milliseconds())
for i := 0; i < 100; i++ {
delay := calculateActualDelay(logger, execDuration, avgExecDurationMs, 250, 85, false)
assert.True(t, delay >= expectedMinimumDelayMs)
assert.True(t, delay <= expectedMinimumDelayMs+float64(250))
}
}