added sql injection simulation for authentication on server

This commit is contained in:
Vomitblood 2024-11-12 11:53:55 +08:00
parent 7232aed4ef
commit 0afbdd97d9
4 changed files with 96 additions and 12 deletions

View file

@ -33,6 +33,7 @@ PGPASSWORD=asdfpassword
!only listening on localhost is supported. DO NOT run this on a public ip.
- `/health`
- `/setup-demo-db`
- `/nuke-db`
- `/fetch-all-users`
@ -40,7 +41,9 @@ PGPASSWORD=asdfpassword
### SQL Injection
- `/sql-execute`
- `/login-sql`
- `/secure-sql-execute`
- `/secure-login-sql`
- `/secure-get-user`
#### 1. Parameterization of Queries

View file

@ -21,7 +21,9 @@ func ServeApi() {
http.HandleFunc("/nuke-db", db.NukeDb)
http.HandleFunc("/fetch-all-users", db.FetchAllUsers)
http.HandleFunc("/execute-sql", sql_injection.ExecuteSql)
http.HandleFunc("/login-sql", sql_injection.LoginSql)
http.HandleFunc("/secure-execute-sql", sql_injection.SecureExecuteSql)
http.HandleFunc("/secure-login-sql", sql_injection.SecureLoginSql)
http.HandleFunc("/secure-get-user", sql_injection.SecureGetUser)
log.Println("Server is running on http://localhost:5000")
if err := http.ListenAndServe(":5000", nil); err != nil {

View file

@ -46,6 +46,50 @@ func ExecuteSql(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(response))
}
// unsecure login
// login endpoint with sql injection vulnerability
func LoginSql(w http.ResponseWriter, r *http.Request) {
// parse the request body to get username and password
var credentials struct {
Username string `json:"username"`
Password string `json:"password"`
}
// decode the json body
if err := json.NewDecoder(r.Body).Decode(&credentials); err != nil {
http.Error(w, "Invalid request format", http.StatusBadRequest)
return
}
defer r.Body.Close()
// construct the unsafe query
query := fmt.Sprintf(
"SELECT id, username FROM users WHERE username = '%s' AND password = '&s'",
credentials.Username,
credentials.Password,
)
// execute the query without sanitizing the input
var id int
var username string
err := db.DbPool.QueryRow(context.Background(), query).Scan(&id, &username)
if err != nil {
http.Error(w, "Invalid credentials", http.StatusUnauthorized)
return
}
// if the user is found, return success response
response := map[string]interface{}{
"message": "Login successful",
"user_id": id,
"username": username,
}
if err := json.NewEncoder(w).Encode(response); err != nil {
http.Error(w, "Failed to encode response", http.StatusInternalServerError)
log.Printf("JSON encoding error: %v", err)
}
}
// secure version
// only allow parameterized queries with validation
func SecureExecuteSql(w http.ResponseWriter, r *http.Request) {
@ -95,7 +139,7 @@ func SecureExecuteSql(w http.ResponseWriter, r *http.Request) {
// return json response
jsonResp, err := json.Marshal(response)
if err != nil {
http.Error(w, "Failed to encode response as JSON", http.StatusInternalServerError)
http.Error(w, "Failed to encode response", http.StatusInternalServerError)
return
}
@ -103,6 +147,41 @@ func SecureExecuteSql(w http.ResponseWriter, r *http.Request) {
w.Write(jsonResp)
}
// secure login
func SecureLoginSql(w http.ResponseWriter, r *http.Request) {
var credentials struct {
Username string `json:"username"`
Password string `json:"password"`
}
if err := json.NewDecoder(r.Body).Decode(&credentials); err != nil {
http.Error(w, "Invalid request format", http.StatusBadRequest)
return
}
defer r.Body.Close()
// secure version using parameterized queries
query := "SELECT id, username FROM users WHERE username = $1 AND password = $2"
var id int
var username string
err := db.DbPool.QueryRow(context.Background(), query, credentials.Username, credentials.Password).Scan(&id, &username)
if err != nil {
http.Error(w, "Invalid credentials", http.StatusUnauthorized)
return
}
// send back the response if great success
response := map[string]interface{}{
"message": "Login successful",
"user_id": id,
"username": username,
}
if err := json.NewEncoder(w).Encode(response); err != nil {
http.Error(w, "Failed to encode response", http.StatusInternalServerError)
log.Printf("JSON encoding error: %v", err)
}
}
// even more secure
func SecureGetUser(w http.ResponseWriter, r *http.Request) {
// decode the json body