Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions src/main/java/org/owasp/benchmark/testcode/Benchmark00898.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/**
* OWASP Benchmark Project v1.2
*
* <p>This file is part of the Open Web Application Security Project (OWASP) Benchmark Project. For
* details, please see <a
* href="https://owasp.org/www-project-benchmark/">https://owasp.org/www-project-benchmark/</a>.
*
* <p>The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation, version 2.
*
* <p>The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* @author Nick Sanidas
* @created 2015
*/
package org.owasp.benchmark.testcode;

import java.io.IOException;
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(value = "/weakrand-01/Benchmark00898")
public class Benchmark00898 extends HttpServlet {

private static final long serialVersionUID = 1L;

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}

@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");

org.owasp.benchmark.helpers.SeparateClassRequest scr =
new org.owasp.benchmark.helpers.SeparateClassRequest(request);
String param = scr.getTheValue("Benchmark00898");

String bar = "";
if (param != null) {
bar =
new String(
org.apache.commons.codec.binary.Base64.decodeBase64(
org.apache.commons.codec.binary.Base64.encodeBase64(
param.getBytes())));
}

byte[] bytes = new byte[10];
new java.util.Random().nextBytes(bytes);
String rememberMeKey = org.owasp.esapi.ESAPI.encoder().encodeForBase64(bytes, true);

String user = "Byron";
String fullClassName = this.getClass().getName();
String testCaseNumber =
fullClassName.substring(fullClassName.lastIndexOf('.') + 1 + "Benchmark".length());
user += testCaseNumber;

String cookieName = "rememberMe" + testCaseNumber;

boolean foundUser = false;
javax.servlet.http.Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (int i = 0; !foundUser && i < cookies.length; i++) {
javax.servlet.http.Cookie cookie = cookies[i];
if (cookieName.equals(cookie.getName())) {
if (cookie.getValue().equals(request.getSession().getAttribute(cookieName))) {
foundUser = true;
}
}
}
}

if (foundUser) {
response.getWriter().println("Welcome back: " + user + "<br/>");
} else {
javax.servlet.http.Cookie rememberMe =
new javax.servlet.http.Cookie(cookieName, rememberMeKey);

Check failure

Code scanning / CodeQL

Insecure randomness High test

Potential Insecure randomness due to a
Insecure randomness source.
.

Copilot Autofix

AI about 20 hours ago

To fix the problem, replace the use of java.util.Random with a cryptographically secure RNG such as java.security.SecureRandom when generating the bytes for rememberMeKey. This preserves existing functionality (random remember‑me tokens) while making them unpredictable to an attacker.

Concretely, within doPost in Benchmark00898.java, change the line that currently creates a new java.util.Random and calls nextBytes so that it uses a java.security.SecureRandom instance instead. Since this class doesn’t currently import SecureRandom, add an import for java.security.SecureRandom at the top of the file. No other logic needs to change: nextBytes(byte[]) exists on SecureRandom with the same signature, and the subsequent ESAPI Base64 encoding and cookie handling remain unchanged.

Specifically:

  • Add import java.security.SecureRandom; near the other imports.
  • Replace new java.util.Random().nextBytes(bytes); with new SecureRandom().nextBytes(bytes);.

No new helper methods or fields are required; using a local SecureRandom instance is sufficient for this context.

Suggested changeset 1
src/main/java/org/owasp/benchmark/testcode/Benchmark00898.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/main/java/org/owasp/benchmark/testcode/Benchmark00898.java b/src/main/java/org/owasp/benchmark/testcode/Benchmark00898.java
--- a/src/main/java/org/owasp/benchmark/testcode/Benchmark00898.java
+++ b/src/main/java/org/owasp/benchmark/testcode/Benchmark00898.java
@@ -18,6 +18,7 @@
 package org.owasp.benchmark.testcode;
 
 import java.io.IOException;
+import java.security.SecureRandom;
 import javax.servlet.ServletException;
 import javax.servlet.annotation.WebServlet;
 import javax.servlet.http.HttpServlet;
@@ -54,7 +55,7 @@
         }
 
         byte[] bytes = new byte[10];
