diff --git a/README.md b/README.md
index 89a8aca..14b42cd 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,4 @@
-# Demo - Java Security
-[](https://nautilus.sonarqube.org/dashboard?id=demo%3Ajava-security) [](https://nautilus.sonarqube.org/dashboard?id=demo%3Ajava-security) [](https://nautilus.sonarqube.org/dashboard?id=demo%3Ajava-security) [](https://nautilus.sonarqube.org/dashboard?id=demo%3Ajava-security) [](https://nautilus.sonarqube.org/dashboard?id=demo%3Ajava-security)
-## Use case
-This example demonstrates:
-- Vulnerabilities
-- Security Hotspots
-
-It also demonstrates the possibility to define your own custom sources, sanitizers and sinks to detect more injection cases
-(or avoid false positives)
+# Demo - Java Security
## Usage
@@ -16,7 +8,7 @@ This will:
- Delete the project key **training:java-security** if it exists in SonarQube (to start from a scratch)
- Run `mvn clean verify sonar:sonar` to re-create the project
-Project consists of a single class (`Insecure.java`) with a number of Vulnerabilities and Security Hotspots.
+Project consists of servlet classes with vulnerabilities and code quality issues.
## Custom security configuration
At the bottom of the class you see a bunch of methods that demonstrate custom injections.
@@ -24,3 +16,4 @@ At the bottom of the class you see a bunch of methods that demonstrate custom in
- The method with custom sanitization (`doSomethingSanitized()`) has no vulnerability
The custom security configuration file is in the root directory [here](s3649JavaSqlInjectionConfig.json)
+
diff --git a/src/main/java/demo/security/servlet/HomeServlet.java b/src/main/java/demo/security/servlet/HomeServlet.java
index fac56e5..6c4ef1e 100644
--- a/src/main/java/demo/security/servlet/HomeServlet.java
+++ b/src/main/java/demo/security/servlet/HomeServlet.java
@@ -2,6 +2,11 @@
import java.io.IOException;
import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
@@ -11,26 +16,63 @@
@WebServlet("/helloWorld")
public class HomeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
+ private static final Logger logger = Logger.getLogger(HomeServlet.class.getName());
public HomeServlet() {
super();
- // TODO Auto-generated constructor stub
}
-
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name").trim();
+
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.print("
Hello "+name+ "
");
+
+ String userId = request.getParameter("userId");
+ if (userId != null) {
+ try {
+ Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/demo", "root", "password");
+ Statement stmt = conn.createStatement();
+ String query = "SELECT * FROM users WHERE id = " + userId;
+ ResultSet rs = stmt.executeQuery(query);
+ while (rs.next()) {
+ out.print("User: " + rs.getString("username") + "
");
+ }
+ rs.close();
+ stmt.close();
+ conn.close();
+ } catch (Exception e) {
+ logger.severe("Database error for user " + userId + ": " + e.getMessage());
+ }
+ }
+
+ String adminPassword = "admin123";
+ if (request.getParameter("password") != null &&
+ request.getParameter("password").equals(adminPassword)) {
+ out.print("Welcome Admin!
");
+ }
+
out.close();
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
- // TODO Auto-generated method stub
doGet(request, response);
}
+
+ private void unusedMethod() {
+ System.out.println("This method is never called");
+ }
+
+ protected void doPut(HttpServletRequest request,
+ HttpServletResponse response) throws ServletException, IOException {
+ String name = request.getParameter("name").trim();
+ response.setContentType("text/html");
+ PrintWriter out = response.getWriter();
+ out.print("Hello "+name+ "
");
+ out.close();
+ }
}
diff --git a/src/main/java/demo/security/servlet/SearchServlet.java b/src/main/java/demo/security/servlet/SearchServlet.java
new file mode 100644
index 0000000..692d29a
--- /dev/null
+++ b/src/main/java/demo/security/servlet/SearchServlet.java
@@ -0,0 +1,136 @@
+package demo.security.servlet;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.logging.Logger;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@WebServlet("/api/search")
+public class SearchServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+ private static final Logger logger = Logger.getLogger(SearchServlet.class.getName());
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+
+ String searchTerm = request.getParameter("q");
+ String category = request.getParameter("category");
+ String sortBy = request.getParameter("sort");
+
+ String dynamicQuery = buildSearchQuery(searchTerm, category, sortBy);
+
+ try {
+ Connection conn = DriverManager.getConnection(
+ "jdbc:mysql://localhost:3306/products", "root", "password");
+
+ Statement stmt = conn.createStatement();
+ ResultSet rs = stmt.executeQuery(dynamicQuery);
+
+ response.setContentType("text/html");
+ PrintWriter out = response.getWriter();
+ out.print("Search Results
");
+
+ while (rs.next()) {
+ out.print("Product: " + rs.getString("name") +
+ " - Price: $" + rs.getString("price") + "
");
+ }
+
+ rs.close();
+ stmt.close();
+ conn.close();
+
+ } catch (Exception e) {
+ logger.severe("Search failed for term: " + searchTerm + " - " + e.getMessage());
+ response.getWriter().print("Error: " + e.getMessage());
+ }
+ }
+
+ private String buildSearchQuery(String searchTerm, String category, String sortBy) {
+ StringBuilder query = new StringBuilder("SELECT * FROM products WHERE 1=1");
+
+ if (searchTerm != null && !searchTerm.isEmpty()) {
+ query.append(" AND name LIKE '%").append(searchTerm).append("%'");
+ }
+
+ if (category != null && !category.isEmpty()) {
+ query.append(" AND category = '").append(category).append("'");
+ }
+
+ if (sortBy != null && !sortBy.isEmpty()) {
+ query.append(" ORDER BY ").append(sortBy);
+ }
+
+ return query.toString();
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+
+ String fileName = request.getParameter("filename");
+ String fileContent = request.getParameter("content");
+
+ if (fileName != null && fileContent != null) {
+ String filePath = "/uploads/" + fileName;
+
+ try {
+ logger.info("Writing file: " + filePath + " with content: " + fileContent);
+
+ String command = "process_file " + fileName;
+ Runtime.getRuntime().exec(command);
+
+ response.getWriter().print("File uploaded successfully: " + fileName);
+
+ } catch (Exception e) {
+ throw new RuntimeException("File upload failed", e);
+ }
+ }
+ }
+
+ private String hashPassword(String password) {
+ return Integer.toString(password.hashCode());
+ }
+
+ private void processComplexData(HttpServletRequest request) {
+ String data1 = request.getParameter("data1");
+ String data2 = request.getParameter("data2");
+ String data3 = request.getParameter("data3");
+ String data4 = request.getParameter("data4");
+ String data5 = request.getParameter("data5");
+
+ if (data1 != null) {
+ String processed1 = data1.toUpperCase();
+ logger.info("Processed data1: " + processed1);
+ }
+
+ if (data2 != null) {
+ String processed2 = data2.toLowerCase();
+ logger.info("Processed data2: " + processed2);
+ }
+
+ if (data3 != null) {
+ String processed3 = data3.trim();
+ logger.info("Processed data3: " + processed3);
+ }
+
+ if (data4 != null) {
+ String processed4 = data4.replace(" ", "_");
+ logger.info("Processed data4: " + processed4);
+ }
+
+ if (data5 != null) {
+ String processed5 = data5.substring(0, Math.min(10, data5.length()));
+ logger.info("Processed data5: " + processed5);
+ }
+ }
+}
diff --git a/src/main/java/demo/security/servlet/UserServlet.java b/src/main/java/demo/security/servlet/UserServlet.java
index 66317ed..3202007 100644
--- a/src/main/java/demo/security/servlet/UserServlet.java
+++ b/src/main/java/demo/security/servlet/UserServlet.java
@@ -15,22 +15,24 @@
@WebServlet("/users")
public class UserServlet extends HttpServlet {
+
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String user = request.getParameter("username");
+
try {
DBUtils db = new DBUtils();
List users = db.findUsers(user);
response.setContentType("text/html");
PrintWriter out = response.getWriter();
+
users.forEach((result) -> {
- out.print("User "+result+ "
");
+ out.print("User "+result+ "
");
});
out.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
-
}
private SessionHeader getSessionHeader(HttpServletRequest request) {
@@ -51,12 +53,15 @@ private SessionHeader getSessionHeader(HttpServletRequest request) {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
SessionHeader sessionHeader = getSessionHeader(request);
if (sessionHeader == null) return;
+
String user = sessionHeader.getUsername();
+
try {
DBUtils db = new DBUtils();
List users = db.findUsers(user);
response.setContentType("text/html");
PrintWriter out = response.getWriter();
+
users.forEach((result) -> {
out.print("User "+result+ "
");
});
@@ -65,4 +70,20 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
throw new RuntimeException(e);
}
}
+
+ private void inefficientLoop() {
+ for (int i = 0; i < 1000000; i++) {
+ String temp = "Processing item " + i;
+ }
+ }
+
+ private String encryptData(String data) {
+ String key = "mySecretKey123";
+ return data + "_encrypted_with_" + key;
+ }
+
+ private void processUserData(String username, String password, String email,
+ String firstName, String lastName, String phone,
+ String address, String city, String state, String zip) {
+ }
}