Giter Site home page Giter Site logo

cyber-students's Introduction

cyber-students

This repository provides some sample code for the Shared Project for Modern Cryptography and Security Management & Compliance. The project requires git, Python 3, and MongoDB. The following sections briefly explain how to setup the project on your local machine.

Get the Sample Code

Create a GitHub account. Download and install git. We will use git to manage our source code.

Verify that git is installed correctly:

git --version

Fork this repository and clone your forked repository to your local machine:

git clone https://github.com/YOUR_GITHUB_USERNAME/cyber-students.git

Setup the Project

Create a Python 3 virtual environment:

python -m venv project-venv

Activate the virtual environment:

:: ... on Windows:
.\project-venv\Scripts\activate
# ... on macOS/*nix:
source project-venv/bin/activate

Install the required packages:

cd cyber-students
pip install -r requirements.txt

Download, install and start MongoDB Community Edition. We will use MongoDB as our database.

Download and install MongoDB Shell. Open a MongoDB shell:

mongosh

Create two databases with a collection named users in each:

use cyberStudents;
db.createCollection('users');

use cyberStudentsTest;
db.createCollection('users');

The first database will store our 'real' data. The second database will be used by our tests.

Download and install curl. curl is also shipped by Microsoft as part of Windows 10 and 11. curl is a command-line tool for interacting with web servers (and other protocols).

Verify that curl is installed correctly:

curl --version

Start the Project

The server contains functionality for:

  • registering new users (api/handlers/registration.py)
  • logging in (api/handlers/login.py)
  • logging out (api/handlers/logout.py)
  • displaying profile (api/handlers/user.py)

To start the server:

python run_server.py

The server is available on port 4000 at http://localhost:4000/students/api. However, it is not possible to use all of the functionality offered by the server directly using a browser. Instead we will use curl to interact with the server.

Registration

To register a new user:

curl -X POST http://localhost:4000/students/api/registration -d "{\"email\": \"[email protected]\", \"password\": \"strongpassword\", \"displayName\": \"Nigel Douglas\", \"fullName\": \"Nigel Douglas\", \"phoneNumber\": \"02537641\", \"disability\": \"leukemia\"}"

If the registration is successful, it will confirm the email address and the display name of the newly registered user:

{"email": "[email protected]", "displayName": "Foo Bar"}

If the registration is unsuccessful, for example, if you try to register the same user twice, it will return an error message:

{"message": "A user with the given email address already exists!"}

Logging In

To login:

curl -X POST http://localhost:4000/students/api/login -d "{\"email\": \"[email protected]\", \"password\": \"pass\"}"

If the login is successful, it will return a token and expiration timestamp:

{"token": "d4a5d8b20fe143b7b92e4fba92d409be", "expiresIn": 1648559677.0}

A token expires and is intended to be short-lived. A token expires two hours after login, after a logout, or if there is another login from the same user, generating a new token.

If the login is unsuccessful, for example, if you provide an incorrect password, it will return an error message:

{"message": "The email address and password are invalid!"}

Displaying a Profile

To display a user's profile you need to a token that has not expired. Then you can use:

curl -H "X-TOKEN: d4a5d8b20fe143b7b92e4fba92d409be" http://localhost:4000/students/api/user

Note that this API call does not require the -X POST flag.

If successful, it will return the email address and the display name for the user:

{"email": "[email protected]", "displayName": "Foo Bar"}

Logging Out

To logout, you also need a token that has not expired. Then you can use:

curl -X POST -H "X-TOKEN: d4a5d8b20fe143b7b92e4fba92d409be" http://localhost:4000/students/api/logout

Test the Project

You can run the automated tests using:

python run_test.py

This command runs a number of automated tests in the tests folder. The tests read and store data in the cyberStudentsTest database only. They perform tests such as registering new users (tests/registration.py), logging in (tests/login.py), and logging out (tests/logout.py).

The project also includes a program called run_hacker.py. You can run it using:

python run_hacker.py list

It displays all information stored in the MongoDB database. It produces output similar to the following:

There are 1 registered users:
{'_id': ObjectId('6242d9c34536b3a16b49aa6b'), 'email': '[email protected]', 'password': 'pass', 'displayName': 'Foo Bar'}

As you can see, all of the information is stored in the clear; there is no encryption or password hashing. If a hacker was to compromise the database, they could easily run a similar program to retrieve all of the users personal information and passwords.

After encryption is enforced

You can see the original 4 registrations did not enforce encryption.
The latest test has a new field called fullName. The full name and password are encrypted:

Screenshot 2023-04-16 at 21 01 13

Using Fernet for Encryption

