diff --git a/Pipfile b/Pipfile index fb202e1..32afe88 100644 --- a/Pipfile +++ b/Pipfile @@ -23,6 +23,7 @@ argon2-cffi = "*" sentry-sdk = "*" aiofiles = "*" meilisearch = "*" +bleach = "*" [dev-packages] coverage = "*" @@ -35,4 +36,4 @@ black = "*" python_version = "3.10" [scripts] -format = "black ." \ No newline at end of file +format = "black ." diff --git a/Pipfile.lock b/Pipfile.lock index e11c0a0..0dfb5a0 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "7e2c8532f63f702ec73822fc0a4cab8fdf54de46dcd6be01aee4fbd0e5a8937e" + "sha256": "9c79265a8b3c11d13cbd676f1c575213f39fa850b59fd02caaa3a2f1391e3277" }, "pipfile-spec": 6, "requires": { @@ -232,6 +232,14 @@ "markers": "python_version >= '3.7'", "version": "==0.22.0" }, + "bleach": { + "hashes": [ + "sha256:08a1fe86d253b5c88c92cc3d810fd8048a16d15762e1e5b74d502256e5926aa1", + "sha256:c6d6cc054bdc9c83b48b8083e236e5f00f238428666d2ce2e083eaa5fd568565" + ], + "index": "pypi", + "version": "==5.0.0" + }, "certifi": { "hashes": [ "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872", @@ -331,7 +339,7 @@ "sha256:0f7569a4a6ff151958b64304071d370daa3243d15941a7beedf0c9fe5105603e", "sha256:a851e51367fb93e9e1361732c1d60dab63eff98712e503ea7d92e6eccb109b4f" ], - "markers": "python_version >= '3.6' and python_version < '4'", + "markers": "python_version >= '3.6' and python_full_version < '4.0.0'", "version": "==2.2.1" }, "ecdsa": { @@ -949,7 +957,7 @@ "sha256:5c6bd9dc7a543b7fe4304a631f8a8a3b674e2bbfc49c2ae96200cdbe55df6b17", "sha256:95c5d300c4e879ee69708c428ba566c59478fd653cc3a22243eeb8ed846950bb" ], - "markers": "python_version >= '3.6' and python_version < '4'", + "markers": "python_version >= '3.6' and python_full_version < '4.0.0'", "version": "==4.8" }, "sentry-sdk": { @@ -1047,7 +1055,7 @@ "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14", "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_full_version < '4.0.0'", "version": "==1.26.9" }, "uvicorn": { @@ -1089,6 +1097,13 @@ ], "version": "==0.8.2" }, + "webencodings": { + "hashes": [ + "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", + "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" + ], + "version": "==0.5.1" + }, "websockets": { "hashes": [ "sha256:038afef2a05893578d10dadbdbb5f112bd115c46347e1efe99f6a356ff062138", @@ -1498,7 +1513,7 @@ "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" ], - "markers": "python_version >= '3.7'", + "markers": "python_version < '3.11'", "version": "==2.0.1" } } diff --git a/classquiz/routers/quiz.py b/classquiz/routers/quiz.py index 834523d..0098e99 100644 --- a/classquiz/routers/quiz.py +++ b/classquiz/routers/quiz.py @@ -7,6 +7,7 @@ from classquiz.helpers import get_meili_data from fastapi import APIRouter, Depends, HTTPException from fastapi.responses import JSONResponse from pydantic import ValidationError +import bleach from classquiz.auth import get_current_user from classquiz.config import redis, settings, storage, meilisearch @@ -22,6 +23,8 @@ router = APIRouter() async def create_quiz_lol(quiz_input: QuizInput, user: User = Depends(get_current_user)): imgur_regex = r"^https://i\.imgur\.com\/.{7}.(jpg|png|gif)$" server_regex = rf"^{settings.root_address}/api/v1/storage/download/.{36}--.{36}$" + quiz_input.title = bleach.clean(quiz_input.title, tags=[], strip=True) + quiz_input.description = bleach.clean(quiz_input.description, tags=[], strip=True) for question in quiz_input.questions: if question.image == "": question.image = None @@ -127,6 +130,8 @@ async def update_quiz(quiz_id: str, quiz_input: QuizInput, user: User = Depends( else: # print(quiz_input) # print(quiz) + quiz_input.description = bleach.clean(quiz_input.description, tags=[], strip=True) + quiz_input.title = bleach.clean(quiz_input.title, tags=[], strip=True) meilisearch.index(settings.meilisearch_index).update_documents([await get_meili_data(quiz)]) if quiz.public and not quiz_input.public: print("removing from meilisearch") diff --git a/classquiz/routers/users.py b/classquiz/routers/users.py index f2ccfdb..63ce3a3 100644 --- a/classquiz/routers/users.py +++ b/classquiz/routers/users.py @@ -17,6 +17,7 @@ from classquiz.auth import ( from classquiz.cache import clear_cache_for_account from classquiz.config import redis, settings import uuid +import bleach from pydantic import BaseModel from classquiz.db.models import User, UserSession, UpdatePassword, Token from classquiz.emails import send_register_email, send_forgotten_password_email @@ -58,6 +59,7 @@ async def create_user(user: route_user, background_task: BackgroundTasks) -> Use raise HTTPException(status_code=409, detail="User already exists") user.password = get_password_hash(user.password) + user.username = bleach.clean(user.username, tags=[], strip=True) if len(user.username) == 32: return JSONResponse({"details": "Username mustn't be 32 characters long"}, 400) await user.save()