Merge remote-tracking branch 'upstream/main' into UseOfLessTrustedSource

This commit is contained in:
haby0
2021-04-19 20:05:49 +08:00
378 changed files with 10416 additions and 3945 deletions

View File

@@ -0,0 +1 @@
| pom.xml:29:9:32:22 | dependency | Insecure configuration of Spring Boot Actuator exposes sensitive endpoints. |

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-016/InsecureSpringActuatorConfig.ql

View File

@@ -0,0 +1,13 @@
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class SensitiveInfo {
@RequestMapping
public void handleLogin(@RequestParam String username, @RequestParam String password) throws Exception {
if (!username.equals("") && password.equals("")) {
//Blank processing
}
}
}

View File

@@ -0,0 +1,14 @@
#management.endpoints.web.base-path=/admin
# vulnerable configuration (spring boot 1.0 - 1.4): exposes actuators by default
# vulnerable configuration (spring boot 1.5+): requires value false to expose sensitive actuators
management.security.enabled=false
# vulnerable configuration (spring boot 2+): exposes health and info only by default, here overridden to expose everything
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=beans
management.endpoint.shutdown.enabled=true
management.endpoint.health.show-details=when_authorized

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>spring-boot-actuator-app</groupId>
<artifactId>spring-boot-actuator-app</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.8.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,46 @@
edges
| JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) : InputStream | JakartaExpressionInjection.java:25:31:25:40 | expression : String |
| JakartaExpressionInjection.java:25:31:25:40 | expression : String | JakartaExpressionInjection.java:32:24:32:33 | expression : String |
| JakartaExpressionInjection.java:25:31:25:40 | expression : String | JakartaExpressionInjection.java:40:24:40:33 | expression : String |
| JakartaExpressionInjection.java:25:31:25:40 | expression : String | JakartaExpressionInjection.java:48:24:48:33 | expression : String |
| JakartaExpressionInjection.java:25:31:25:40 | expression : String | JakartaExpressionInjection.java:59:24:59:33 | expression : String |
| JakartaExpressionInjection.java:25:31:25:40 | expression : String | JakartaExpressionInjection.java:67:24:67:33 | expression : String |
| JakartaExpressionInjection.java:25:31:25:40 | expression : String | JakartaExpressionInjection.java:75:24:75:33 | expression : String |
| JakartaExpressionInjection.java:25:31:25:40 | expression : String | JakartaExpressionInjection.java:85:24:85:33 | expression : String |
| JakartaExpressionInjection.java:25:31:25:40 | expression : String | JakartaExpressionInjection.java:95:24:95:33 | expression : String |
| JakartaExpressionInjection.java:32:24:32:33 | expression : String | JakartaExpressionInjection.java:34:28:34:37 | expression |
| JakartaExpressionInjection.java:40:24:40:33 | expression : String | JakartaExpressionInjection.java:42:32:42:41 | expression |
| JakartaExpressionInjection.java:48:24:48:33 | expression : String | JakartaExpressionInjection.java:53:13:53:28 | lambdaExpression |
| JakartaExpressionInjection.java:59:24:59:33 | expression : String | JakartaExpressionInjection.java:61:32:61:41 | expression |
| JakartaExpressionInjection.java:67:24:67:33 | expression : String | JakartaExpressionInjection.java:69:43:69:52 | expression |
| JakartaExpressionInjection.java:75:24:75:33 | expression : String | JakartaExpressionInjection.java:79:13:79:13 | e |
| JakartaExpressionInjection.java:85:24:85:33 | expression : String | JakartaExpressionInjection.java:89:13:89:13 | e |
| JakartaExpressionInjection.java:95:24:95:33 | expression : String | JakartaExpressionInjection.java:99:13:99:13 | e |
nodes
| JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| JakartaExpressionInjection.java:25:31:25:40 | expression : String | semmle.label | expression : String |
| JakartaExpressionInjection.java:32:24:32:33 | expression : String | semmle.label | expression : String |
| JakartaExpressionInjection.java:34:28:34:37 | expression | semmle.label | expression |
| JakartaExpressionInjection.java:40:24:40:33 | expression : String | semmle.label | expression : String |
| JakartaExpressionInjection.java:42:32:42:41 | expression | semmle.label | expression |
| JakartaExpressionInjection.java:48:24:48:33 | expression : String | semmle.label | expression : String |
| JakartaExpressionInjection.java:53:13:53:28 | lambdaExpression | semmle.label | lambdaExpression |
| JakartaExpressionInjection.java:59:24:59:33 | expression : String | semmle.label | expression : String |
| JakartaExpressionInjection.java:61:32:61:41 | expression | semmle.label | expression |
| JakartaExpressionInjection.java:67:24:67:33 | expression : String | semmle.label | expression : String |
| JakartaExpressionInjection.java:69:43:69:52 | expression | semmle.label | expression |
| JakartaExpressionInjection.java:75:24:75:33 | expression : String | semmle.label | expression : String |
| JakartaExpressionInjection.java:79:13:79:13 | e | semmle.label | e |
| JakartaExpressionInjection.java:85:24:85:33 | expression : String | semmle.label | expression : String |
| JakartaExpressionInjection.java:89:13:89:13 | e | semmle.label | e |
| JakartaExpressionInjection.java:95:24:95:33 | expression : String | semmle.label | expression : String |
| JakartaExpressionInjection.java:99:13:99:13 | e | semmle.label | e |
#select
| JakartaExpressionInjection.java:34:28:34:37 | expression | JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) : InputStream | JakartaExpressionInjection.java:34:28:34:37 | expression | Jakarta Expression Language injection from $@. | JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) | this user input |
| JakartaExpressionInjection.java:42:32:42:41 | expression | JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) : InputStream | JakartaExpressionInjection.java:42:32:42:41 | expression | Jakarta Expression Language injection from $@. | JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) | this user input |
| JakartaExpressionInjection.java:53:13:53:28 | lambdaExpression | JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) : InputStream | JakartaExpressionInjection.java:53:13:53:28 | lambdaExpression | Jakarta Expression Language injection from $@. | JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) | this user input |
| JakartaExpressionInjection.java:61:32:61:41 | expression | JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) : InputStream | JakartaExpressionInjection.java:61:32:61:41 | expression | Jakarta Expression Language injection from $@. | JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) | this user input |
| JakartaExpressionInjection.java:69:43:69:52 | expression | JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) : InputStream | JakartaExpressionInjection.java:69:43:69:52 | expression | Jakarta Expression Language injection from $@. | JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) | this user input |
| JakartaExpressionInjection.java:79:13:79:13 | e | JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) : InputStream | JakartaExpressionInjection.java:79:13:79:13 | e | Jakarta Expression Language injection from $@. | JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) | this user input |
| JakartaExpressionInjection.java:89:13:89:13 | e | JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) : InputStream | JakartaExpressionInjection.java:89:13:89:13 | e | Jakarta Expression Language injection from $@. | JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) | this user input |
| JakartaExpressionInjection.java:99:13:99:13 | e | JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) : InputStream | JakartaExpressionInjection.java:99:13:99:13 | e | Jakarta Expression Language injection from $@. | JakartaExpressionInjection.java:23:25:23:47 | getInputStream(...) | this user input |