Fernet guarantees that a message encrypted using it cannot be manipulated or read without the key.
Fernet is an implementation of symmetric (also known as “secret key”) authenticated cryptography.
Fernet also has support for implementing key rotation via MultiFernet .

Screenshot 2023-04-16 at 20 23 14

Before and after the encryption - as seen in MongoDB Compass

Screenshot 2023-04-17 at 12 45 09

Using the git worklflow

git remote -v shows me which repo I'm currently connected to.
git remote set-url origin sets the desired Github account to push changes to.
git push -f forcefully pushes the changes to the Github branch - even if there is conflict
git status ensures I'm on the master branch. I don't want to commit to the wrong branch
git pull checks that everything is already up-to-date
git diff shows the differences between the file locally and in github
git add simply adds the files to the approval process
git commit commits the changes to GitHub -m flag is to add a description
git pushfinally pushes the changes up to my Github master

git remote -v
git remote set-url origin [email protected]:nigeldouglas-itcarlow/cyber-students.git
git push - f
git status
git pull
git diff requirements.txt
git add requirements.txt
git commit -m "adding password hasher package"
git push

Screenshot 2023-04-17 at 12 57 11

Creating GDPR fields

I'm able to parse the full_name field to JSON:

curl -X POST http://localhost:4000/students/api/registration -d "{\"email\": \"[email protected]\", \"password\": \"happier\", \"displayName\": \"happier\", \"fullName\": \"Mr. Happy\"}"
{"email": "[email protected]", "displayName": "happier", "fullName": "Mr. Happy"}%

However, I'm unable to parse the phone_number field to JSON:

curl -X POST http://localhost:4000/students/api/registration -d "{\"email\": \"[email protected]\", \"password\": \"happier\", \"displayName\": \"happier\", \"fullName\": \"Mr. Happy\", \phoneNumber\": \"02136541\"}"

Screenshot 2023-04-17 at 14 51 12

Eventually loaded the Disabilities and Phone Numbers
The issue was not with the fields I created, it was with the run_server.py script
Between tests, I need to kill the process manually, and then restart it to see the changes.

ps aux | grep run
kill -9 55879
python run_server.py 

Screenshot 2023-04-18 at 15 42 59

Ensuring weak password are not used

Ensuring the character length has to exceed 6 characters:

if len(password) < 6:
    self.send_error(400, message='The password must be at least 6 characters long!')
    return

Screenshot 2023-04-18 at 16 31 15

import re

password = input("Create a password: ")
password_pattern = re.compile(r'^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)[A-Za-z\d]{6,}$')

while not password_pattern.match(password):
    print("Your password must contain at least one uppercase letter, one lowercase letter, and one digit, and be at least 6 characters long.")
    password = input("Create a password: ")
    
print("Password set successfully!")

Screenshot 2023-04-19 at 09 57 55

Using regular expressions, (password_pattern) to ensure that the password contains at least:

  • one uppercase letter
  • one lowercase letter
  • one digit
  • at least 14 characters long.

If the user's input does not match this pattern, the program will prompt them to create a new password until the requirements are met.

Loading the key from a file

It's not okay to hardcode your cryptography keys in the source code
Instead, I can load it from a file or to use environmental variables (recommended)

Screenshot 2023-04-18 at 15 54 46

Loading the key from a file is a more common approach to avoid hardcoding sensitive data in the code.
I created a new file named secret.env in the same directory as my Python script.

The load_dotenv function loads environment variables from the .env file, and os.getenv('CRYPTO_KEY') retrieves the value of the CRYPTO_KEY environment variable set in the .env file. The .encode() method converts the string key to bytes, which is needed for the Fernet module to work.
I made sure to install the python-dotenv package by running pip install python-dotenv in the terminal.

Screenshot 2023-04-19 at 15 52 32

Partially initialized module 'api.app' Error

Screenshot 2023-04-20 at 08 25 49

Cannot import name 'Application' from 'api.app' error

Screenshot 2023-04-20 at 08 36 57

ImportError: attempted relative import with no known parent package

Screenshot 2023-04-20 at 08 28 06

Commiting changes to Git so progress is tracked

Screenshot 2023-04-20 at 08 47 23

There was a long learning curve when working with git

Screenshot 2023-04-20 at 09 06 46

However, I was able to add /modify files in the end:

Screenshot 2023-04-20 at 09 12 07

Merging all changes

When I felt the project was in a working state, I merged from nigel-branch to the master branch

Screenshot 2023-04-29 at 23 03 44

cyber-students's People

Contributors

nigeldouglas-itcarlow avatar setumartin avatar

Stargazers

Nigel Douglas avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.