mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-02-07 20:03:33 -05:00
If a user chooses a very common password then an attacker could guess it in relatively few attempts, circumventing the lockout. CESG recommend blacklisting the most common passwords: > …enforcing the requirement for complex character sets in passwords is > not recommended. Instead, concentrate efforts on technical controls, > especially: > > - defending against automated guessing attacks by either using account > lockout, throttling, or protective monitoring > - blacklisting the most common password choices How I made this list: - went to the OWASP repository of security lists: https://github.com/danielmiessler/SecLists - downloaded `10k_most_common.txt`, `twitter-banned.txt` and `500-worst-passwords.txt` - filtered out any under 8 characters: ``` sed -r '/^.{,7}$/d' passwords-twitter.txt > passwords-combined.txt sed -r '/^.{,7}$/d' passwords-500.txt >> passwords-combined.txt sed -r '/^.{,7}$/d' passwords.txt >> passwords-combined.txt ``` - filtered out any duplicates: ``` cat passwords-combined.txt | awk '!x[$0]++' > passwords-combined-deduped.txt ```
51 lines
1.7 KiB
Python
51 lines
1.7 KiB
Python
import re
|
||
from wtforms import ValidationError
|
||
from notifications_utils.template import Template
|
||
from app.utils import Spreadsheet
|
||
from ._blacklisted_passwords import blacklisted_passwords
|
||
|
||
|
||
class Blacklist(object):
|
||
def __init__(self, message=None):
|
||
if not message:
|
||
message = 'Password is blacklisted.'
|
||
self.message = message
|
||
|
||
def __call__(self, form, field):
|
||
if field.data in blacklisted_passwords:
|
||
raise ValidationError(self.message)
|
||
|
||
|
||
class CsvFileValidator(object):
|
||
|
||
def __init__(self, message='Not a csv file'):
|
||
self.message = message
|
||
|
||
def __call__(self, form, field):
|
||
if not Spreadsheet.can_handle(field.data.filename):
|
||
raise ValidationError("{} isn’t a spreadsheet that Notify can read".format(field.data.filename))
|
||
|
||
|
||
class ValidEmailDomainRegex(object):
|
||
|
||
def __call__(self, form, field):
|
||
from flask import (current_app, url_for)
|
||
message = (
|
||
'Enter a central government email address.'
|
||
' If you think you should have access'
|
||
' <a href="{}">contact us</a>').format(url_for('main.feedback'))
|
||
valid_domains = current_app.config.get('EMAIL_DOMAIN_REGEXES', [])
|
||
email_regex = "[^\@^\s]+@([^@^\\.^\\s]+\.)*({})$".format("|".join(valid_domains))
|
||
if not re.match(email_regex, field.data.lower()):
|
||
raise ValidationError(message)
|
||
|
||
|
||
class NoCommasInPlaceHolders():
|
||
|
||
def __init__(self, message='You can’t have commas in your fields'):
|
||
self.message = message
|
||
|
||
def __call__(self, form, field):
|
||
if ',' in ''.join(Template({'content': field.data}).placeholders):
|
||
raise ValidationError(self.message)
|