View File

@@ -0,0 +1,103 @@
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.function.Consumer;
import javax.el.ELContext;
import javax.el.ELManager;
import javax.el.ELProcessor;
import javax.el.ExpressionFactory;
import javax.el.LambdaExpression;
import javax.el.MethodExpression;
import javax.el.StandardELContext;
import javax.el.ValueExpression;
public class JakartaExpressionInjection {
// calls a consumer with a string received from a socket
private static void testWithSocket(Consumer<String> action) throws IOException {
try (ServerSocket serverSocket = new ServerSocket(0)) {
try (Socket socket = serverSocket.accept()) {
byte[] bytes = new byte[1024];
int n = socket.getInputStream().read(bytes);
String expression = new String(bytes, 0, n);
action.accept(expression);
}
}
}
// BAD (untrusted input to ELProcessor.eval)
private static void testWithELProcessorEval() throws IOException {
testWithSocket(expression -> {
ELProcessor processor = new ELProcessor();
processor.eval(expression);
});
}
// BAD (untrusted input to ELProcessor.getValue)
private static void testWithELProcessorGetValue() throws IOException {
testWithSocket(expression -> {
ELProcessor processor = new ELProcessor();
processor.getValue(expression, Object.class);
});
}
// BAD (untrusted input to LambdaExpression.invoke)
private static void testWithLambdaExpressionInvoke() throws IOException {
testWithSocket(expression -> {
ExpressionFactory factory = ELManager.getExpressionFactory();
StandardELContext context = new StandardELContext(factory);
ValueExpression valueExpression = factory.createValueExpression(context, expression, Object.class);
LambdaExpression lambdaExpression = new LambdaExpression(new ArrayList<>(), valueExpression);
lambdaExpression.invoke(context, new Object[0]);
});
}
// BAD (untrusted input to ELProcessor.setValue)
private static void testWithELProcessorSetValue() throws IOException {
testWithSocket(expression -> {
ELProcessor processor = new ELProcessor();
processor.setValue(expression, new Object());
});
}
// BAD (untrusted input to ELProcessor.setVariable)
private static void testWithELProcessorSetVariable() throws IOException {
testWithSocket(expression -> {
ELProcessor processor = new ELProcessor();
processor.setVariable("test", expression);
});
}
// BAD (untrusted input to ValueExpression.getValue when it was created by JUEL)
private static void testWithJuelValueExpressionGetValue() throws IOException {
testWithSocket(expression -> {
ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl();
ELContext context = new de.odysseus.el.util.SimpleContext();
ValueExpression e = factory.createValueExpression(context, expression, Object.class);
e.getValue(context);
});
}
// BAD (untrusted input to ValueExpression.setValue when it was created by JUEL)
private static void testWithJuelValueExpressionSetValue() throws IOException {
testWithSocket(expression -> {
ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl();
ELContext context = new de.odysseus.el.util.SimpleContext();
ValueExpression e = factory.createValueExpression(context, expression, Object.class);
e.setValue(context, new Object());
});
}
// BAD (untrusted input to MethodExpression.invoke when it was created by JUEL)
private static void testWithJuelMethodExpressionInvoke() throws IOException {
testWithSocket(expression -> {
ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl();
ELContext context = new de.odysseus.el.util.SimpleContext();
MethodExpression e = factory.createMethodExpression(context, expression, Object.class, new Class[0]);
e.invoke(context, new Object[0]);
});
}
}

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-094/JakartaExpressionInjection.ql

