Skip to content

Commit 4daa950

Browse files
Merge pull request #229 from AikidoSec/add-hypersql-support
Add support for HyperSQL
2 parents e3a90b3 + c0b67bc commit 4daa950

26 files changed

Lines changed: 955 additions & 1 deletion

File tree

.github/workflows/end2end.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ jobs:
4545
- { name: JavalinPostgres, test_file: end2end/javalin_postgres.py }
4646
- { name: JavalinMySQLKotlin, test_file: end2end/javalin_mysql_kotlin.py }
4747
- { name: SpringBoot2.7Postgres, test_file: end2end/spring_boot_2.7_postgres.py }
48+
- { name: SpringBootHyperSQL, test_file: end2end/spring_boot_hypersql.py }
4849
java-version: [17, 18, 19, 20, 21]
4950
distribution: ['adopt', 'corretto', 'oracle']
5051
steps:

agent/src/main/java/dev/aikido/agent/Wrappers.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ private Wrappers() {}
4141
new JavalinWrapper(),
4242
new JavalinDataWrapper(),
4343
new JavalinContextClearWrapper(),
44-
new SQLiteWrapper()
44+
new SQLiteWrapper(),
45+
new HyperSQLWrapper()
4546
);
4647
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package dev.aikido.agent.wrappers.jdbc;
2+
3+
import dev.aikido.agent.wrappers.Wrapper;
4+
import net.bytebuddy.description.method.MethodDescription;
5+
import net.bytebuddy.description.type.TypeDescription;
6+
import net.bytebuddy.matcher.ElementMatcher;
7+
8+
import java.sql.Connection;
9+
import java.sql.Statement;
10+
11+
import static net.bytebuddy.matcher.ElementMatchers.isSubTypeOf;
12+
import static net.bytebuddy.matcher.ElementMatchers.nameContains;
13+
14+
public class HyperSQLWrapper implements Wrapper {
15+
public String getName() {
16+
return JDBCConnectionAdvice.class.getName();
17+
}
18+
public ElementMatcher<? super MethodDescription> getMatcher() {
19+
return JDBCConnectionAdvice.getMatcher("org.hsqldb.jdbc");
20+
}
21+
22+
@Override
23+
public ElementMatcher<? super TypeDescription> getTypeMatcher() {
24+
return nameContains("org.hsqldb.jdbc")
25+
.and(isSubTypeOf(Connection.class).or(isSubTypeOf(Statement.class)));
26+
}
27+
}

agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/sql_injection/Dialect.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ public Dialect(String dialect) {
1818
} else if(Objects.equals(dialect, "sqlite")) {
1919
rustDialectInt = 12;
2020
humanName = "SQLite";
21+
} else if(Objects.equals(dialect, "hsql database engine")) {
22+
// HyperSQL dialect doesn't exist yet on our tokenizer, so we use generic dialect,
23+
// which is SQL:2016, HyperSQL is closest to this variant.
24+
rustDialectInt = 0;
25+
humanName = "HyperSQL";
2126
} else {
2227
rustDialectInt = 0; // Default option
2328
humanName = "Generic";

end2end/spring_boot_hypersql.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from utils import App, Request
2+
3+
spring_boot_hsql_app = App(8108)
4+
5+
spring_boot_hsql_app.add_payload("sql",
6+
safe_request=Request("/api/pets/create", body={"name": "Bobby"}),
7+
unsafe_request=Request("/api/pets/create", body={"name": "Malicious Pet', 'Gru from the Minions') -- "})
8+
)
9+
10+
spring_boot_hsql_app.test_all_payloads()

sample-apps/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Here is an overview of all of our sample apps together with their port numbers.
2424
- [SpringBoot MVC With SQLite](./SpringBootSQLite) on port [`8100`](http://localhost:8100/)
2525
- [SpringBoot MVC v2.7 With Postgres](./SpringBoot2.7Postgres) on port [`8104`](http://localhost:8104/)
2626
- [SpringBoot MVC With MongoDB](./SpringBootMongo) on port [`8106`](http://localhost:8106/)
27+
- [SpringBoot MVC With HyperSQL](./SpringBootPostgres) on port [`8108`](http://localhost:8108/)
2728

2829
#### Webflux Apps
2930
- [SpringBoot Webflux with Postgres](./SpringWebfluxSampleApp) on port [`8090`](http://localhost:8090/)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
**output**.log
2+
dd-java-agent**
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Define variables
2+
GRADLEW = ./gradlew
3+
JAR_FILE = build/libs/demo-0.0.1-SNAPSHOT.jar
4+
JAVA_AGENT = ../../dist/agent.jar
5+
6+
# Default target
7+
.PHONY: all
8+
all: build
9+
10+
# Build the project
11+
.PHONY: build
12+
build:
13+
@echo "Building the project..."
14+
chmod +x $(GRADLEW)
15+
$(GRADLEW) build
16+
17+
# Run the application with the Java agent
18+
.PHONY: run
19+
run: build
20+
@echo "Running SpringBootHyperSQL with Zen & ENV (http://localhost:8108)"
21+
AIKIDO_LOG_LEVEL="error" \
22+
AIKIDO_TOKEN="token" \
23+
AIKIDO_REALTIME_ENDPOINT="http://localhost:5000/realtime" \
24+
AIKIDO_ENDPOINT="http://localhost:5000" \
25+
AIKIDO_BLOCK=1 \
26+
java -javaagent:$(JAVA_AGENT) -jar $(JAR_FILE) --server.port=8108
27+
28+
# Run the application without Zen
29+
.PHONY: runWithoutZen
30+
runWithoutZen: build
31+
@echo "Running SpringBootHyperSQL without Zen & ENV (http://localhost:8109)"
32+
AIKIDO_TOKEN="random-invalid-token" java -jar $(JAR_FILE) --server.port=8109
33+
34+
# Clean the project
35+
.PHONY: clean
36+
clean:
37+
@echo "Cleaning the project..."
38+
$(GRADLEW) clean
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# SpringBoot+HyperSQL vulnerable sample app
2+
- Inserting a malicious dog : `Malicious Pet', 'Gru from the Minions') -- `
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
plugins {
2+
id 'java'
3+
id 'org.springframework.boot' version '3.3.4'
4+
id 'io.spring.dependency-management' version '1.1.6'
5+
}
6+
7+
java {
8+
sourceCompatibility = '17'
9+
targetCompatibility = '17'
10+
}
11+
12+
group = 'com.example'
13+
version = '0.0.1-SNAPSHOT'
14+
15+
repositories {
16+
mavenCentral()
17+
}
18+
19+
dependencies {
20+
implementation files('../../dist/agent_api.jar')
21+
implementation 'org.springframework.boot:spring-boot-starter'
22+
implementation 'org.springframework.boot:spring-boot-starter-web'
23+
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
24+
compileOnly 'org.projectlombok:lombok'
25+
implementation 'org.hsqldb:hsqldb:2.7.2'
26+
annotationProcessor 'org.projectlombok:lombok'
27+
}

0 commit comments

Comments
 (0)