-        new java.util.Random().nextBytes(bytes);
+        new SecureRandom().nextBytes(bytes);
         String rememberMeKey = org.owasp.esapi.ESAPI.encoder().encodeForBase64(bytes, true);
 
         String user = "Byron";
EOF
@@ -18,6 +18,7 @@
package org.owasp.benchmark.testcode;

import java.io.IOException;
import java.security.SecureRandom;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
@@ -54,7 +55,7 @@
}

byte[] bytes = new byte[10];
new java.util.Random().nextBytes(bytes);
new SecureRandom().nextBytes(bytes);
String rememberMeKey = org.owasp.esapi.ESAPI.encoder().encodeForBase64(bytes, true);

String user = "Byron";
Copilot is powered by AI and may make mistakes. Always verify output.
rememberMe.setSecure(true);
rememberMe.setHttpOnly(true);
rememberMe.setDomain(new java.net.URL(request.getRequestURL().toString()).getHost());
rememberMe.setPath(request.getRequestURI()); // i.e., set path to JUST this servlet
// e.g., /benchmark/sql-01/Benchmark01001
request.getSession().setAttribute(cookieName, rememberMeKey);
response.addCookie(rememberMe);
response.getWriter()
.println(
user
+ " has been remembered with cookie: "
+ rememberMe.getName()
+ " whose value is: "
+ rememberMe.getValue()
+ "<br/>");
}

response.getWriter().println("Randomness java.util.Random.nextBytes() executed");
}
}
116 changes: 116 additions & 0 deletions src/main/java/org/owasp/benchmark/testcode/Benchmark00899.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/**
* OWASP Benchmark Project v1.2
*
* <p>This file is part of the Open Web Application Security Project (OWASP) Benchmark Project. For
* details, please see <a
* href="https://owasp.org/www-project-benchmark/">https://owasp.org/www-project-benchmark/</a>.
*
* <p>The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation, version 2.
*
* <p>The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* @author Nick Sanidas
* @created 2015
*/
package org.owasp.benchmark.testcode;

import java.io.IOException;
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(value = "/weakrand-01/Benchmark00899")
public class Benchmark00899 extends HttpServlet {

private static final long serialVersionUID = 1L;

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}

@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");

org.owasp.benchmark.helpers.SeparateClassRequest scr =
new org.owasp.benchmark.helpers.SeparateClassRequest(request);
String param = scr.getTheValue("Benchmark00899");

String bar;
String guess = "ABC";
char switchTarget = guess.charAt(1); // condition 'B', which is safe

// Simple case statement that assigns param to bar on conditions 'A', 'C', or 'D'
switch (switchTarget) {
case 'A':
bar = param;
break;
case 'B':
bar = "bob";
break;
case 'C':
case 'D':
bar = param;
break;
default:
bar = "bob's your uncle";
break;
}

double value = new java.util.Random().nextDouble();
String rememberMeKey = Double.toString(value).substring(2); // Trim off the 0. at the front.

String user = "Donna";
String fullClassName = this.getClass().getName();
String testCaseNumber =
fullClassName.substring(fullClassName.lastIndexOf('.') + 1 + "Benchmark".length());
user += testCaseNumber;

String cookieName = "rememberMe" + testCaseNumber;

boolean foundUser = false;
javax.servlet.http.Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (int i = 0; !foundUser && i < cookies.length; i++) {
javax.servlet.http.Cookie cookie = cookies[i];
if (cookieName.equals(cookie.getName())) {
if (cookie.getValue().equals(request.getSession().getAttribute(cookieName))) {
foundUser = true;
}
}
}
}

