CVE-2015-10044 (published 2023-01-15T10:15Z)

A vulnerability classified as critical was found in gophergala sqldump. This vulnerability affects unknown code. The manipulation leads to sql injection. The patch is identified as 76db54e9073b5248b8863e71a63d66a32d567d21. It is recommended to apply a patch to fix this issue. VDB-218350 is the identifier assigned to this vulnerability.

CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-89
cwe_name: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
description: The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
extended_description: 
            
            
         
         

Fix information:
repo_url: https://github.com/gophergala/sqldump
commit_details: repo_url: https://github.com/gophergala/sqldump
author: micha-p
author_date: 2015-01-25 02:26:19+01:00
msg: Protection against sql injection doesnt work with ? for table. Using HTMLEscapeString instead
repository: repo_url: https://github.com/gophergala/sqldump
repo_name: gophergala/sqldump
description: Small tool for database administration
repo_language: Go
owner: gophergala
file_changes: filename: README.md
change_type: ModificationType.MODIFY
diff: @@ -7,13 +7,13 @@ Use your fantasy for best UX and choose high levels of abstraction and imaginati
 
 ## prepare
 
-    sudo mysqladmin --defaults-file=/etc/mysql/debian.cnf create gotestdb
-    sudo mysql --defaults-file=/etc/mysql/debian.cnf -e "GRANT ALL PRIVILEGES  ON gotestdb.*  TO 'go_user'@'localhost' IDENTIFIED BY 'mypassword'  WITH GRANT OPTION;"
-    mysql -p"mypassword" -u go_user gotestdb -e 'create table posts (title varchar(64) default null, start date default null);'
-    mysql -p"mypassword" -u go_user gotestdb -e 'insert into posts values("hello","2015-01-01");'
-    mysql -p"mypassword" -u go_user gotestdb -e 'insert into posts values("more","2015-01-03");'
-    mysql -p"mypassword" -u go_user gotestdb -e 'insert into posts values("end","2015-01-23");'
-    mysql -p"mypassword" -u go_user gotestdb -B -e 'select * from posts;'
+    sudo mysqladmin --defaults-file=/etc/mysql/debian.cnf create galadb
+    sudo mysql --defaults-file=/etc/mysql/debian.cnf -e "GRANT ALL PRIVILEGES  ON galadb.*  TO 'galagopher'@'localhost' IDENTIFIED BY 'mypassword'  WITH GRANT OPTION;"
+    mysql -p"mypassword" -u galagopher galadb -e 'create table posts (title varchar(64) default null, start date default null);'
+    mysql -p"mypassword" -u galagopher galadb -e 'insert into posts values("hello","2015-01-01");'
+    mysql -p"mypassword" -u galagopher galadb -e 'insert into posts values("more","2015-01-03");'
+    mysql -p"mypassword" -u galagopher galadb -e 'insert into posts values("end","2015-01-23");'
+    mysql -p"mypassword" -u galagopher galadb -B -e 'select * from posts;'
 
 ## install
 
@@ -38,7 +38,8 @@ Use your fantasy for best UX and choose high levels of abstraction and imaginati
 
 ## perspectives
 
-. output in tables
+- output in tables
+- menu line
 - choice for different database drivers
 - insert and edit records
 

