added encryption to uploadkeys and added a key generator #1
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -133,3 +133,4 @@ uploadkeys | ||||
| savelog.log | ||||
| uwsgi.log | ||||
| settings.py | ||||
| secret.key | ||||
| @@ -1,4 +1,9 @@ | ||||
| # imgupload | ||||
| Python Flask uWSGI application to receive and save images over POST requests. | ||||
|         | ||||
|  | ||||
| This project is still in development. Use at your own risk! | ||||
| ### What is imgupload?  | ||||
| imgupload is a Flask + uWSGI application to serve as an all-purpose image/file uploader over POST requests. | ||||
|  | ||||
| ### Usage | ||||
| Make sure you install the dependencies first. To do this, run `sudo python3 -m pip install -r requirements.txt`.   | ||||
| To deploy imgupload, run `flask run`. | ||||
| @@ -11,6 +11,7 @@ defaults = { | ||||
|     "SAVELOG_CHMOD": "0o644", | ||||
|     "UPLOADKEYS_CHMOD": "0o400", | ||||
|     "SAVELOG_KEYPREFIX": 4, | ||||
|     "ENCKEY_PATH": "secret.key" | ||||
| } | ||||
|  | ||||
| deftypes = { | ||||
| @@ -21,6 +22,7 @@ deftypes = { | ||||
|     "SAVELOG_CHMOD": int, | ||||
|     "UPLOADKEYS_CHMOD": int, | ||||
|     "SAVELOG_KEYPREFIX": int, | ||||
|     "ENCKEY_PATH": str, | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -54,7 +56,7 @@ if "ALLOWED_EXTENSIONS" in checksettings: | ||||
|     for e in settings.ALLOWED_EXTENSIONS: | ||||
|         if not e.startswith("."): | ||||
|             invalid_exts.append(e) | ||||
|  | ||||
|      | ||||
|     if len(invalid_exts) > 0: | ||||
|         print("[!] The following extensions listed in ALLOWED_EXTENSIONS are invalid:") | ||||
|         for e in invalid_exts: | ||||
| @@ -99,6 +101,15 @@ if "SAVELOG" in checksettings: | ||||
|     print("[*] SAVELOG was interpreted to be {0}".format(settings.SAVELOG)) | ||||
|     print("[*] If this is not the intended filename, please fix it.") | ||||
|  | ||||
| # Check if ENCKEY_PATH exists | ||||
| enckey_exists = True | ||||
| if "UPLOAD_FOLDER" in checksettings: | ||||
|     if not os.path.isfile(settings.ENCKEY_PATH): | ||||
|         enckey_exists = False | ||||
|         print("[!] The path set in ENCKEY_PATH ('{0}') doesn't exist!".format(settings.ENCKEY_PATH)) | ||||
|     else: | ||||
|         print("[" + u"\u2713" + "] ENCKEY_PATH exists!") | ||||
|  | ||||
|  | ||||
| # Show summary | ||||
| print() | ||||
|   | ||||
							
								
								
									
										27
									
								
								imgupload.py
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								imgupload.py
									
									
									
									
									
								
							| @@ -1,4 +1,5 @@ | ||||
| from flask import Flask, request, jsonify, abort, Response | ||||
| from cryptography.fernet import Fernet | ||||
| from flask_api import status | ||||
| from pathlib import Path | ||||
| import string | ||||
| @@ -40,28 +41,32 @@ def log_savelog(key, ip, savedname): | ||||
|             slogf.write("[{0}] {1} - {2}\n".format(datetime.datetime.now(), ip, savedname)) | ||||
|         os.chmod(settings.SAVELOG, settings.SAVELOG_CHMOD) | ||||
|  | ||||
|  | ||||
| @app.route("/upload", methods = ["POST"]) | ||||
| def upload(): | ||||
|     if request.method == "POST":  # sanity check: make sure it's a POST request | ||||
|         print("Request method was POST!") | ||||
|  | ||||
|         os.chmod("uploadkeys", settings.UPLOADKEYS_CHMOD) | ||||
|         print("Changed permissions of `uploadkeys`") | ||||
|         with open("uploadkeys", "r") as keyfile:  # load valid keys | ||||
|             validkeys = keyfile.readlines() | ||||
|         validkeys = [x.strip("\n") for x in validkeys] | ||||
|         with open(settings.ENCKEY_PATH,"rb") as enckey: # load encryption key | ||||
|             key = enckey.read() | ||||
|         f = Fernet(key) | ||||
|  | ||||
|         with open("uploadkeys", "rb") as keyfile: | ||||
|             encrypted_data = keyfile.read() | ||||
|         decrypted_data = str(f.decrypt(encrypted_data).decode('utf-8')) | ||||
|         decrypted_data = decrypted_data.splitlines() | ||||
|  | ||||
|         validkeys = [x.strip("\n") for x in decrypted_data] | ||||
|         while "" in validkeys: | ||||
|             validkeys.remove("") | ||||
|             print("Removed blank key(s)") | ||||
|         print("Loaded validkeys") | ||||
|  | ||||
|         if "uploadKey" in request.form:  # if an uploadKey was provided | ||||
|             if request.form["uploadKey"] in validkeys:  # check if uploadKey is valid | ||||
|                 print("Key is valid!") | ||||
|  | ||||
|                 if "imageUpload" in request.files:  # check if image to upload was provided | ||||
|                     f = request.files["imageUpload"]  # f is the image to upload | ||||
|                     print("Found uploaded image") | ||||
|                 else: | ||||
|                     print("No image upload was found!") | ||||
|                     return jsonify({'status': 'error', 'error': 'NO_IMAGE_UPLOADED'}), status.HTTP_400_BAD_REQUEST | ||||
| @@ -71,23 +76,23 @@ def upload(): | ||||
|                     return jsonify({'status': 'error', 'error': 'FILENAME_BLANK'}), status.HTTP_400_BAD_REQUEST | ||||
|  | ||||
|                 fext = Path(f.filename).suffix  # get the uploaded extension | ||||
|                 print("Uploaded file extensions is {0}".format(fext)) | ||||
|                 if allowed_extension(fext):  # if the extension is allowed | ||||
|                     print("Generating file with extension {0}".format(fext)) | ||||
|                     fname = generate_name(fext)  # generate file name | ||||
|                     print("Generated name: {0}".format(fname)) | ||||
|  | ||||
|                     if f:  # if the uploaded image exists | ||||
|                         print("Uploaded image exists, obviously.") | ||||
|                         print("Uploaded image exists") | ||||
|                         f.save(os.path.join(settings.UPLOAD_FOLDER, fname))  # save the image | ||||
|                         print("Saved to {0}".format(fname)) | ||||
|                         url = settings.ROOTURL + fname  # construct the url to the image | ||||
|                         if settings.SAVELOG != "/dev/null": | ||||
|                             print("Saving to savelog") | ||||
|                             log_savelog(request.form["uploadKey"], request.remote_addr, fname) | ||||
|                             print("Logged message to savelog") | ||||
|                         print("Returning json response") | ||||
|                         return jsonify({'status': 'success', 'url': url, 'name': fname, 'uploadedName': f.filename}), status.HTTP_201_CREATED | ||||
|                     else:  # this shouldn't happen | ||||
|                         print("Um... uploaded image is nonexistent..? Please report this error!") | ||||
|                         print("Um... uploaded image... is nonexistent? Please report this error!") | ||||
|                         return jsonify({'status': 'error', 'error': 'UPLOADED_IMAGE_FAILED_SANITY_CHECK_1'}), status.HTTP_400_BAD_REQUEST | ||||
|  | ||||
|                 else:  # if the extension was invalid | ||||
|   | ||||
							
								
								
									
										65
									
								
								keygen.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								keygen.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| from cryptography.fernet import Fernet | ||||
| from pathlib import Path | ||||
| import settings | ||||
| import string | ||||
| import secrets | ||||
| import sys | ||||
| import os | ||||
|  | ||||
| # Check if the script is ran as root  | ||||
| if os.geteuid() != 0: | ||||
|     exit("Root privileges are necessary to run this script.\nPlease try again as root or using `sudo`.") | ||||
|  | ||||
| # Check if encryption key exists | ||||
| enckey = Path(settings.ENCKEY_PATH) | ||||
| if enckey.is_file(): | ||||
| 	print("Encryption key found.") | ||||
| else: | ||||
|     print("Encryption key not found.") | ||||
|     print("Generating key...") | ||||
|     key = Fernet.generate_key() | ||||
|     with open(settings.ENCKEY_PATH, "wb") as key_file: | ||||
|         key_file.write(key) | ||||
|     print("Encryption key generated and stored in secret.key.") | ||||
|  | ||||
| # Load encryption key | ||||
| def load_key(): | ||||
|     return open(settings.ENCKEY_PATH, "rb").read() | ||||
|  | ||||
| # Set size of string | ||||
| N = 64 | ||||
|  | ||||
| # Generating of key | ||||
| token = ''.join(secrets.choice(string.ascii_letters + string.digits) for i in range(64)) | ||||
|  | ||||
| # Decrypt the existing keyfile | ||||
| key = load_key() | ||||
| f = Fernet(key) | ||||
| with open("uploadkeys", "rb") as file: | ||||
|     # read the encrypted data | ||||
|     encrypted_data = file.read() | ||||
| # decrypt data | ||||
| decrypted_data = f.decrypt(encrypted_data) | ||||
| # write the original file | ||||
| with open("uploadkeys", "wb") as file: | ||||
|     file.write(decrypted_data) | ||||
|  | ||||
| # Encrypting and storing of key | ||||
| def encrypt_key(message): | ||||
|     key = load_key() | ||||
|     f = Fernet(key) | ||||
|  | ||||
|     with open('uploadkeys', 'a+') as uploadkeys: | ||||
|         print(str(token), file=uploadkeys) | ||||
|  | ||||
|     with open("uploadkeys", "rb") as keyfile: | ||||
|         keyfile_data = keyfile.read() | ||||
|  | ||||
|     encrypted_data = f.encrypt(keyfile_data) | ||||
|  | ||||
|     with open("uploadkeys", "wb") as keyfile: | ||||
|         keyfile.write(encrypted_data) | ||||
|  | ||||
| # Print result on display and call encrypt_key | ||||
| print("Your new token is: " + str(token)) | ||||
| encrypt_key(str(token)) | ||||
							
								
								
									
										4
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| Flask_API==2.0 | ||||
| cryptography==2.8 | ||||
| Flask==1.1.2 | ||||
| secrets==1.0.2 | ||||
| @@ -5,3 +5,4 @@ SAVELOG = "savelog.log" | ||||
| SAVELOG_CHMOD = 0o644 | ||||
| UPLOADKEYS_CHMOD = 0o600 | ||||
| SAVELOG_KEYPREFIX = 4 | ||||
| ENCKEY_PATH = "secret.key" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user