Skip to content

School project for realizing a small blog web app with the focus on web-security.

Notifications You must be signed in to change notification settings

ruegerj/security-blog

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 

Repository files navigation

Security Blog

School project for realizing a small blog web app in the context of the module M183 with the focus on web-security. Built with an Angular 11 client and an Express REST Api backend.

Table of Contents

Getting Started

This section shows you how to set up and run this project on your machine. The project was developed and test with Node.js v14.1.0 and npm v6.14.4. These are the only software dependencies therefore please ensure you got them installed on your system prior to the setup.

Create Database

First let us create the SQLite database on the machine. To achieve this we must run all migrations in order to create a database which is compatible to the current entity models. This can be done by executing following command in the terminal:

cd server

npm run migrations

cd ..

Note: The default location of the database will be dynamically determined based on the value set for the APPDATA enviroment variable which should be specified per default in the process.env. The default path for the database will therefore look someting lîke this on Windows: %APPDATA%/security-blog/db/security-blog.db. If you should encounter any issue due to this, you could simply set the variable APP_DATA_DIR in config.dev.env to an absolute path on your machine, were file write operations aren't restricted.

Build Application

Now that we got the database setup, we now can build the client and api applications. As long as no changes are made to the source code of the respective app, this must only be done once. First lets start by building the client app with the following command:

cd client

# Build in productive configuration for improved performance
npm run build:prod

cd ..

Let's continue by building the api application. This can be achieved with the following command:

cd server

npm run build

cd ..

Run Application

With both applications built, we now can go ahead and run them. Because the angular client is hosted by the Express app this is as simple, as the following command:

cd server

# Run api in development configuration
npm run start:dev

User Accounts

The application comes with two pre configured user accounts: one for the admin- and one for the userr-role. The credentials for these two accounts are the following:

// Admin account
{
    username: 'not-the-admin',
    email: 'admin@security-blog.io'
    password: 'ImTh34dm|n',
}

// User account
{
    username: 'john.doe',
    email: 'john.doe@security-blog.io',
    password: 'BlogP4$$w0rd'
}

Note: The phone numbers assigned to this users are just placeholders. In order to be able to use one account you have to replace its phone number in the database with your own. A rather convenient tool for this purposer is the DB Browser for SQLite.

XSS Protection

On the API the middleware xss-clean is used to sanitize all incoming data (request params and request body). Therefore any content wich is save into the database will be satitized automatically. On the client, angular takes care of everything. Because only angular manipulates the DOM its DOM sanitizer ensures, that all scripts are removed, before rendered. Even when HTML is set using the innerHTML directive (like on the post detail page) all malicious scripts would be automatically removed and therefore prevented form execution.

Passwords

This section covers the approach for storing passwords in this application and the used password policy.

Storage

Before a password is persisted, it goes through the following steps:

  • SHA-512:
    The incoming plain text password will first be hashed using the SHA-512 algorythm. This adds the benefit of an always consistent output while consuming very little time.

  • bcrypt:
    The ouput of the of the preceeding step (SHA-512) will now be salted and hashed using the bcrypt algorythm. Bcrypt is an excellent choice for this job because its a slow hashing algorithm whose time/iteration cost can be configured. With a consistent input length ensured, the time factor can be tuned much more effectively.

    In this app the cost factor is set to 12 which translates to 4'096 hashing iterations. As this post nicely displays it is equivalent to arround 250ms on an Intel i7 9700k CPU. The consumed time of approximately 250ms add a solid artifical deceleration while have not having a to big impact on the UX.

This concept of storing a password is huegely inspired by the approach Dropbox uses:

Plain text => SHA-512 => bcrypt salt => AES256 pepper

Alltough the pepper adds an addiontal security layer ontop the others and protects against potential database leaks (dictionary attacks), it was deliberately ommited in this project. The reason behind this was the huge amount of work which would have been nescessary to implement a solid key rotation system used for the pepper private keys. This issue is nicely clarified in this Stack Overflow post.

Policy

The used password policy for this app uses the rules recommended by Microsoft for Windows account credentials. The following conditions have to be fullfilled for a valid password:

  • Consists of atleast ten characters
  • Contains atleast one lowercase character (a-z)
  • Contains atleast one upperchase character (A-z)
  • Contains atleast one digit (0-9)
  • Contains atleast one non alphanumeric character (~!@#$%^&*_-+=`|(){}[]:;"'<>,.?/)

Logging

This section covers the used logging policy and how it was implemented.

Policy

In the api (server) every event should be logged, which could be useful for any later investigation. The types of such an investigation could vary from performance improvement (e.g. lag spikes), error monitoring, api calls or security incidents. However, care must be taken to ensure that sensitive data (user data, credentials, tokens etc.) is not accidentally logged, which could lead to possible leaks. The following log levels are defined and should be used as specified:

  • Trace: should only used for information which is useful to pinpoint sepcific parts of a funciontality (code)
  • Debug: should be used for diagnostic information wich is useful for the developers or the system administrators
  • Info: should be used for general information about the ongoing events while the application is running
  • Warn: should be used for information about incidents from which the app manged to recover itself but could lead to odd behaviour. Additionaly all security relevant information should be logged with this level (e.g. failed login attempt, failed authorization on a resourec etc.)
  • Error: should be used for information about application errors which have occured.

Implementation

An application wide logger is implement using the winston logger under the hood. It's currently configured to log into a log file, but could be easily extended for delegating the logs into a database. In combination, morgan is used to log any request on the api.

Libraries

This section lists any external library used in the application

API

Collection of all NPM packages used within the express api:

Package Usage
bcrypt Password hashing
class-transformer Model mapping
class-validator Validation of DTO's
compression Compression for static served content
cookie-parser Parsing request cookies
dotenv-with-expand App configuration using .env files
envalid Verification of required env variables
express Handling web interactations more efficiently
helmet Configuring HTTP security headers
hpp Protection against HTTP parameter polution attacks
jsonwebtoken Parsing and handling JWT
morgan Request logging
node-fetch Performing in-app HTTP requests
reflect-metadata TS decorators
sqlite3 Conection to sqlite databases
toobusy-js Monitoring of event loops load
typedi Dependency injection
typeorm ORM for data access and db interaction
typeorm-typedi-extensions Dependency injection for typeorm
uuid Creating and handling UUID's
winston Handling and persisting logs
xss-clean Sanitizing every incoming input against XSS

Client

Collection of all NPM packages used within the angular client:

Package Usage
@angular/animations Component of angular
@angular/cdk Component of angular
@angular/common Component of angular
@angular/compiler Component of angular
@angular/core Component of angular
@angular/forms Component of angular
@angular/platform-browser Component of angular
@angular/platform-browser-dynamic Component of angular
@angular/router Component of angular
@ckeditor/ckeditor5-angular Rich text editor
@ckeditor/ckeditor5-build-classic UI component for rich text editor
@datorama/akita Component state management
@fortawesome/fontawesome-free Icon library
angular-bootstrap-md Styling of the app
animate.css Animations
chart.js Display of charts
hammerjs Touch interactions
jwt-decode Parsing JWT's
ngx-logger Global logger
rxjs Application wide data flow
zone.js Performing async tasks

About

School project for realizing a small blog web app with the focus on web-security.

Topics

Resources

Stars

Watchers

Forks