Move authentication delay into __init__.py and add config
Use the delay for all backends (not only htpasswd). Add configuration option to configure the delay.
This commit is contained in:
parent
fb970246e0
commit
f2fb07fa84
3
config
3
config
@ -78,6 +78,9 @@
|
|||||||
# bcrypt and md5 require the passlib library to be installed.
|
# bcrypt and md5 require the passlib library to be installed.
|
||||||
#htpasswd_encryption = bcrypt
|
#htpasswd_encryption = bcrypt
|
||||||
|
|
||||||
|
# Incorrect authentication delay (seconds)
|
||||||
|
#delay = 1
|
||||||
|
|
||||||
|
|
||||||
[rights]
|
[rights]
|
||||||
|
|
||||||
|
@ -34,11 +34,13 @@ import itertools
|
|||||||
import os
|
import os
|
||||||
import posixpath
|
import posixpath
|
||||||
import pprint
|
import pprint
|
||||||
|
import random
|
||||||
import socket
|
import socket
|
||||||
import socketserver
|
import socketserver
|
||||||
import ssl
|
import ssl
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
import wsgiref.simple_server
|
import wsgiref.simple_server
|
||||||
import zlib
|
import zlib
|
||||||
@ -383,6 +385,13 @@ class Application:
|
|||||||
is_authenticated = False
|
is_authenticated = False
|
||||||
else:
|
else:
|
||||||
is_authenticated = self.Auth.is_authenticated(user, password)
|
is_authenticated = self.Auth.is_authenticated(user, password)
|
||||||
|
if not is_authenticated:
|
||||||
|
# Random delay to avoid timing oracles and bruteforce attacks
|
||||||
|
delay = self.configuration.getfloat("auth", "delay")
|
||||||
|
if delay > 0:
|
||||||
|
random_delay = delay * (0.5 + random.random())
|
||||||
|
self.logger.debug("Sleeping %.3f seconds", random_delay)
|
||||||
|
time.sleep(random_delay)
|
||||||
|
|
||||||
# Create principal collection
|
# Create principal collection
|
||||||
if user and is_authenticated:
|
if user and is_authenticated:
|
||||||
|
@ -58,8 +58,6 @@ import functools
|
|||||||
import hashlib
|
import hashlib
|
||||||
import hmac
|
import hmac
|
||||||
import os
|
import os
|
||||||
import random
|
|
||||||
import time
|
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
|
|
||||||
|
|
||||||
@ -198,6 +196,4 @@ class Auth(BaseAuth):
|
|||||||
login, hash_value = line.split(":")
|
login, hash_value = line.split(":")
|
||||||
if login == user and self.verify(hash_value, password):
|
if login == user and self.verify(hash_value, password):
|
||||||
return True
|
return True
|
||||||
# Random timer to avoid timing oracles and simple bruteforce attacks
|
|
||||||
time.sleep(1 + random.random())
|
|
||||||
return False
|
return False
|
||||||
|
@ -93,7 +93,10 @@ INITIAL_CONFIG = OrderedDict([
|
|||||||
"help": "htpasswd filename"}),
|
"help": "htpasswd filename"}),
|
||||||
("htpasswd_encryption", {
|
("htpasswd_encryption", {
|
||||||
"value": "bcrypt",
|
"value": "bcrypt",
|
||||||
"help": "htpasswd encryption method"})])),
|
"help": "htpasswd encryption method"}),
|
||||||
|
("delay", {
|
||||||
|
"value": "1",
|
||||||
|
"help": "incorrect authentication delay"})])),
|
||||||
("rights", OrderedDict([
|
("rights", OrderedDict([
|
||||||
("type", {
|
("type", {
|
||||||
"value": "owner_only",
|
"value": "owner_only",
|
||||||
|
@ -47,6 +47,8 @@ class TestBaseAuthRequests(BaseTest):
|
|||||||
self.configuration.set("storage", "filesystem_fsync", "False")
|
self.configuration.set("storage", "filesystem_fsync", "False")
|
||||||
# Required on Windows, doesn't matter on Unix
|
# Required on Windows, doesn't matter on Unix
|
||||||
self.configuration.set("storage", "close_lock_file", "True")
|
self.configuration.set("storage", "close_lock_file", "True")
|
||||||
|
# Set incorrect authentication delay to a very low value
|
||||||
|
self.configuration.set("auth", "delay", "0.002")
|
||||||
|
|
||||||
def teardown(self):
|
def teardown(self):
|
||||||
shutil.rmtree(self.colpath)
|
shutil.rmtree(self.colpath)
|
||||||
|
Loading…
Reference in New Issue
Block a user