login and registration unsecured

This commit is contained in:
Vomitblood 2025-01-14 03:50:45 +08:00
parent 53c0ada12e
commit ffbdd9d427
11 changed files with 71 additions and 22 deletions

View file

@ -41,7 +41,9 @@ PGPASSWORD=asdfpassword
### SQL Injection
- `/unsecure-register-sql`
- `/secure-register-sql`
- `/unsecure-login-sql`
- `/secure-login-sql`
#### 1. Parameterization of Queries

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -17,7 +17,7 @@ export const HeaderLogo: FC<HeaderLogoProps> = ({ sx }) => {
alt="Logo"
height={40}
priority
src="images/logo.gif"
src="images/logo.webp"
width={40}
/>
<Typography

View file

@ -9,9 +9,9 @@ export const ServerUrlInput = () => {
return (
<TextField
fullWidth
label='Backend server URL'
onChange={(event) => setServerUrl(event.target.value)}
size='small'
label="Backend server URL"
// onChange={(event) => setServerUrl(event.target.value)}
size="small"
value={serverUrl}
/>
);

View file

@ -30,12 +30,12 @@ export const Home = () => {
CSPJ Application Attack Simulator
</Typography>
</Box>
<Button
{/* <Button
href="https://github.com/cspj-nyp/cspj-application"
sx={{ mb: 2 }}
>
Need help getting started?
</Button>
</Button> */}
</Box>
<Grid2
container

View file

@ -1,10 +1,11 @@
import { Box, TextField, Typography } from "@mui/material";
import { LoadingButton } from "@mui/lab";
import { Box, FormControlLabel, Switch, TextField, Typography } from "@mui/material";
import { fetch } from "@tauri-apps/plugin-http";
import { useAtom } from "jotai";
import { useState } from "react";
import { useNotification } from "../../../contexts/NotificationContext";
import { serverUrlAtom } from "../../../lib/jotai";
import { HeaderLogo } from "../../Generic/HeaderLogo";
import { LoadingButton } from "@mui/lab";
export const SqlInjectionLogin = () => {
// contexts
@ -18,6 +19,7 @@ export const SqlInjectionLogin = () => {
const [passwordValueRaw, setPasswordValueRaw] = useState<string>("");
const [errorMsg, setErrorMsg] = useState<string>("");
const [loginLoading, setLoginLoading] = useState<boolean>(false);
const [secured, setSecured] = useState<boolean>(false);
const nextClickEvent = async () => {
// reset the error messages
@ -35,9 +37,11 @@ export const SqlInjectionLogin = () => {
// start loading indicator
setLoginLoading(true);
const endpointUrl = serverUrl + (secured ? "/secure-login-sql" : "/unsecure-login-sql");
try {
// make request good
const response = await fetch(serverUrl + "/register-sql", {
const response = await fetch(endpointUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
@ -100,7 +104,7 @@ export const SqlInjectionLogin = () => {
label="Email"
onChange={(e: { target: { value: string } }) => setEmailValueRaw(e.target.value)}
size="small"
type="email"
type="text"
value={emailValueRaw}
sx={{ mb: 2 }}
variant="outlined"
@ -122,9 +126,20 @@ export const SqlInjectionLogin = () => {
sx={{
display: "flex",
flexDirection: "row",
justifyContent: "end",
justifyContent: "space-between",
}}
>
<FormControlLabel
control={
<Switch
checked={secured}
onChange={(e) => {
setSecured(e.target.checked);
}}
/>
}
label="Use secure endpoint"
/>
<LoadingButton
loading={loginLoading}
type="submit"

View file

@ -1,11 +1,11 @@
import { LoadingButton } from "@mui/lab";
import { Box, LinearProgress, TextField, Typography } from "@mui/material";
import { Box, FormControlLabel, LinearProgress, Switch, TextField, Typography } from "@mui/material";
import { fetch } from "@tauri-apps/plugin-http";
import { useAtom } from "jotai";
import { useState } from "react";
import { useNotification } from "../../../contexts/NotificationContext";
import { serverUrlAtom } from "../../../lib/jotai";
import { HeaderLogo } from "../../Generic/HeaderLogo";
import { useNotification } from "../../../contexts/NotificationContext";
export const SqlInjectionRegister = () => {
// contexts
@ -25,6 +25,7 @@ export const SqlInjectionRegister = () => {
);
const [passwordStrengthInfo, setPasswordStrengthInfo] = useState("Enter a password");
const [registerLoading, setRegisterLoading] = useState<boolean>(false);
const [secured, setSecured] = useState<boolean>(false);
let newPasswordStrengthInfo = "Enter a password";
@ -105,9 +106,12 @@ export const SqlInjectionRegister = () => {
// start loading indicator
setRegisterLoading(true);
// construct endpoint url
const endpointUrl = serverUrl + (secured ? "/secure-register-sql" : "/unsecure-register-sql");
try {
// make request good
const response = await fetch(serverUrl + "/secure-register-sql", {
const response = await fetch(endpointUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
@ -171,7 +175,7 @@ export const SqlInjectionRegister = () => {
label="Email"
onChange={(e: { target: { value: string } }) => setEmailValueRaw(e.target.value)}
size="small"
type="email"
type="text"
value={emailValueRaw}
sx={{ mb: 2 }}
variant="outlined"
@ -237,9 +241,20 @@ export const SqlInjectionRegister = () => {
sx={{
display: "flex",
flexDirection: "row",
justifyContent: "end",
justifyContent: "space-between",
}}
>
<FormControlLabel
control={
<Switch
checked={secured}
onChange={(e) => {
setSecured(e.target.checked);
}}
/>
}
label="Use secure endpoint"
/>
<LoadingButton
loading={registerLoading}
type="submit"

View file

@ -13,4 +13,5 @@ type ServerConnection = "connected" | "connecting" | "disconnected";
export const serverConnectionAtom = atom<ServerConnection>("disconnected");
// store the url of the backend server
export const serverUrlAtom = atom("");
// TODO: let user enter their own backend server url
export const serverUrlAtom = atom("http://localhost:5000");

View file

@ -8,6 +8,7 @@ import (
"net/http"
"github.com/jackc/pgx/v5/pgxpool"
"golang.org/x/crypto/bcrypt"
)
// db connection info
@ -75,6 +76,17 @@ func DbHealthCheck(w http.ResponseWriter, r *http.Request) {
// setup demo db
func SetupDemoDb(w http.ResponseWriter, r *http.Request) {
// default password for demo users
defaultPassword := "Password!23"
// Hash the default password
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(defaultPassword), bcrypt.DefaultCost)
if err != nil {
http.Error(w, "Error hashing password", http.StatusInternalServerError)
log.Printf("Error hashing password: %v", err)
return
}
// create table and insert demo data
createTableSQL := `
CREATE TABLE IF NOT EXISTS users (
@ -87,13 +99,13 @@ func SetupDemoDb(w http.ResponseWriter, r *http.Request) {
// avoid duplicate entries and specify roles
insertDataSQL := `
INSERT INTO users (email, password, role) VALUES
('alice@example.com', 'asdfalicepassword', 'user'),
('bob@example.com', 'asdfbobpassword', 'user'),
('charlie@example.com', 'asdfcharliepassword', 'admin')
('alice@example.com', $1, 'user'),
('bob@example.com', $2, 'user'),
('charlie@example.com', $3, 'admin')
`
// execute create table
_, err := DbPool.Exec(context.Background(), createTableSQL)
_, err = DbPool.Exec(context.Background(), createTableSQL)
if err != nil {
http.Error(w, "Failed to create table", http.StatusInternalServerError)
log.Printf("Error creating table: %v", err)
@ -101,7 +113,7 @@ func SetupDemoDb(w http.ResponseWriter, r *http.Request) {
}
// execute insert demo data
_, err = DbPool.Exec(context.Background(), insertDataSQL)
_, err = DbPool.Exec(context.Background(), insertDataSQL, hashedPassword, hashedPassword, hashedPassword)
if err != nil {
http.Error(w, "Failed to insert demo data", http.StatusInternalServerError)
log.Printf("Error inserting demo data: %v", err)

View file

@ -21,8 +21,11 @@ func ServeApi() {
http.HandleFunc("/setup-demo-db", db.SetupDemoDb)
http.HandleFunc("/nuke-db", db.NukeDb)
http.HandleFunc("/fetch-all-users", db.FetchAllUsers)
http.HandleFunc("/unsecure-register-sql", sql_injection.UnsecureRegisterSql)
http.HandleFunc("/secure-register-sql", sql_injection.SecureRegisterSql)
http.HandleFunc("/unsecure-login-sql", sql_injection.UnsecureLoginSql)
http.HandleFunc("/secure-login-sql", sql_injection.SecureLoginSql)
log.Println("Server is running on http://localhost:5000")
if err := http.ListenAndServe(":5000", nil); err != nil {
log.Fatalf("Failed to start server: %v", err)

View file

@ -59,6 +59,7 @@ func UnsecureRegisterSql(w http.ResponseWriter, r *http.Request) {
// hash the password
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(credentials.Password), bcrypt.DefaultCost)
fmt.Println(hashedPassword)
if err != nil {
http.Error(w, "Error hashing password", http.StatusInternalServerError)
return