This website was developed as a capstone project fore the Cybersecurity Specialization, from the University of Maryland, College Park, at Coursera
This project attempts to meet the requirements with the following functionalities:
An experimental login system
Instead of one strong password, users are asked to create three passwords. The password requirements were relaxed and password strength meter was put in place to aid users to create stronger passwords.
The idea behind the three password input fields is to improve strength by
- stimulating a longer password, composed of three words, without imposing a great burden on the user.
- ease the memorization of the password, as each chunk may be memorized independently, as in "78", "crossed", "Berlin".
- ease the password creation process, as the user may change each part of the password independently
Three passwords are not more secure than one, but they may be easier than a single hard-to-remember one.
Encrypted database with public key encryption
The entire database will be made available to the opponent. Therefore, it needs to be encrypted.
The entire source-code will also be made available, therefore it cannot hold any unencrypted private-keys
There will be no administration account able to read user's messages or to provide keys.
The solution this project proposes is to store a encrypted key and a initialization vector for each user, and encrypt the messages with each user's public key.
The intention is to stop an opponent from gaining access to user's messages even when in possession of the entire database.
If an opponent manages to gain access to a user's secret (sha256 hashed password), he'll be able to gain access only to that user's messages.
- Upon registration, the provided passwords are merged and two different hashes are created:
- the first one is persisted for login purposes. It uses PHP password_hash default algorithm: bcrypt
- the second one is not persisted, but used to create the user's key-pair. It uses sha256 and it lives in PHP session.
- Upon registration each users receives a initialization vector, created with PHP random_bytes function, which, on Linux, uses getrandom to provide cryptographic secure random bytes.
- Upon registration, user's private key is encrypted using user's secret (sha256 hashed password) and the initialization vector. The encrypted private key is persisted.
- Upon login user's secret is generated and stored in PHP's session
The system uses PHP's session to store user's secret, which is destroyed upon logoff. It uses a different cookie to identify the user.
Both cookies are provided on each request, if they are absent and are attached to a user id upon login
A Sqlite database is used as storage and almost every interaction with it is done using PHP's PDO extension.
The entire database is available for download at the dbdump link. This is a assignment requirement. Preparing the database for download is the only interaction with it that does not uses PHP's PDO extension.
To avoid SQL injection Every SQL statement is written as a separate .sql file, read by php with file_get_contents and parameters are bind with PDO's bind method.
Cross site scripting
HTML Purifier was used to prevent XSS attacks. Every untrusted content that is sent to the user is filtered with it's purify method.
Stored data are not subject to HTML Purifier. The sanitization occurs previous to building the HTML.
The system avoids using paths or Get queries that may leak information. Many websites will display the user page in a path similar to '/user/john', revealing the username or user id to an opponent monitoring traffic. Even worse, these requests may be used to set the parameter of the destination of a message, as in '/send-message/to/john', or simply 'send/john'. These requests reveal contacts information and frequency of exchanged messages.
We use a single path, 'compose', to both answers and new messages. The contact information, if necessary, is provided through a Post request.
Database dumping is done with a Shell Script, executed by PHP without any parameter, using sqlite3 and zip commands.