programming_language: Shell
filename: auth.go
change_type: ModificationType.MODIFY
diff: @@ -1,4 +1,4 @@
-/* no Credentials management needed
+/* no session management needed
  * Credentials are stored at user side using secure cookies
  *
  * credits:
@@ -16,25 +16,29 @@ var cookieHandler = securecookie.New(
 	securecookie.GenerateRandomKey(64),
 	securecookie.GenerateRandomKey(32))
 
-func getCredentials(request *http.Request) (userName string, password string) {
-	if cookie, err := request.Cookie("Credentials"); err == nil {
+func getCredentials(request *http.Request) (userName string, password string, host string, port string) {
+	if cookie, err := request.Cookie("Datasource"); err == nil {
 		cookieValue := make(map[string]string)
-		if err = cookieHandler.Decode("Credentials", cookie.Value, &cookieValue); err == nil {
+		if err = cookieHandler.Decode("Datasource", cookie.Value, &cookieValue); err == nil {
 			userName = cookieValue["user"]
 			password = cookieValue["passwd"]
+			host = cookieValue["host"]
+			port = cookieValue["port"]
 		}
 	}
-	return userName, password
+	return userName, password, host, port
 }
 
-func setCredentials(userName string, pw string, w http.ResponseWriter) {
+func setCredentials( w http.ResponseWriter, userName string, pw string, host string, port string) {
 	value := map[string]string{
 		"user":   userName,
 		"passwd": pw,
+		"host": host,
+		"port": port,
 	}
-	if encoded, err := cookieHandler.Encode("Credentials", value); err == nil {
+	if encoded, err := cookieHandler.Encode("Datasource", value); err == nil {
 		cookie := &http.Cookie{
-			Name:  "Credentials",
+			Name:  "Datasource",
 			Value: encoded,
 			Path:  "/",
 		}
@@ -44,7 +48,7 @@ func setCredentials(userName string, pw string, w http.ResponseWriter) {
 
 func clearCredentials(w http.ResponseWriter) {
 	cookie := &http.Cookie{
-		Name:   "Credentials",
+		Name:   "Datasource",
 		Value:  "",
 		Path:   "/",
 		MaxAge: -1,
@@ -55,8 +59,10 @@ func clearCredentials(w http.ResponseWriter) {
 func loginHandler(w http.ResponseWriter, request *http.Request) {
 	user := request.FormValue("user")
 	pass := request.FormValue("password")
+	host := request.FormValue("host")
+	port := request.FormValue("port")
 	if user != "" && pass != "" {
-		setCredentials(user, pass, w)
+		setCredentials(w, user, pass, host, port)
 	}
 	http.Redirect(w, request, "/", 302)
 }
@@ -69,8 +75,10 @@ func logoutHandler(w http.ResponseWriter, request *http.Request) {
 const loginPage = `
 <h1>Login</h1>
 <form method="post" action="/login">
-   <label for="user">User name</label><input type="text" id="user" name="user">
-   <label for="password">Password</label><input type="password" id="password" name="password">
+   <label for="user">User name</label><input type="text" id="user" name="user"><br>
+   <label for="password">Password</label><input type="password" id="password" name="password"><br>
+   <label for="host">Host</label><input type="text" id="host" name="host" value="localhost"><br>
+   <label for="port">Port</label><input type="text" id="port" name="port" value="3306"><br>
    <button type="submit">Login</button>
 </form>
 `

programming_language: Go
filename: aux.go
change_type: ModificationType.MODIFY
diff: @@ -21,7 +21,7 @@ func linkDeeper(cwd string, link string, name string) string {
 }
 
 // Compose dataSourceName from components and globals
-func dsn(user string, pw string, db string) string {
+func dsn(user string, pw string, host string, port string, db string) string {
 	return user + ":" + pw + "@tcp(" + host + ":" + port + ")/" + db
 }
 

programming_language: Go
filename: dump.go
change_type: ModificationType.MODIFY
diff: @@ -1,7 +1,7 @@
 package main
 
 /* TODO
- * turn into generic functions
+ * turn into more generic functions for printing into tables
  */
 
 import (
@@ -11,13 +11,14 @@ import (
 	"net/http"
 	"strconv"
 	"strings"
+	"text/template"
 )
 
 // Shows selection of databases at top level
 func home(w http.ResponseWriter, r *http.Request) {
 
-	user, pw := getCredentials(r)
-	conn, err := sql.Open("mysql", dsn(user, pw, database))
+	user, pw, h , p := getCredentials(r)
+	conn, err := sql.Open("mysql", dsn(user, pw, h, p, database))
 	checkY(err)
 	defer conn.Close()
 
@@ -41,9 +42,9 @@ func home(w http.ResponseWriter, r *http.Request) {
 //  Dump all tables of a database
 func dumpdb(w http.ResponseWriter, r *http.Request, parray []string) {
 
-	user, pw := getCredentials(r)
+	user, pw, h, p := getCredentials(r)
 	database := parray[0]
-	conn, err := sql.Open("mysql", dsn(user, pw, database))
+	conn, err := sql.Open("mysql", dsn(user, pw, h, p, database))
 	checkY(err)
 	defer conn.Close()
 
@@ -67,18 +68,18 @@ func dumpdb(w http.ResponseWriter, r *http.Request, parray []string) {
 //  Dump all records of a table, one per line
 func dumptable(w http.ResponseWriter, r *http.Request, parray []string) {
 
-	user, pw := getCredentials(r)
+	user, pw, h, p := getCredentials(r)
 	database := parray[0]
 	table := parray[1]
 
-	conn, err := sql.Open("mysql", dsn(user, pw, database))
+	conn, err := sql.Open("mysql", dsn(user, pw, h, p, database))
 	checkY(err)
 	defer conn.Close()
 
-	statement, err := conn.Prepare("select * from ?")
+	statement, err := conn.Prepare("select * from " + template.HTMLEscapeString(table))
 	checkY(err)
 
-	rows, err := statement.Query(table)
+	rows, err := statement.Query()
 	checkY(err)
 	defer rows.Close()
 
@@ -123,15 +124,15 @@ func dumprecord(w http.ResponseWriter, r *http.Request, parray []string) {
 	rec, err := strconv.Atoi(parray[2])
 	checkY(err)
 
-	user, pw := getCredentials(r)
-	conn, err := sql.Open("mysql", dsn(user, pw, database))
+	user, pw, h, p := getCredentials(r)
+	conn, err := sql.Open("mysql", dsn(user, pw, h, p, database))
 	checkY(err)
 	defer conn.Close()
 
-	statement, err := conn.Prepare("select * from ?")
+	statement, err := conn.Prepare("select * from " + template.HTMLEscapeString(table))
 	checkY(err)
 
-	rows, err := statement.Query(table)
+	rows, err := statement.Query()
 	checkY(err)
 	defer rows.Close()
 

programming_language: Go
filename: sqldump.go
change_type: ModificationType.MODIFY
diff: @@ -7,8 +7,6 @@ import (
 )
 
 var base_url = "http://localhost"
-var host = "localhost"
-var port = "3306"
 var database = "information_schema"
 
 func faviconHandler(w http.ResponseWriter, r *http.Request) {
@@ -38,10 +36,10 @@ func pathHandler(w http.ResponseWriter, r *http.Request) {
 }
 
 func indexHandler(w http.ResponseWriter, r *http.Request) {
-	u, _ := getCredentials(r)
+	user , _ , host , port := getCredentials(r)
 
-	if u != "" {
-		fmt.Fprintln(w, "<h1>", u, "</h1>")
+	if user != "" {
+		fmt.Fprintln(w, "<p>", user + "@" + host + ":" + port, "</p>")
 		pathHandler(w, r)
 	} else {
 		loginPageHandler(w, r)

programming_language: Go