View File

@@ -1,2 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.2.3:${testdir}/../../../../stubs/mvel2-2.4.7:${testdir}/../../../../stubs/jsr223-api:${testdir}/../../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../../stubs/scriptengine
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.2.3:${testdir}/../../../../stubs/mvel2-2.4.7:${testdir}/../../../../stubs/jsr223-api:${testdir}/../../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../../stubs/scriptengine:${testdir}/../../../../stubs/java-ee-el:${testdir}/../../../../stubs/juel-2.2

View File

@@ -0,0 +1,41 @@
edges
| SensitiveCookieNotHttpOnly.java:24:33:24:43 | "jwt_token" : String | SensitiveCookieNotHttpOnly.java:31:28:31:36 | jwtCookie |
| SensitiveCookieNotHttpOnly.java:42:42:42:49 | "token=" : String | SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... |
| SensitiveCookieNotHttpOnly.java:42:42:42:57 | ... + ... : String | SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... |
| SensitiveCookieNotHttpOnly.java:52:56:52:75 | "session-access-key" : String | SensitiveCookieNotHttpOnly.java:52:42:52:124 | toString(...) |
| SensitiveCookieNotHttpOnly.java:63:51:63:70 | "session-access-key" : String | SensitiveCookieNotHttpOnly.java:65:42:65:47 | keyStr |
| SensitiveCookieNotHttpOnly.java:70:28:70:35 | "token=" : String | SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString |
| SensitiveCookieNotHttpOnly.java:70:28:70:43 | ... + ... : String | SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString |
| SensitiveCookieNotHttpOnly.java:70:28:70:55 | ... + ... : String | SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString |
| SensitiveCookieNotHttpOnly.java:88:35:88:51 | "Presto-UI-Token" : String | SensitiveCookieNotHttpOnly.java:91:16:91:21 | cookie : Cookie |
| SensitiveCookieNotHttpOnly.java:91:16:91:21 | cookie : Cookie | SensitiveCookieNotHttpOnly.java:110:25:110:64 | createAuthenticationCookie(...) : Cookie |
| SensitiveCookieNotHttpOnly.java:110:25:110:64 | createAuthenticationCookie(...) : Cookie | SensitiveCookieNotHttpOnly.java:111:28:111:33 | cookie |
nodes
| SensitiveCookieNotHttpOnly.java:24:33:24:43 | "jwt_token" : String | semmle.label | "jwt_token" : String |
| SensitiveCookieNotHttpOnly.java:31:28:31:36 | jwtCookie | semmle.label | jwtCookie |
| SensitiveCookieNotHttpOnly.java:42:42:42:49 | "token=" : String | semmle.label | "token=" : String |
| SensitiveCookieNotHttpOnly.java:42:42:42:57 | ... + ... : String | semmle.label | ... + ... : String |
| SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | semmle.label | ... + ... |
| SensitiveCookieNotHttpOnly.java:52:42:52:124 | toString(...) | semmle.label | toString(...) |
| SensitiveCookieNotHttpOnly.java:52:56:52:75 | "session-access-key" : String | semmle.label | "session-access-key" : String |
| SensitiveCookieNotHttpOnly.java:63:51:63:70 | "session-access-key" : String | semmle.label | "session-access-key" : String |
| SensitiveCookieNotHttpOnly.java:65:42:65:47 | keyStr | semmle.label | keyStr |
| SensitiveCookieNotHttpOnly.java:70:28:70:35 | "token=" : String | semmle.label | "token=" : String |
| SensitiveCookieNotHttpOnly.java:70:28:70:43 | ... + ... : String | semmle.label | ... + ... : String |
| SensitiveCookieNotHttpOnly.java:70:28:70:55 | ... + ... : String | semmle.label | ... + ... : String |
| SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | semmle.label | secString |
| SensitiveCookieNotHttpOnly.java:88:35:88:51 | "Presto-UI-Token" : String | semmle.label | "Presto-UI-Token" : String |
| SensitiveCookieNotHttpOnly.java:91:16:91:21 | cookie : Cookie | semmle.label | cookie : Cookie |
| SensitiveCookieNotHttpOnly.java:110:25:110:64 | createAuthenticationCookie(...) : Cookie | semmle.label | createAuthenticationCookie(...) : Cookie |
| SensitiveCookieNotHttpOnly.java:111:28:111:33 | cookie | semmle.label | cookie |
#select
| SensitiveCookieNotHttpOnly.java:31:28:31:36 | jwtCookie | SensitiveCookieNotHttpOnly.java:24:33:24:43 | "jwt_token" : String | SensitiveCookieNotHttpOnly.java:31:28:31:36 | jwtCookie | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:24:33:24:43 | "jwt_token" | This sensitive cookie |
| SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | SensitiveCookieNotHttpOnly.java:42:42:42:49 | "token=" : String | SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:42:42:42:49 | "token=" | This sensitive cookie |
| SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | SensitiveCookieNotHttpOnly.java:42:42:42:57 | ... + ... : String | SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:42:42:42:57 | ... + ... | This sensitive cookie |
| SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | This sensitive cookie |
| SensitiveCookieNotHttpOnly.java:52:42:52:124 | toString(...) | SensitiveCookieNotHttpOnly.java:52:56:52:75 | "session-access-key" : String | SensitiveCookieNotHttpOnly.java:52:42:52:124 | toString(...) | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:52:56:52:75 | "session-access-key" | This sensitive cookie |
| SensitiveCookieNotHttpOnly.java:65:42:65:47 | keyStr | SensitiveCookieNotHttpOnly.java:63:51:63:70 | "session-access-key" : String | SensitiveCookieNotHttpOnly.java:65:42:65:47 | keyStr | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:63:51:63:70 | "session-access-key" | This sensitive cookie |
| SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | SensitiveCookieNotHttpOnly.java:70:28:70:35 | "token=" : String | SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:70:28:70:35 | "token=" | This sensitive cookie |
| SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | SensitiveCookieNotHttpOnly.java:70:28:70:43 | ... + ... : String | SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:70:28:70:43 | ... + ... | This sensitive cookie |
| SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | SensitiveCookieNotHttpOnly.java:70:28:70:55 | ... + ... : String | SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:70:28:70:55 | ... + ... | This sensitive cookie |
| SensitiveCookieNotHttpOnly.java:111:28:111:33 | cookie | SensitiveCookieNotHttpOnly.java:88:35:88:51 | "Presto-UI-Token" : String | SensitiveCookieNotHttpOnly.java:111:28:111:33 | cookie | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:88:35:88:51 | "Presto-UI-Token" | This sensitive cookie |

