diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0cafc1c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.venv/ \ No newline at end of file diff --git a/client/src/components/Generic/FloatingDialog.tsx b/client/src/components/Generic/FloatingDialog.tsx index af51d5e..1a6a022 100644 --- a/client/src/components/Generic/FloatingDialog.tsx +++ b/client/src/components/Generic/FloatingDialog.tsx @@ -1,12 +1,5 @@ import { Close, UnfoldLess, UnfoldMore } from "@mui/icons-material"; -import { - Box, - IconButton, - Modal, - Tooltip, - Typography, - useTheme, -} from "@mui/material"; +import { Box, IconButton, Modal, Tooltip, Typography, useTheme } from "@mui/material"; import { FC, ReactNode } from "react"; import { defaultSettings } from "../../lib/settings"; @@ -40,19 +33,18 @@ export const FloatingDialog: FC = ({ <> {openButton} - + = ({ top: "50%", transform: "translate(-50%, -50%)", transition: "all ease-in-out", - transitionDuration: - defaultSettings.style.transition_duration + "ms", - width: maximisedState - ? "100vw" - : defaultSettings.style.window_width + "px", + transitionDuration: defaultSettings.style.transition_duration + "ms", + width: maximisedState ? "100vw" : defaultSettings.style.window_width + "px", }} > = ({ px: 1, }} > - {title} + {title} {actionButtons} @@ -92,7 +81,7 @@ export const FloatingDialog: FC = ({ {maximisedState ? : } - + diff --git a/client/src/components/Generic/LoadingScreen.tsx b/client/src/components/Generic/LoadingScreen.tsx index f74f25e..0a91c81 100644 --- a/client/src/components/Generic/LoadingScreen.tsx +++ b/client/src/components/Generic/LoadingScreen.tsx @@ -16,10 +16,16 @@ export const LoadingScreen: FC = ({ loadingText }) => { justifyContent: "center", }} > - + {loadingText} - + ); }; diff --git a/server-ml/main.py b/server-ml/main.py new file mode 100644 index 0000000..3a18c14 --- /dev/null +++ b/server-ml/main.py @@ -0,0 +1,41 @@ +from flask import Flask, request, jsonify +import joblib +import os + +# first see if the trained model file exists +if os.path.exists("model.pkl"): + model = joblib.load("model.pkl") +else: + raise FileNotFoundError("The model.pkl file does not exist.") + +# load the model +model = joblib.load("model.pkl") + +# create the flask app +app = Flask(__name__) + + +# app route for the predict endpoint +@app.route("/predict", methods=["POST"]) +def predict(): + try: + # get the input query from the request + data = request.json + query = data.get("query", "") + + if not query: + return jsonify({"error": "No query provided."}), 400 + + # make a prediction + # the model expects an array + prediction = model.predict([query])[0] + bad = bool(prediction) + + return jsonify({"bad": bad}), 200 + + except Exception as error: + return jsonify({"error": str(error)}), 500 + + +if __name__ == "__main__": + app.run(debug=True, host="0.0.0.0", port=5000) diff --git a/server-ml/model.pkl b/server-ml/model.pkl new file mode 100644 index 0000000..7f3aff8 Binary files /dev/null and b/server-ml/model.pkl differ diff --git a/server-ml/requirements.txt b/server-ml/requirements.txt new file mode 100644 index 0000000..0ca250e --- /dev/null +++ b/server-ml/requirements.txt @@ -0,0 +1,3 @@ +flask +scikit-learn +joblib \ No newline at end of file diff --git a/server-ml/training.py b/server-ml/training.py new file mode 100644 index 0000000..74ad56b --- /dev/null +++ b/server-ml/training.py @@ -0,0 +1,35 @@ +import joblib +from sklearn.feature_extraction.text import CountVectorizer +from sklearn.linear_model import LogisticRegression +from sklearn.pipeline import make_pipeline +from sklearn.model_selection import train_test_split + +# random data +data = [ + ("' OR '1'='1", 1), + ("SELECT * FROM users WHERE id=1", 1), + ("DROP TABLE users;", 1), + ("username=admin'--", 1), + ("hello world", 0), + ("this is a normal query", 0), + ("select data from table", 0), + ("just another harmless input", 0), +] + +queries, labels = zip(*data) + +# split data into training and testing sets +X_train, X_test, y_train, y_test = train_test_split( + queries, labels, test_size=0.2, random_state=42 +) + +# build a pipeline with a vectorizer and a logistic regression model +pipeline = make_pipeline(CountVectorizer(), LogisticRegression()) + +# train the model +pipeline.fit(X_train, y_train) + +# save the model to a file +joblib.dump(pipeline, "model.pkl") + +print("Model trained and saved to model.pkl")