if (foundUser) {
response.getWriter().println("Welcome back: " + user + "<br/>");
} else {
javax.servlet.http.Cookie rememberMe =
new javax.servlet.http.Cookie(cookieName, rememberMeKey);

Check failure

Code scanning / CodeQL

Insecure randomness High test

Potential Insecure randomness due to a
Insecure randomness source.
.

Copilot Autofix

AI about 20 hours ago

In general, the fix is to replace uses of java.util.Random for generating security-sensitive values with java.security.SecureRandom, which is designed to be cryptographically strong and resistant to prediction. Any token or cookie that enables access or session continuation must be generated using a CSPRNG.

For this specific file, we should:

  • Replace new java.util.Random().nextDouble() with a SecureRandom-based token.
  • Keep functionality similar (a random-looking string) while changing only the randomness source.
  • Because we shouldn’t alter behavior more than necessary, we can keep using a double-derived string if we wish, but it’s cleaner to generate a random byte array and encode it as hex or base64. However, the current code expects a string of digits; to minimize functional change we can still derive from nextDouble() but produced by SecureRandom. The simplest minimal change is: create a SecureRandom instance, call nextDouble(), and use it as before.

Concretely:

  • Add import java.security.SecureRandom; near the other imports in Benchmark00899.java.
  • Change line 68 from double value = new java.util.Random().nextDouble(); to use SecureRandom, e.g.:
    • java.security.SecureRandom secureRandom = new java.security.SecureRandom();
    • double value = secureRandom.nextDouble();
      This keeps all subsequent uses (Double.toString(value)...) unchanged, while ensuring the randomness source is cryptographically secure.

Suggested changeset 1
src/main/java/org/owasp/benchmark/testcode/Benchmark00899.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/main/java/org/owasp/benchmark/testcode/Benchmark00899.java b/src/main/java/org/owasp/benchmark/testcode/Benchmark00899.java
--- a/src/main/java/org/owasp/benchmark/testcode/Benchmark00899.java
+++ b/src/main/java/org/owasp/benchmark/testcode/Benchmark00899.java
@@ -18,6 +18,7 @@
 package org.owasp.benchmark.testcode;
 
 import java.io.IOException;
+import java.security.SecureRandom;
 import javax.servlet.ServletException;
 import javax.servlet.annotation.WebServlet;
 import javax.servlet.http.HttpServlet;
@@ -65,7 +66,8 @@
                 break;
         }
 
-        double value = new java.util.Random().nextDouble();
+        SecureRandom secureRandom = new SecureRandom();
+        double value = secureRandom.nextDouble();
         String rememberMeKey = Double.toString(value).substring(2); // Trim off the 0. at the front.
 
         String user = "Donna";
EOF
@@ -18,6 +18,7 @@
package org.owasp.benchmark.testcode;

import java.io.IOException;
import java.security.SecureRandom;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
@@ -65,7 +66,8 @@
break;
}

double value = new java.util.Random().nextDouble();
SecureRandom secureRandom = new SecureRandom();
double value = secureRandom.nextDouble();
String rememberMeKey = Double.toString(value).substring(2); // Trim off the 0. at the front.

String user = "Donna";
Copilot is powered by AI and may make mistakes. Always verify output.
rememberMe.setSecure(true);
rememberMe.setHttpOnly(true);
rememberMe.setDomain(new java.net.URL(request.getRequestURL().toString()).getHost());
rememberMe.setPath(request.getRequestURI()); // i.e., set path to JUST this servlet
// e.g., /benchmark/sql-01/Benchmark01001
request.getSession().setAttribute(cookieName, rememberMeKey);
response.addCookie(rememberMe);
response.getWriter()
.println(
user
+ " has been remembered with cookie: "
+ rememberMe.getName()
+ " whose value is: "
+ rememberMe.getValue()
+ "<br/>");
}

response.getWriter().println("Randomness java.util.Random.nextDouble() executed");
}
}