View File

@@ -0,0 +1,164 @@
import java.io.IOException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import javax.ws.rs.core.NewCookie;
import org.springframework.security.web.csrf.CsrfToken;
class SensitiveCookieNotHttpOnly {
// GOOD - Tests adding a sensitive cookie with the `HttpOnly` flag set.
public void addCookie(String jwt_token, HttpServletRequest request, HttpServletResponse response) {
Cookie jwtCookie = new Cookie("jwt_token", jwt_token);
jwtCookie.setPath("/");
jwtCookie.setMaxAge(3600*24*7);
jwtCookie.setHttpOnly(true);
response.addCookie(jwtCookie);
}
// BAD - Tests adding a sensitive cookie without the `HttpOnly` flag set.
public void addCookie2(String jwt_token, String userId, HttpServletRequest request, HttpServletResponse response) {
String tokenCookieStr = "jwt_token";
Cookie jwtCookie = new Cookie(tokenCookieStr, jwt_token);
Cookie userIdCookie = new Cookie("user_id", userId);
jwtCookie.setPath("/");
userIdCookie.setPath("/");
jwtCookie.setMaxAge(3600*24*7);
userIdCookie.setMaxAge(3600*24*7);
response.addCookie(jwtCookie);
response.addCookie(userIdCookie);
}
// GOOD - Tests set a sensitive cookie header with the `HttpOnly` flag set.
public void addCookie3(String authId, HttpServletRequest request, HttpServletResponse response) {
response.addHeader("Set-Cookie", "token=" +authId + ";HttpOnly;Secure");
}
// BAD - Tests set a sensitive cookie header without the `HttpOnly` flag set.
public void addCookie4(String authId, HttpServletRequest request, HttpServletResponse response) {
response.addHeader("Set-Cookie", "token=" +authId + ";Secure");
}
// GOOD - Tests set a sensitive cookie header using the class `javax.ws.rs.core.Cookie` with the `HttpOnly` flag set through string concatenation.
public void addCookie5(String accessKey, HttpServletRequest request, HttpServletResponse response) {
response.setHeader("Set-Cookie", new NewCookie("session-access-key", accessKey, "/", null, null, 0, true) + ";HttpOnly");
}
// BAD - Tests set a sensitive cookie header using the class `javax.ws.rs.core.Cookie` without the `HttpOnly` flag set.
public void addCookie6(String accessKey, HttpServletRequest request, HttpServletResponse response) {
response.setHeader("Set-Cookie", new NewCookie("session-access-key", accessKey, "/", null, null, 0, true).toString());
}
// GOOD - Tests set a sensitive cookie header using the class `javax.ws.rs.core.Cookie` with the `HttpOnly` flag set through the constructor.
public void addCookie7(String accessKey, HttpServletRequest request, HttpServletResponse response) {
NewCookie accessKeyCookie = new NewCookie("session-access-key", accessKey, "/", null, null, 0, true, true);
response.setHeader("Set-Cookie", accessKeyCookie.toString());
}
// BAD - Tests set a sensitive cookie header using the class `javax.ws.rs.core.Cookie` without the `HttpOnly` flag set.
public void addCookie8(String accessKey, HttpServletRequest request, HttpServletResponse response) {
NewCookie accessKeyCookie = new NewCookie("session-access-key", accessKey, "/", null, 0, null, 86400, true);
String keyStr = accessKeyCookie.toString();
response.setHeader("Set-Cookie", keyStr);
}
// BAD - Tests set a sensitive cookie header using a variable without the `HttpOnly` flag set.
public void addCookie9(String authId, HttpServletRequest request, HttpServletResponse response) {
String secString = "token=" +authId + ";Secure";
response.addHeader("Set-Cookie", secString);
}
// GOOD - Tests set a sensitive cookie header with the `HttpOnly` flag set using `String.format(...)`.
public void addCookie10(HttpServletRequest request, HttpServletResponse response) {
response.addHeader("SET-COOKIE", String.format("%s=%s;HttpOnly", "sessionkey", request.getSession().getAttribute("sessionkey")));
}
public Cookie createHttpOnlyAuthenticationCookie(HttpServletRequest request, String jwt) {
String PRESTO_UI_COOKIE = "Presto-UI-Token";
Cookie cookie = new Cookie(PRESTO_UI_COOKIE, jwt);
cookie.setHttpOnly(true);
cookie.setPath("/ui");
return cookie;
}
public Cookie createAuthenticationCookie(HttpServletRequest request, String jwt) {
String PRESTO_UI_COOKIE = "Presto-UI-Token";
Cookie cookie = new Cookie(PRESTO_UI_COOKIE, jwt);
cookie.setPath("/ui");
return cookie;
}
public Cookie removeAuthenticationCookie(HttpServletRequest request, String jwt) {
String PRESTO_UI_COOKIE = "Presto-UI-Token";
Cookie cookie = new Cookie(PRESTO_UI_COOKIE, jwt);
cookie.setPath("/ui");
cookie.setMaxAge(0);
return cookie;
}
// GOOD - Tests set a sensitive cookie header with the `HttpOnly` flag set using a wrapper method.
public void addCookie11(HttpServletRequest request, HttpServletResponse response, String jwt) {
Cookie cookie = createHttpOnlyAuthenticationCookie(request, jwt);
response.addCookie(cookie);
}
// BAD - Tests set a sensitive cookie header without the `HttpOnly` flag set using a wrapper method.
public void addCookie12(HttpServletRequest request, HttpServletResponse response, String jwt) {
Cookie cookie = createAuthenticationCookie(request, jwt);
response.addCookie(cookie);
}
// GOOD - Tests remove a sensitive cookie header without the `HttpOnly` flag set using a wrapper method.
public void addCookie13(HttpServletRequest request, HttpServletResponse response, String jwt) {
Cookie cookie = removeAuthenticationCookie(request, jwt);
response.addCookie(cookie);
}
private Cookie createCookie(String name, String value, Boolean httpOnly){
Cookie cookie = null;
cookie = new Cookie(name, value);
cookie.setDomain("/");
cookie.setHttpOnly(httpOnly);
//for production https
cookie.setSecure(true);
cookie.setMaxAge(60*60*24*30);
cookie.setPath("/");
return cookie;
}
// GOOD - Tests set a sensitive cookie header with the `HttpOnly` flag set through a boolean variable using a wrapper method.
public void addCookie14(HttpServletRequest request, HttpServletResponse response, String refreshToken) {
response.addCookie(createCookie("refresh_token", refreshToken, true));
}
// BAD (but not detected) - Tests set a sensitive cookie header with the `HttpOnly` flag not set through a boolean variable using a wrapper method.
// This example is missed because the `cookie.setHttpOnly` call in `createCookie` is thought to maybe set the HTTP-only flag, and the `cookie`
// object flows to this `addCookie` call.
public void addCookie15(HttpServletRequest request, HttpServletResponse response, String refreshToken) {
response.addCookie(createCookie("refresh_token", refreshToken, false));
}
// GOOD - CSRF token doesn't need to have the `HttpOnly` flag set.
public void addCsrfCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Spring put the CSRF token in session attribute "_csrf"
CsrfToken csrfToken = (CsrfToken) request.getAttribute("_csrf");
// Send the cookie only if the token has changed
String actualToken = request.getHeader("X-CSRF-TOKEN");
if (actualToken == null || !actualToken.equals(csrfToken.getToken())) {
// Session cookie that can be used by AngularJS
String pCookieName = "CSRF-TOKEN";
Cookie cookie = new Cookie(pCookieName, csrfToken.getToken());
cookie.setMaxAge(-1);
cookie.setHttpOnly(false);
cookie.setPath("/");
response.addCookie(cookie);
}
}
}

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.ql

