CVE-2015-10034 (published 2023-01-09T21:15Z)

A vulnerability has been found in j-nowak workout-organizer and classified as critical. This vulnerability affects unknown code. The manipulation leads to sql injection. The patch is identified as 13cd6c3d1210640bfdb39872b2bb3597aa991279. It is recommended to apply a patch to fix this issue. VDB-217714 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/j-nowak/workout-organizer
commit_details: repo_url: https://github.com/j-nowak/workout-organizer
author: Wojtek Kruk
author_date: 2015-02-03 21:22:56+01:00
msg: Fixed building queries - preventing SQL-injection
repository: repo_url: https://github.com/j-nowak/workout-organizer
repo_name: j-nowak/workout-organizer
repo_language: Java
owner: j-nowak
file_changes: filename: AccountController.java
change_type: ModificationType.MODIFY
diff: @@ -1,7 +1,6 @@
 package controllers;
 
-import java.util.HashMap;
-import java.util.Map;
+import java.sql.Date;
 
 import models.Secured;
 import play.data.DynamicForm;
@@ -19,10 +18,17 @@ public class AccountController extends Controller {
 		String oldPassword = requestData.get("oldPassword");
 		String newPassword = requestData.get("newPassword");
 		String repeatedPassword = requestData.get("repeatedPassword");
+		int userId;
+		try {
+			userId = Integer.parseInt(session(Application.USER_ID));
+		} catch (Exception e) {
+			e.printStackTrace();
+			return badRequest();
+		}
 		
 		if (newPassword.equals(repeatedPassword)) {
-			if (UsersDao.get().checkPasswordForUser(session().get(Application.USER_ID), oldPassword)) {
-				UsersDao.get().changePassword(session().get(Application.USER_ID), newPassword);
+			if (UsersDao.get().checkPasswordForUser(userId, oldPassword)) {
+				UsersDao.get().changePassword(userId, newPassword);
 				return ok();
 			}
 			else {
@@ -35,28 +41,32 @@ public class AccountController extends Controller {
 	}
 	
 	public static Result changeUserInfo() {
-		String userId = session(Application.USER_ID);
 		DynamicForm requestData = Form.form().bindFromRequest();
-		String weight = requestData.get("weight");
-		String height = requestData.get("height");
-		String dateOfBirth = requestData.get("dateOfBirth");
-
-		Map<String, String> toUpdate = new HashMap<String, String>();
-		if (!weight.equals("")) {
-			toUpdate.put("weight", weight);
-		}
-		if (!height.equals("")) {
-			toUpdate.put("height", height);
-		}
-		if (!dateOfBirth.equals("")) {
-			toUpdate.put("date_of_birth", dateOfBirth);
+		Double weight = null;
+		Double height = null;
+		Date dateOfBirth = null;
+		int userId;
+		try {
+			userId = Integer.parseInt(session(Application.USER_ID));
+		} catch (Exception e) {
+			e.printStackTrace();
+			return badRequest();
 		}
-		
 
-		if (toUpdate.size() > 0 && UsersDao.get().update(userId, toUpdate)) {
-			return ok();
-		}
-		else {
+		if (!requestData.get("weight").equals(""))
+			weight = Double.valueOf(requestData.get("weight"));
+		if (!requestData.get("height").equals(""))
+			height = Double.valueOf(requestData.get("height"));
+		if (!requestData.get("dateOfBirth").equals(""))
+			dateOfBirth = Date.valueOf(requestData.get("dateOfBirth"));
+
+		try {
+			if (UsersDao.get().update(userId, weight, height, dateOfBirth))
+				return ok();
+			else
+				return badRequest();
+		} catch (Exception e) {
+			e.printStackTrace();
 			return badRequest();
 		}
 	}

programming_language: Java
filename: Application.java
change_type: ModificationType.MODIFY
diff: @@ -36,8 +36,13 @@ public class Application extends Controller {
     }
     
     public static Result editAccountSettings() {
-    	User user = UsersDao.get().getById(session(USER_ID)); //TODO change session to userId
-    	return ok(account.render(user));
+    	try {
+	    	User user = UsersDao.get().getById(Integer.parseInt(session(USER_ID))); //TODO change session to userId
+	    	return ok(account.render(user));
+    	} catch (Exception e) {
+    		e.printStackTrace();
+    		return badRequest();
+    	}
     }
 
 }

programming_language: Java
filename: UsersController.java
change_type: ModificationType.MODIFY
diff: @@ -30,7 +30,7 @@ public class UsersController extends Controller {
 	
 	public static Result showUser(int foreignerId) {
 		int userId = Integer.parseInt(session("user_id"));
-		User user = UsersDao.get().getById(foreignerId + "");
+		User user = UsersDao.get().getById(foreignerId);
 		boolean isYourFriend = UsersDao.get().areFriends(userId, foreignerId);
 		if (user != null) {
 			return ok(user_info.render(user, isYourFriend));			

programming_language: Java
filename: ExerciseDao.java
change_type: ModificationType.MODIFY
diff: @@ -1,6 +1,7 @@
 package database;
 
 import java.sql.Connection;
+import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
@@ -98,10 +99,13 @@ public class ExerciseDao {
 		Connection connection = null;
 		try {
 			connection = DB.getConnection();
-			String sql = connection.nativeSQL("INSERT INTO exercise_ratings(user_id, exercise_id, rating) VALUES" + 
-					"  (" + userId + ", " + exerciseId + ", " + rating + ");");
-			play.Logger.info("Insert exercise_rating: " + sql);
-			connection.createStatement().execute(sql);
+			PreparedStatement p = connection.prepareStatement("INSERT INTO exercise_ratings(user_id, exercise_id, rating) VALUES (?, ?, ?);");
+			p.setInt(1, userId);
+			p.setInt(2, exerciseId);
+			p.setInt(3, rating);
+			
+			p.executeQuery();
+			p.close();
 		} catch (SQLException e) {
 			e.printStackTrace();
 		} finally {
@@ -123,13 +127,13 @@ public class ExerciseDao {
 		Connection connection = null;
 		try {
 			connection = DB.getConnection();
-			Statement statement = connection.createStatement();
-			ResultSet resultSet = statement.executeQuery("SELECT weight, set_count, reps_per_set" + 
-					"		FROM workout_entries" + 
-					"		JOIN workouts USING (workout_id)" + 
-					"		WHERE user_id = " + userId + " AND exercise_id = " + exerciseId + 
-					"		ORDER BY weight" + 
-					"		LIMIT 1;");
+			PreparedStatement p = connection.prepareStatement("SELECT weight, set_count, reps_per_set"
+					+ "FROM workout_entries "
+					+ "JOIN workouts USING (workout_id) "
+					+ "WHERE user_id = ? AND exercise_id = ? "
+					+ "ORDER BY weight"
+					+ "LIMIT 1;");
+			ResultSet resultSet = p.executeQuery();
 			ExerciseResult result = null;
 			if (resultSet.next()) {
 				result = new ExerciseResult();
@@ -138,7 +142,8 @@ public class ExerciseDao {
 				result.setWeight(resultSet.getInt("weight"));
 				
 			}
-			
+			resultSet.close();
+			p.close();
 			return result;
 		} catch (SQLException e) {
 			e.printStackTrace();

programming_language: Java
filename: GymsDao.java
change_type: ModificationType.MODIFY
diff: @@ -1,6 +1,7 @@
 package database;
 
 import java.sql.Connection;
+import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
@@ -67,10 +68,12 @@ public class GymsDao {
 		Connection connection = null;
 		try {
 			connection = DB.getConnection();
-			String sql = connection.nativeSQL("INSERT INTO gym_ratings(user_id, gym_id, rating) VALUES" + 
-					"  (" + userId + ", " + gymId + ", " + rating + ");");
-			play.Logger.info("Insert gym_rating: " + sql);
-			connection.createStatement().execute(sql);
+			PreparedStatement p = connection.prepareStatement("INSERT INTO gym_ratings(user_id, gym_id, rating) VALUES (?, ?, ?)");
+			p.setInt(1, userId);
+			p.setInt(2, gymId);
+			p.setInt(3, rating);
+			p.executeQuery();
+			p.close();
 		} catch (SQLException e) {
 			e.printStackTrace();
 		} finally {

programming_language: Java
filename: UsersDao.java
change_type: ModificationType.MODIFY
diff: @@ -3,14 +3,12 @@ package database;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.sql.Connection;
+import java.sql.Date;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
 
 import models.Stranger;
 import models.User;
@@ -34,21 +32,26 @@ public class UsersDao {
 			connection = DB.getConnection();
 			String passwordDigest = byteArrayToHexString(MessageDigest
 					.getInstance("SHA-1").digest(user.getPassword().getBytes()));
-			String sql = connection.nativeSQL("INSERT INTO users(login, email, password_digest, first_name, last_name) VALUES" + 
-					"  ('" + user.getLogin() + "','" + user.getEmail() + "','" + passwordDigest + "','" + user.getFirstName() + "','" + user.getLastName() + "')");
-			
-			play.Logger.info("Insert user: " + sql);
-			connection.createStatement().execute(sql);
+			PreparedStatement p = connection.prepareStatement("INSERT INTO users(login, email, password_digest, first_name, last_name) VALUES (?, ?, ?, ?, ?)");
+			p.setString(1, user.getLogin());
+			p.setString(2, user.getEmail());
+			p.setString(3, passwordDigest);
+			p.setString(4, user.getFirstName());
+			p.setString(5, user.getLastName());
+			p.executeQuery();
+			p.close();
 			
-			Statement statement = connection.createStatement();
-			ResultSet result = statement.executeQuery("SELECT * FROM users WHERE login = '" + user.getLogin() +"'");
+			p = connection.prepareStatement("SELECT * FROM users WHERE login = ?");
+			p.setString(1, user.getLogin());
+			ResultSet result = p.executeQuery();
 			if (result.next()){
 				user.setId(result.getInt("user_id"));				
 			}
 			else {
 				throw new SQLException("Insert error");
 			}
-			
+			result.close();
+			p.close();
 			return true;
 		} catch (SQLException e) {
 			e.printStackTrace();
@@ -71,11 +74,13 @@ public class UsersDao {
 		Connection connection = null;
 		try {
 			connection = DB.getConnection();
-			Statement getuserStatement = connection.createStatement();
 			String passwordDigest = byteArrayToHexString(MessageDigest
 					.getInstance("SHA-1").digest(password.getBytes()));
-			ResultSet resultUser = getuserStatement.executeQuery("SELECT * FROM users "
-					+ "WHERE (login = '" + login + "' OR email = '" + login + "') AND password_digest = '" + passwordDigest + "'");
+			PreparedStatement p = connection.prepareStatement("SELECT * FROM users WHERE (login = ? OR email = ?) AND password_digest = ?");
+			p.setString(1, login);
+			p.setString(2, login);
+			p.setString(3, passwordDigest);
+			ResultSet resultUser = p.executeQuery();
 			
 			User user = null;
 			if (resultUser.next()) {
@@ -87,7 +92,7 @@ public class UsersDao {
 			}
 			
 			resultUser.close();
-			getuserStatement.close();
+			p.close();
 			
 			return user;
 		} catch (SQLException e) {
@@ -115,13 +120,14 @@ public class UsersDao {
 		return result;
 	}
 
-	public User getById(String userId) { //TODO change to userId
+	public User getById(int userId) {
 		Connection connection = null;
 		try {
 			connection = DB.getConnection();
-			Statement getuserStatement = connection.createStatement();
-			ResultSet resultUser = getuserStatement.executeQuery("SELECT * FROM users "
-					+ "WHERE user_id = '" + userId + "'");
+			PreparedStatement p = connection.prepareStatement("SELECT * FROM users WHERE user_id = ?");
+			p.setInt(1, userId);
+			
+			ResultSet resultUser = p.executeQuery();
 			
 			User user = null;
 			if (resultUser.next()) {
@@ -137,7 +143,7 @@ public class UsersDao {
 			}
 			
 			resultUser.close();
-			getuserStatement.close();
+			p.close();
 			
 			return user;
 		} catch (SQLException e) {
@@ -154,16 +160,17 @@ public class UsersDao {
 		}
 	}
 
-	public boolean checkPasswordForUser(String userId, String password) {
+	public boolean checkPasswordForUser(int userId, String password) {
 		Connection connection = null;
 		try {
 			String passwordDigest = byteArrayToHexString(MessageDigest
 					.getInstance("SHA-1").digest(password.getBytes()));
 			
 			connection = DB.getConnection();
-			Statement getuserStatement = connection.createStatement();
-			ResultSet resultUser = getuserStatement.executeQuery("SELECT * FROM users "
-					+ "WHERE user_id = '" + userId + "' AND password_digest = '" + passwordDigest + "'");
+			PreparedStatement p = connection.prepareStatement("SELECT * FROM users WHERE user_id = ? AND password_digest = ?");
+			p.setInt(1, userId);
+			p.setString(2, passwordDigest);
+			ResultSet resultUser = p.executeQuery();
 			
 			boolean result;
 			if (resultUser.next()) {
@@ -174,7 +181,7 @@ public class UsersDao {
 			}
 			
 			resultUser.close();
-			getuserStatement.close();
+			p.close();
 			return result;
 		} catch (SQLException e) {
 			e.printStackTrace();
@@ -193,19 +200,20 @@ public class UsersDao {
 		}
 	}
 
-	public void changePassword(String userId, String password) {
+	public void changePassword(int userId, String password) {
 		Connection connection = null;
 		try {
 			String passwordDigest = byteArrayToHexString(MessageDigest
 					.getInstance("SHA-1").digest(password.getBytes()));
 			
 			connection = DB.getConnection();
-			Statement statement = connection.createStatement();
-			String sql = "UPDATE users SET password_digest = '"+ passwordDigest + "' where user_id = '" + userId + "';";
-			statement.executeUpdate(sql);
+			PreparedStatement p = connection.prepareStatement("UPDATE users SET password_digest = ? where user_id = ?");
+			p.setString(1, passwordDigest);;
+			p.setInt(2, userId);
+			p.executeQuery();
+			p.close();
 			play.Logger.info("Password changed!");
 			
-			statement.close();
 		} catch (SQLException e) {
 			e.printStackTrace();
 		} catch (NoSuchAlgorithmException e) {
@@ -221,23 +229,38 @@ public class UsersDao {
 		}
 	}
 
-	public boolean update(String userId, Map<String, String> toUpdate) {
+	public boolean update(int userId, Double weight, Double height, Date dateOfBirth) {
 		Connection connection = null;
 		try {	
 			connection = DB.getConnection();
-			Statement statement = connection.createStatement();
-			String sql = "UPDATE users SET ";
-			for (Entry<String, String> entry : toUpdate.entrySet()) {
-				sql += entry.getKey() + " = '" + entry.getValue() + "', ";
-			}
+			String sql = "UPDATE users SET   ";
+			if (weight != null)
+				sql += "weight = ?, ";
+			if (height != null)
+				sql += "height = ?, ";
+			if (dateOfBirth != null)
+				sql += "date_of_birth = ?, ";
 			sql = sql.substring(0, sql.length() - 2);
-			sql += " where user_id = '" + userId + "';";
+			sql += " WHERE user_id = ?";
 			
-			play.Logger.info(sql);
-			statement.executeUpdate(sql);
+			PreparedStatement p = connection.prepareStatement(sql);
+
+			int i = 1;
+			if (weight != null)
+				p.setDouble(i++, weight);
+			if (height != null)
+				p.setDouble(i++, height);
+			if (dateOfBirth != null)
+				p.setDate(i++, dateOfBirth);
 			
+			p.setInt(i, userId);
+
+			play.Logger.info(sql);
+
+			if (i > 1)
+				p.executeUpdate();
 			
-			statement.close();
+			p.close();
 			return true;
 		} catch (SQLException e) {
 			e.printStackTrace();
@@ -259,8 +282,9 @@ public class UsersDao {
 		Connection connection = null;
 		try {	
 			connection = DB.getConnection();
-			Statement statement = connection.createStatement();
-			ResultSet resultSet = statement.executeQuery("SELECT * FROM random_strangers_of_user(" + userId + ")");
+			PreparedStatement p = connection.prepareStatement("SELECT * FROM random_strangers_of_user(?)");
+			p.setInt(1, userId);
+			ResultSet resultSet = p.executeQuery();
 			
 			Stranger stranger = null;
 			while (resultSet.next()) {
@@ -272,7 +296,7 @@ public class UsersDao {
 			}
 			
 			resultSet.close();
-			statement.close();
+			p.close();
 		} catch (SQLException e) {
 			e.printStackTrace();
 		} finally {

programming_language: Java
filename: WorkoutDao.java
change_type: ModificationType.MODIFY
diff: @@ -4,7 +4,6 @@ import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.sql.Statement;
 import java.sql.Timestamp;
 import java.sql.Types;
 import java.util.ArrayList;
@@ -25,18 +24,55 @@ public class WorkoutDao {
 	private WorkoutDao() {}
 	
 	public List<Workout> getAll() {
-		return getWorkouts("SELECT workouts.*, gyms.gym_name "
-				+ "FROM workouts "
-				+ "LEFT JOIN gyms using (gym_id) "
-				+ "ORDER BY workouts.finished_at DESC");
+		List<Workout> workouts = new ArrayList<Workout>();
+		Connection connection = null;
+		try {
+			connection = DB.getConnection();
+			PreparedStatement p = connection.prepareStatement("SELECT workouts.*, gyms.gym_name "
+					+ "FROM workouts "
+					+ "LEFT JOIN gyms using (gym_id) "
+					+ "ORDER BY workouts.finished_at DESC");
+			workouts = buildWorkouts(p.executeQuery());
+			p.close();
+		} catch (SQLException e) {
+			e.printStackTrace();
+		} finally {
+			if (connection != null) {
+				try {
+					connection.close();
+				} catch (SQLException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		return workouts;
 	}
 	
 	public List<Workout> getUserWorkouts(int userId) {
-		return getWorkouts("SELECT workouts.*, gyms.gym_name "
-				+ "FROM workouts "
-				+ "LEFT JOIN gyms using (gym_id) "
-				+ "WHERE user_id = " + userId + " "
-				+ "ORDER BY workouts.finished_at DESC");
+		List<Workout> workouts = new ArrayList<Workout>();
+		Connection connection = null;
+		try {
+			connection = DB.getConnection();
+			PreparedStatement p = connection.prepareStatement("SELECT workouts.*, gyms.gym_name "
+					+ "FROM workouts "
+					+ "LEFT JOIN gyms using (gym_id) "
+					+ "WHERE user_id = ? "
+					+ "ORDER BY workouts.finished_at DESC");
+			p.setInt(1, userId);
+			workouts = buildWorkouts(p.executeQuery());
+			p.close();
+		} catch (SQLException e) {
+			e.printStackTrace();
+		} finally {
+			if (connection != null) {
+				try {
+					connection.close();
+				} catch (SQLException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		return workouts;
 	}
 	
 	public boolean create(Workout workout) {
@@ -116,15 +152,10 @@ public class WorkoutDao {
 		}
 	}
 	
-	private List<Workout> getWorkouts(String sql) {
+	private List<Workout> buildWorkouts(ResultSet resultSet) {
 		List<Workout> workouts = new ArrayList<Workout>();
-		
-		Connection connection = null;
+
 		try {
-			connection = DB.getConnection();
-			Statement statement = connection.createStatement();
-			ResultSet resultSet = statement.executeQuery(sql);
-			
 			while (resultSet.next()) {
 				int id = resultSet.getInt("workout_id");
 				int userId = resultSet.getInt("user_id");
@@ -138,19 +169,9 @@ public class WorkoutDao {
 				w.setNote(note);
 				workouts.add(w);
 			}
-			
 			resultSet.close();
-			statement.close();
 		} catch (SQLException e) {
 			e.printStackTrace();
-		} finally {
-			if (connection != null) {
-				try {
-					connection.close();
-				} catch (SQLException e) {
-					e.printStackTrace();
-				}
-			}
 		}
 
 		return workouts;

programming_language: Java