view on full screen for the full gloryness
//////// //////// ////////// //////////// //////// /// ////////////// ////////////// ////// //////// ///////// ////// ////////// ////////
// // // // // // // // // // // // // // // // // // // // // // // // ///
////// //////// // // // ////// //////// //////// // // // // // // // // // // //// ///// // // //
// // // // // // // // // // // // // // // // // // // // // // // // // //
// // // ////////// //////////// // // // // // // // // // // ////// // // //////// // ////////// //
/////// // // /////// /////// //////// //////// /////// /////// // // //////// ////// //////// // //
// // // // // // // // // // // // // // // // // // //
// ///// /////// /////// //////// /////// /////// // // // //////// // // /////
// // // // // // // // // // // // // // // // //
//////// // /////// /////// // // /////// /////// //////// //////// // // ////// // //
This is my first attempt at ever making a program and was for my university course
The code is not the cleanest or the simplest it could be for now
Gettings started:
#setup a virtual environment(recommended)
python -m venv venv
#install dependencies
pip install PySide6 argon2-cffi cryptography zxcvbn pyotp qrcode[pil]
#run
Open the folder in your IDE
open secure password system.py file
run secure password system.py file
If the images do not load make sure you're running from within the working directory
#end of setup
#####################################################################
the program creates 3 files:
authentication
integrity
logs.db
1. authentication is a sqlite file and contains all user data
|- auth contains password, recover, masterkey, totp hashes and salts per user
|- customer data contains date of birth, home address and so on per user
2. integrity is a txt file which contains a sha256 hash of the database for data integrity verification
3. logs.db is another sqlite file which contains well. . . logs
#####################################################################
language choice and why it is appropriate:
I chose python because it seemed like the easiest to use so I could get into making programme without worrying too much about the underlying language
- memory leaks | python deals with freeing memory for me and use after free errors
- no buffer overflows | python tells me if the programme attempts to write over the allocated memory and stops the programme
- pointers | c has pointers which I found I struggled with casting errors and python just works
- support | python has many many libraries which have been extensively checked to ensure absolute security which i could use to make my life easier
#####################################################################
how I implemented secure programming techniques:
I followed the standards
I followed the documentation
password hashing:
I ended up using argon2 because its the most modern most capable hashing algorithm
for password hashing and salting:
https://argon2-cffi.readthedocs.io/en/stable/
https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
| I followed the best practice found here
|---https://www.rfc-editor.org/rfc/rfc9106.html
|
|--argon2_OWASP_paramaters = {
| "time_cost": 3,
| "memory_cost": 262144, #256mb for offline safety in the secure login system™️
| "parallelism": 4,
| "hash_len": 32,
| "type": Type.ID
| }
all encryption is done through aes
https://youtu.be/-fpVv_T4xwA
password strength:
force over 8 characters because nist recommends
https://pages.nist.gov/800-63-3/sp800-63b.html
https://datatracker.ietf.org/doc/html/rfc20
password strength estimator: (zxcvbn)
zxcvbn is currently seemingly the most capable, most convenient, open source, open license
https://www.youtube.com/watch?v=vf37jh3dV2I&t=2s
keepass2 password strength estimator is older and less accurate so i did not use
input validation:
https://regex101.com/
help in understanding regex
https://stackoverflow.com/questions/4709652/python-regex-to-match-dates
inactivity sign out:
through the qt timer logic
https://doc.qt.io/qt-6/qtimer.html
qt sqlite
https://doc.qt.io/qt-6/sql-driver.html
all the encrypted blob(binary) data in the databases is stored as hex due to problems in querying blob data in and out
frontend in qt was VERY helpful especially understanding how to hide passwords and clear input boxes
https://doc.qt.io/qtforpython-6/index.html
got cut from the project in the end but did assist in learning the tools
https://www.codestudy.net/blog/regular-expression-to-validate-uk-national-insurance-number/
https://docs.python.org/3/library/dataclasses.html
#####################################################################
vulnerabilities I identified and how I mitigated them.
I encountered many problems with not clearing data and mitigated it by clearing unused variables and input boxes when it's no longer in use and adding logout
I previously just used the password strength estimator (zxcvbn) with no minimum character limit so if the inputted characters was complex enough a user could have a 5 character password which is very easy to be brute forced
had no inactivity sign out so the user would stay logged in even when leaving the computer unattended for a long time and i mitigated by making the logic and setting it to logout after 5 minutes
#####################################################################
Example test cases (including invalid/malicious inputs)
✅ = passed
❌ = failed
sign up page
signup username box:
- attempted to enter a very large string: unable to enter ✅
- attempted to repeatedly paste small amounts of data and it capped at 256 characters ✅
- attempted to enter same password and username and got error: cannot be same ✅
- attempting to enter malicious inputs:
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
print("Matty" + "\x00" + "admin")
was allowed to make user with the malicious inputs but recognised as text not as code + home menu and user change title had the username: print("A" * 32767 + "'; DROP TABLE auth; --") without any injection occurring* turned to lowercase and spaces removed✅
signup password box:
- attempted to enter a very large string: unable to enter ✅
- attempted to repeatedly paste small amounts of data and it capped at 256 characters ✅
- attempting to enter malicious inputs:
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
print("Matty" + "\x00" + "admin")
the malicious inputs were treated as text and allowed as a password✅
signup otp manual key read only box
attempted to put text into box and it did not allow ✅
signup otp enter code box
attempted to enter characters and it refused ✅
attempted to enter special characters and it refused✅
attempted to enter unicode special characters and it refused ✅
attempted to enter sql injection code and it refused✅
attempted to put more than 6 characters in and it refused✅
signup recovery key read only box
attempted to put text into box and it did not allow ✅
clicked edit many many times and found no logs are ever deleted ❌
updated logic files are deleted after 30 days and checked if works ✅
moved on to login page
login username box:
- attempted to enter a very large string: unable to enter ✅
- attempted to repeatedly paste small amounts of data | managed to get 32767 characters (that was quick)❌
- fixed then attempted to repeatedly paste small amounts of data and it capped at 256 characters ✅
- attempting to enter malicious inputs:
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
print("Matty" + "\x00" + "admin")
and got response User entered a username not found(due to parameterized queries)* turned to lowercase and spaces removed✅
login password box:
- attempted to enter a very large string: unable to enter ✅
- attempted to repeatedly paste small amounts of data and it capped at 256 characters ✅
- attempting to enter malicious inputs:
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
print("Matty" + "\x00" + "admin")
and got response User entered a username not found(due to parameterized queries) ✅
reattempted malicious inputs with a user that exists in the database and got the error: User entered a invalid username or password✅
login otp enter code box
attempted to enter characters and it refused ✅
attempted to enter special characters and it refused✅
attempted to enter unicode special characters and it refused ✅
attempted to enter sql injection code and it refused✅
attempted to put more then 6 characters in and it refused✅
moving on to recovery page
recovery username box:
- attempted to enter a very large string: unable to enter ✅
- fixed it attempted to enter a very large string: unable to enter ✅
- attempted to repeatedly paste small amounts of data and it capped at 256 characters ✅
- attempting to enter malicious inputs:
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
print("Matty" + "\x00" + "admin")
the malicious inputs were treated as text and allowed as a password* turned to lowercase and spaces removed ✅
recovery code box:
- attempted to enter a very large string: unable to enter ✅
- attempted to repeatedly paste small amounts of data and it capped at 256 characters ✅
- attempting to enter malicious inputs:
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
print("Matty" + "\x00" + "admin")
the malicious inputs were treated as text and allowed as a password✅
edit page:
Change username
verify password box
- attempted to enter a very large string: allowed over 256 ❌
- fixed and reattempted to enter a very large string: did not allow over 256✅
- attempted to repeatedly paste small amounts of data and it capped at 256 characters ✅
- attempting to enter malicious inputs:
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
print("Matty" + "\x00" + "admin")
the malicious inputs were treated as text and errored because password is incorrect✅
enter new username box
- attempted to enter a very large string: unable to enter ✅
- attempted to repeatedly paste small amounts of data and it capped at 256 characters ✅
- attempting to enter malicious inputs:
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
print("Matty" + "\x00" + "admin")
the malicious inputs were treated as text and allowed as a username* turned to lowercase and spaces removed✅
Change password
verify old password box
- attempted to enter a very large string: allowed over 256 ❌
- fixed and reattempted to enter a very large string: did not allow over 256✅
- attempted to repeatedly paste small amounts of data and it capped at 256 characters ✅
- attempting to enter malicious inputs:
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
print("Matty" + "\x00" + "admin")
the malicious inputs were treated as text and errored because password is incorrect✅
enter new password box
- attempted to enter a very large string: unable to enter ✅
- attempted to repeatedly paste small amounts of data and it capped at 256 characters ✅
- attempting to enter malicious inputs:
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
print("Matty" + "\x00" + "admin")
the malicious inputs were treated as text and allowed as a password ✅
confirm new password box
- attempted to enter a very large string: unable to enter ✅
- attempted to repeatedly paste small amounts of data and it capped at 256 characters ✅
- attempting to enter malicious inputs:
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
print("Matty" + "\x00" + "admin")
the malicious inputs were treated as text and allowed as a password ✅
change display name
- attempted to enter a very large string: unable to enter ✅
- attempted to repeatedly paste small amounts of data and it capped at 50 characters ✅
- attempting to enter malicious inputs:
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
print("Matty" + "\x00" + "admin")
the malicious inputs were blocked due to special characters as its a display name ✅
change email
- attempted to enter a very large string: unable to enter ✅
- attempted to repeatedly paste small amounts of data and it capped at 256 characters ✅
- attempting to enter malicious inputs:
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
print("Matty" + "\x00" + "admin")
the malicious inputs errored due to incorrect format for emails ✅
change email
- attempted to enter a very large string: unable to enter ✅
- attempted to repeatedly paste small amounts of data and it capped at 256 characters ✅
- attempting to enter malicious inputs:
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
print("Matty" + "\x00" + "admin")
the malicious inputs errored due to incorrect format for emails ✅
change date of birth
- attempted to enter a very large string: unable to enter ✅
- attempted to repeatedly paste small amounts of data and it capped at 6 characters ✅
- attempted to enter 06/06/1500: and errored due to not being a valid year ✅
- attempted to enter 06/06/2500: and errored due to not being a valid year ✅
- attempting to enter malicious inputs:
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
print("Matty" + "\x00" + "admin")
the malicious inputs errored due to not being numbers ✅
change home address
- attempted to enter a very large string: unable to enter ✅
- attempted to repeatedly paste small amounts of data and it told me too many characters (capped at 100)✅
- attempting to enter malicious inputs:
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
print("Matty" + "\x00" + "admin")
the malicious inputs were accepted as text without causing what they were designed to do ✅
change billing address
- attempted to enter a very large string: unable to enter ✅
- attempted to repeatedly paste small amounts of data and it told me too many characters (capped at 256)✅
- attempting to enter malicious inputs:
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
print("Matty" + "\x00" + "admin")
the malicious inputs were accepted as text without causing what they were designed to do ✅
denial of service
- attempted overloading through making many of accounts through ui and was unable to cause spikes in memory or slowdown✅
source for the very large string:
https://canterlotavenue.com/blog/410/the-entire-bee-movie-script/
source for malicious inputs:
https://github.com/unicornsasfuel/sqlite_sqli_cheat_sheet
' OR '1'='1' --
print("A" * 32767 + "'; DROP TABLE auth; --")
#####################################################################
icon sources:
home(recoloured):
https://www.svgrepo.com/svg/453354/home
login(recoloured):
https://creazilla.com/media/icon/3262795/login
signup(rotated)(recoloured):
https://creazilla.com/media/icon/3262795/login
edit(recoloured):
https://icon-icons.com/icon/notes-edit-modify/143729
not logged in:
https://icon-icons.com/icon/question-mark/83826
logged in (recoloured):
https://icon-icons.com/icon/account/138984
windows_icon (recoloured)
https://icon-icons.com/icon/icon-icx/245382
edit commit button(recoloured):
https://www.flaticon.com/free-icon/refresh_10613701?term=update&page=1&position=95&origin=tag&related_id=10613701
password_view_enable(recoloured):
https://icon-icons.com/icon/eye-see-show-view-watch/110339
password_view_disable(recoloured):
https://icon-icons.com/icon/disable-eye-inactive-see-show-view-watch/110343
#####################################################################
// // // // // ///////
// // // // // // //
// // // // // // ///////
// // // // // // //
//////// // // ///////
########################################
- made by matt