View File

@@ -0,0 +1 @@
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/jsr311-api-1.1.1:${testdir}/../../../../stubs/springframework-5.2.3

View File

@@ -0,0 +1,161 @@
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
@Controller
public class JsonpController {
private static HashMap hashMap = new HashMap();
static {
hashMap.put("username","admin");
hashMap.put("password","123456");
}
@GetMapping(value = "jsonp1")
@ResponseBody
public String bad1(HttpServletRequest request) {
String resultStr = null;
String jsonpCallback = request.getParameter("jsonpCallback");
Gson gson = new Gson();
String result = gson.toJson(hashMap);
resultStr = jsonpCallback + "(" + result + ")";
return resultStr;
}
@GetMapping(value = "jsonp2")
@ResponseBody
public String bad2(HttpServletRequest request) {
String resultStr = null;
String jsonpCallback = request.getParameter("jsonpCallback");
resultStr = jsonpCallback + "(" + JSONObject.toJSONString(hashMap) + ")";
return resultStr;
}
@GetMapping(value = "jsonp3")
@ResponseBody
public String bad3(HttpServletRequest request) {
String resultStr = null;
String jsonpCallback = request.getParameter("jsonpCallback");
String jsonStr = getJsonStr(hashMap);
resultStr = jsonpCallback + "(" + jsonStr + ")";
return resultStr;
}
@GetMapping(value = "jsonp4")
@ResponseBody
public String bad4(HttpServletRequest request) {
String resultStr = null;
String jsonpCallback = request.getParameter("jsonpCallback");
String restr = JSONObject.toJSONString(hashMap);
resultStr = jsonpCallback + "(" + restr + ");";
return resultStr;
}
@GetMapping(value = "jsonp5")
@ResponseBody
public void bad5(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String jsonpCallback = request.getParameter("jsonpCallback");
PrintWriter pw = null;
Gson gson = new Gson();
String result = gson.toJson(hashMap);
String resultStr = null;
pw = response.getWriter();
resultStr = jsonpCallback + "(" + result + ")";
pw.println(resultStr);
}
@GetMapping(value = "jsonp6")
@ResponseBody
public void bad6(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String jsonpCallback = request.getParameter("jsonpCallback");
PrintWriter pw = null;
ObjectMapper mapper = new ObjectMapper();
String result = mapper.writeValueAsString(hashMap);
String resultStr = null;
pw = response.getWriter();
resultStr = jsonpCallback + "(" + result + ")";
pw.println(resultStr);
}
@RequestMapping(value = "jsonp7", method = RequestMethod.GET)
@ResponseBody
public String bad7(HttpServletRequest request) {
String resultStr = null;
String jsonpCallback = request.getParameter("jsonpCallback");
Gson gson = new Gson();
String result = gson.toJson(hashMap);
resultStr = jsonpCallback + "(" + result + ")";
return resultStr;
}
@RequestMapping(value = "jsonp11")
@ResponseBody
public String good1(HttpServletRequest request) {
JSONObject parameterObj = readToJSONObect(request);
String resultStr = null;
String jsonpCallback = request.getParameter("jsonpCallback");
String restr = JSONObject.toJSONString(hashMap);
resultStr = jsonpCallback + "(" + restr + ");";
return resultStr;
}
@RequestMapping(value = "jsonp12")
@ResponseBody
public String good2(@RequestParam("file") MultipartFile file,HttpServletRequest request) {
if(null == file){
return "upload file error";
}
String fileName = file.getOriginalFilename();
System.out.println("file operations");
String resultStr = null;
String jsonpCallback = request.getParameter("jsonpCallback");
String restr = JSONObject.toJSONString(hashMap);
resultStr = jsonpCallback + "(" + restr + ");";
return resultStr;
}
public static JSONObject readToJSONObect(HttpServletRequest request){
String jsonText = readPostContent(request);
JSONObject jsonObj = JSONObject.parseObject(jsonText, JSONObject.class);
return jsonObj;
}
public static String readPostContent(HttpServletRequest request){
BufferedReader in= null;
String content = null;
String line = null;
try {
in = new BufferedReader(new InputStreamReader(request.getInputStream(),"UTF-8"));
StringBuilder buf = new StringBuilder();
while ((line = in.readLine()) != null) {
buf.append(line);
}
content = buf.toString();
} catch (IOException e) {
e.printStackTrace();
}
String uri = request.getRequestURI();
return content;
}
public static String getJsonStr(Object result) {
return JSONObject.toJSONString(result);
}
}

