The program is a social platform prototype web app where users can write posts for other people to see. Included features are sign up, log in & log out, create and delete a post, password change, and delete account. User posts can be seen on the landing page. Administrators (must be created manually by setting the admin column to true in the database) can delete other users' posts.
The front-end of the program is implemented using React and Material-UI components. The back-end uses Rust, Actix Web, and PostgreSQL.
Folder structure
- server (contains backend files)
- src (rust source code)
- api (api endpoints)
- db (database communication)
- src (rust source code)
- web (frontend files)
- components (react components)
- pages (routing structure for frontend)
- public (public files served by frontend)
- styles (css styles)
- types (typescript types)
- utils (miscellaneous utility files)
- Latest stable version of rust and cargo (https://www.rust-lang.org/tools/install)
- node 18 (https://nodejs.org/en/download)
- pnpm (https://pnpm.io/installation)
- PostgreSQL 14
To get started create the file server/.env and fill include the following key value pairs. The provided values are only examples
POSTGRES_CONFIG="user=postgres password=secret dbname=name_of_db host=localhost"
RUST_LOG=info
RUST_BACKTRACE=1
SESSION_SECRET=haeH6bjwJKZbgK924nrB71by50EWtsDMGMHwfykzVIrGeAPEyof5SxZShjk94KP7
CSRF_SECRET=q20qAr3QoZeQ8LxQo8N15CRbEfrSyh1p7ihSkf7IZH0=
POSTGRES_CONFIG
contains the connection values as key value pairs separated by spaces.
Detailed info can be found in their documentation
The database and accounts that can access the database must be created manually.
RUST_LOG
and RUST_BACKTRACE
define what is logged and at what level.
SESSION_SECRET
is a long cryptographically random string that is used to generate session secrets.
CSRF_SECRET
is exactly 32 bytes of base-64 encoded cryptographically secure random data.
The example value is provided for convenience and should not be used outside of development.
After creating the .env file the next step is to get the database up to date.
This can be done by running cargo run --bin migrate-up
. If no errors show up
everything is set up correctly thus far.
The commands
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
require superuser permissions in postgres, so you might have to run them against your database as an admin account before running migrate-up.
To build the backend run cargo run
for a development build or cargo run --profile release
for a production build (this one requires setting up the frontend first).
If the commands run without error everything is set up correctly thus far.
To install all frontend dependencies run pnpm install
in the web directory.
For a development builds create the file web/.env.development with the following content
NEXT_PUBLIC_APP_PATH=http://localhost:8080
The value should be the base url to the API server.
To start the development version of the frontend you must run pnpm run dev
.
To build a production version run pnpm run export
(this needs to be run before starting production backend).
OWASP CheatSheetSeries was followed for authentication and Cross-Site Request Forgery (CSRF) prevention. React DOM takes care of input sanitization.
Passwords are required to be at least 8 characters long (as per NIST SP800-63B), a password strength meter (zxcvbn) is implemented to help users create stronger passwords, error messages do not reveal the status of an account (e.g., if account exists but input password was wrong), and account changing actions require a logged-in user to input their current password.
CSRF protection pattern used is the synchronizer token pattern
and ChaCha20 is used as the encryption algorithm.
Bcrypt with salt is used for password encryption.
SANS 25 is used as a checklist below for vulnerabilities of the application.
All buffers are handled by external libraries and Rust provides decent memory safety.
React handles input sanitization for user generated text content.
Values are inserted to queries through query parameters which keep the values separate from the query itself.
Input validation is done on the backend through the use of a validation library. Purely cosmetic input validation is also done on the frontend for better UX.
Rust has checks for this making it difficult to do out-of-bounds without getting compile time errors
OS commands are not used directly. If they are used within libraries it is unclear if they are safe.
Rust memory handling prevents this.
Actix-files library serves files, and it has mitigations for this.
Mitigated with the use of a CSRF token using the synchronizer token pattern.
User cannot upload files.
Rust memory handling prevents this.
Serde handles serialization into rust structs, and it will guarantee that the input is serialized into a well-formed struct with the correct types.
Not relevant for this project as it has no integer additions in the code we have written.
The application performs server-side authentication. However, there is no rate limitation, allowing brute-force attacking, which can lead to an account hijacking.
There are no hard-coded passwords or default administration accounts.
In addition to the UI showing only authorized actions to a user, the server checks that the current user is authorized for the made requests.
No commands with user input are run except for SQL which was addressed earlier.
A logged-in user is required to input their current password when changing their password and deleting their account.
Rust memory handling prevents this.
Irrelevant for this application, as there are no installable files.
The server does not do any data fetching based on a user given url.
Each session is a copy of the original. When making multiple simultaneous requests, if any request modifies the session the other requests might receive an outdated session.
No ratelimits are implemented which leads to a DOS vulnerability if the service receives a large enough volume of requests that do database queries.
The application does not support the uploading of files, including XML documents.
The application does not construct code segments based on user given data.
Security testing was done manually, and it was based on the above checklist. The security features were taken into account from the start and tested during the development phases of the features. Thus, no security flaws that were not already documented were found afterward.
The attack surface of the program is also relatively small, as the user does not have a lot of ways to enter or extract data on the web app. The user can input various xss attacks as their username, password, or post (email is prevented) but React's sanitization prevents the attack.
As mentioned in the SANS checklist above, rate limitation would help against DOS attacks and brute forcing.
The application is currently missing Multi-Factor Authentication. A new user is instantly logged in after registering, but ideally they would first get an email to activate their account. Similarly, due to the service not sending emails, a user cannot reset their password, nor retrieve their data (as per GDPR legislation).
The application gives a user a session token, which expires after 1 day of inactivity. The token keeps the user logged in, but having a "remember me" feature would be better than a long session token.
Application administrators only have the added authorization to delete any post compared to a regular account. However, they should be able to also perform other administrative actions, such as deleting regular user accounts and preventing users from making posts for a fixed amount of time.
As the program is simply a prototype, many other features could be added to make the social platform more interesting. Some examples include up-voting posts, profile personalization, following users, multimedia posts, and cascaded posts / replies.