View File

@@ -0,0 +1,58 @@
edges
| JsonpController.java:33:32:33:68 | getParameter(...) : String | JsonpController.java:37:16:37:24 | resultStr |
| JsonpController.java:36:21:36:54 | ... + ... : String | JsonpController.java:37:16:37:24 | resultStr |
| JsonpController.java:44:32:44:68 | getParameter(...) : String | JsonpController.java:46:16:46:24 | resultStr |
| JsonpController.java:45:21:45:80 | ... + ... : String | JsonpController.java:46:16:46:24 | resultStr |
| JsonpController.java:53:32:53:68 | getParameter(...) : String | JsonpController.java:56:16:56:24 | resultStr |
| JsonpController.java:55:21:55:55 | ... + ... : String | JsonpController.java:56:16:56:24 | resultStr |
| JsonpController.java:63:32:63:68 | getParameter(...) : String | JsonpController.java:66:16:66:24 | resultStr |
| JsonpController.java:65:21:65:54 | ... + ... : String | JsonpController.java:66:16:66:24 | resultStr |
| JsonpController.java:73:32:73:68 | getParameter(...) : String | JsonpController.java:80:20:80:28 | resultStr |
| JsonpController.java:79:21:79:54 | ... + ... : String | JsonpController.java:80:20:80:28 | resultStr |
| JsonpController.java:87:32:87:68 | getParameter(...) : String | JsonpController.java:94:20:94:28 | resultStr |
| JsonpController.java:93:21:93:54 | ... + ... : String | JsonpController.java:94:20:94:28 | resultStr |
| JsonpController.java:101:32:101:68 | getParameter(...) : String | JsonpController.java:105:16:105:24 | resultStr |
| JsonpController.java:104:21:104:54 | ... + ... : String | JsonpController.java:105:16:105:24 | resultStr |
| JsonpController.java:115:21:115:54 | ... + ... : String | JsonpController.java:116:16:116:24 | resultStr |
| JsonpController.java:130:21:130:54 | ... + ... : String | JsonpController.java:131:16:131:24 | resultStr |
nodes
| JsonpController.java:33:32:33:68 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| JsonpController.java:36:21:36:54 | ... + ... : String | semmle.label | ... + ... : String |
| JsonpController.java:37:16:37:24 | resultStr | semmle.label | resultStr |
| JsonpController.java:37:16:37:24 | resultStr | semmle.label | resultStr |
| JsonpController.java:44:32:44:68 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| JsonpController.java:45:21:45:80 | ... + ... : String | semmle.label | ... + ... : String |
| JsonpController.java:46:16:46:24 | resultStr | semmle.label | resultStr |
| JsonpController.java:46:16:46:24 | resultStr | semmle.label | resultStr |
| JsonpController.java:53:32:53:68 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| JsonpController.java:55:21:55:55 | ... + ... : String | semmle.label | ... + ... : String |
| JsonpController.java:56:16:56:24 | resultStr | semmle.label | resultStr |
| JsonpController.java:56:16:56:24 | resultStr | semmle.label | resultStr |
| JsonpController.java:63:32:63:68 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| JsonpController.java:65:21:65:54 | ... + ... : String | semmle.label | ... + ... : String |
| JsonpController.java:66:16:66:24 | resultStr | semmle.label | resultStr |
| JsonpController.java:66:16:66:24 | resultStr | semmle.label | resultStr |
| JsonpController.java:73:32:73:68 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| JsonpController.java:79:21:79:54 | ... + ... : String | semmle.label | ... + ... : String |
| JsonpController.java:80:20:80:28 | resultStr | semmle.label | resultStr |
| JsonpController.java:80:20:80:28 | resultStr | semmle.label | resultStr |
| JsonpController.java:87:32:87:68 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| JsonpController.java:93:21:93:54 | ... + ... : String | semmle.label | ... + ... : String |
| JsonpController.java:94:20:94:28 | resultStr | semmle.label | resultStr |
| JsonpController.java:94:20:94:28 | resultStr | semmle.label | resultStr |
| JsonpController.java:101:32:101:68 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| JsonpController.java:104:21:104:54 | ... + ... : String | semmle.label | ... + ... : String |
| JsonpController.java:105:16:105:24 | resultStr | semmle.label | resultStr |
| JsonpController.java:105:16:105:24 | resultStr | semmle.label | resultStr |
| JsonpController.java:115:21:115:54 | ... + ... : String | semmle.label | ... + ... : String |
| JsonpController.java:116:16:116:24 | resultStr | semmle.label | resultStr |
| JsonpController.java:130:21:130:54 | ... + ... : String | semmle.label | ... + ... : String |
| JsonpController.java:131:16:131:24 | resultStr | semmle.label | resultStr |
#select
| JsonpController.java:37:16:37:24 | resultStr | JsonpController.java:33:32:33:68 | getParameter(...) : String | JsonpController.java:37:16:37:24 | resultStr | Jsonp response might include code from $@. | JsonpController.java:33:32:33:68 | getParameter(...) | this user input |
| JsonpController.java:46:16:46:24 | resultStr | JsonpController.java:44:32:44:68 | getParameter(...) : String | JsonpController.java:46:16:46:24 | resultStr | Jsonp response might include code from $@. | JsonpController.java:44:32:44:68 | getParameter(...) | this user input |
| JsonpController.java:56:16:56:24 | resultStr | JsonpController.java:53:32:53:68 | getParameter(...) : String | JsonpController.java:56:16:56:24 | resultStr | Jsonp response might include code from $@. | JsonpController.java:53:32:53:68 | getParameter(...) | this user input |
| JsonpController.java:66:16:66:24 | resultStr | JsonpController.java:63:32:63:68 | getParameter(...) : String | JsonpController.java:66:16:66:24 | resultStr | Jsonp response might include code from $@. | JsonpController.java:63:32:63:68 | getParameter(...) | this user input |
| JsonpController.java:80:20:80:28 | resultStr | JsonpController.java:73:32:73:68 | getParameter(...) : String | JsonpController.java:80:20:80:28 | resultStr | Jsonp response might include code from $@. | JsonpController.java:73:32:73:68 | getParameter(...) | this user input |
| JsonpController.java:94:20:94:28 | resultStr | JsonpController.java:87:32:87:68 | getParameter(...) : String | JsonpController.java:94:20:94:28 | resultStr | Jsonp response might include code from $@. | JsonpController.java:87:32:87:68 | getParameter(...) | this user input |
| JsonpController.java:105:16:105:24 | resultStr | JsonpController.java:101:32:101:68 | getParameter(...) : String | JsonpController.java:105:16:105:24 | resultStr | Jsonp response might include code from $@. | JsonpController.java:101:32:101:68 | getParameter(...) | this user input |

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-352/JsonpInjection.ql

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/apache-http-4.4.13/:${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/fastjson-1.2.74/:${testdir}/../../../../stubs/gson-2.8.6/:${testdir}/../../../../stubs/jackson-databind-2.10/:${testdir}/../../../../stubs/springframework-5.2.3/

View File

@@ -0,0 +1,5 @@
| configuration.properties:6:1:6:25 | ldap.password=mysecpass | Plaintext credentials ldap.password have cleartext value mysecpass in properties file |
| configuration.properties:18:1:18:35 | datasource1.password=Passw0rd@123 | Plaintext credentials datasource1.password have cleartext value Passw0rd@123 in properties file |
| configuration.properties:25:1:25:31 | mail.password=MysecPWxWa@1993 | Plaintext credentials mail.password have cleartext value MysecPWxWa@1993 in properties file |
| configuration.properties:33:1:33:50 | com.example.aws.s3.access_key=AKMAMQPBYMCD6YSAYCBA | Plaintext credentials com.example.aws.s3.access_key have cleartext value AKMAMQPBYMCD6YSAYCBA in properties file |
| configuration.properties:34:1:34:70 | com.example.aws.s3.secret_key=8lMPSfWzZq+wcWtck5+QPLOJDZzE783pS09/IO3k | Plaintext credentials com.example.aws.s3.secret_key have cleartext value 8lMPSfWzZq+wcWtck5+QPLOJDZzE783pS09/IO3k in properties file |

View File

@@ -0,0 +1,10 @@
/*
* Note this is similar to src/experimental/Security/CWE/CWE-555/CredentialsInPropertiesFile.ql
* except we do not filter out test files.
*/
import java
import experimental.semmle.code.java.frameworks.CredentialsInPropertiesFile
from CredentialsConfig cc
select cc, cc.getConfigDesc()

View File

@@ -0,0 +1,37 @@
#***************************** LDAP Credentials *****************************************#
ldap.ldapHost = ldap.example.com
ldap.ldapPort = 636
ldap.loginDN = cn=Directory Manager
#### BAD: LDAP credentials are stored in cleartext ####
ldap.password = mysecpass
#### GOOD: LDAP credentials are stored in the encrypted format ####
ldap.password = eFRZ3Cqo5zDJWMYLiaEupw==
ldap.domain1 = example
ldap.domain2 = com
ldap.url= ldaps://ldap.example.com:636/dc=example,dc=com
#*************************** MS SQL Database Connection **********************************#
datasource1.driverClassName = com.microsoft.sqlserver.jdbc.SQLServerDriver
datasource1.url = jdbc:sqlserver://ms.example.com\\exampledb:1433;
datasource1.username = sa
#### BAD: Datasource credentials are stored in cleartext ####
datasource1.password = Passw0rd@123
#### GOOD: Datasource credentials are stored in the encrypted format ####
datasource1.password = VvOgflYS1EUzJdVNDoBcnA==
#*************************** Mail Connection **********************************#
mail.username = test@example.com
#### BAD: Mail credentials are stored in cleartext ####
mail.password = MysecPWxWa@1993
#### GOOD: Mail credentials are stored in the encrypted format ####
mail.password = M*********@1993
#*************************** AWS S3 Connection **********************************#
com.example.aws.s3.bucket_name=com-bucket-1
com.example.aws.s3.directory_name=com-directory-1
#### BAD: Access keys are stored in properties file in cleartext ####
com.example.aws.s3.access_key=AKMAMQPBYMCD6YSAYCBA
com.example.aws.s3.secret_key=8lMPSfWzZq+wcWtck5+QPLOJDZzE783pS09/IO3k
#### GOOD: Access keys are not stored in properties file ####
com.example.aws.s3.access_key=${ENV:AWS_ACCESS_KEY_ID}
com.example.aws.s3.secret_key=${ENV:AWS_SECRET_ACCESS_KEY}

View File

@@ -0,0 +1,9 @@
# GOOD: UI display messages; not credentials
prompt.username=Username
prompt.password=Password
forgot_password.error=Please enter a valid email address.
reset_password.error=Passwords must match and not be empty.
login.password_expired=Your current password has expired. Please reset your password.
login.login_failure=Unable to verify username or password. Please try again.