Skip to content

Commit dac9126

Browse files
Merge pull request #101 from AikidoSec/AIK-4287
AIK-4287 Include user in attack event
2 parents addd9e0 + 6152261 commit dac9126

File tree

9 files changed

+39
-20
lines changed

9 files changed

+39
-20
lines changed

agent_api/src/main/java/dev/aikido/agent_api/background/cloud/api/events/DetectedAttack.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import dev.aikido.agent_api.background.cloud.CloudConnectionManager;
44
import dev.aikido.agent_api.background.cloud.GetManagerInfo;
55
import dev.aikido.agent_api.context.ContextObject;
6+
import dev.aikido.agent_api.context.User;
67
import dev.aikido.agent_api.vulnerabilities.Attack;
78

89
import java.util.Map;
@@ -40,7 +41,8 @@ public record AttackData (
4041
// Auxiliary attack data :
4142
String module,
4243
boolean blocked,
43-
String stack
44+
String stack,
45+
User user
4446
) {};
4547

4648
public static DetectedAttackEvent createAPIEvent(Attack attack, ContextObject context, CloudConnectionManager connectionManager) {
@@ -56,7 +58,7 @@ public static DetectedAttackEvent createAPIEvent(Attack attack, ContextObject co
5658
);
5759
AttackData attackData = new AttackData(
5860
attack.kind, attack.operation, attack.source, attack.pathToPayload, attack.payload, attack.metadata,
59-
"MODULE?", connectionManager.shouldBlock(), attack.stack
61+
"module", connectionManager.shouldBlock(), attack.stack, attack.user
6062
);
6163
return new DetectedAttackEvent(
6264
"detected_attack", // type

agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/Attack.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package dev.aikido.agent_api.vulnerabilities;
22

3+
import dev.aikido.agent_api.context.User;
4+
35
import java.util.Map;
46

57
public class Attack {
@@ -10,14 +12,16 @@ public class Attack {
1012
public final Map<String, String> metadata;
1113
public final String payload;
1214
public final String stack;
13-
public Attack(String op, Vulnerabilities.Vulnerability vulnerability, String source, String pathToPayload, Map<String, String> metadata, String payload, String stack) {
15+
public final User user;
16+
public Attack(String op, Vulnerabilities.Vulnerability vulnerability, String source, String pathToPayload, Map<String, String> metadata, String payload, String stack, User user) {
1417
this.operation = op;
1518
this.kind = vulnerability.getKind();
1619
this.source = source;
1720
this.pathToPayload = pathToPayload;
1821
this.metadata = metadata;
1922
this.payload = payload;
2023
this.stack = stack;
24+
this.user = user;
2125
}
2226

2327
@Override
@@ -30,6 +34,6 @@ public String toString() {
3034
", metadata=" + metadata +
3135
", payload='" + payload + '\'' +
3236
", stack='" + stack + '\'' +
33-
'}';
37+
", user=" + user.id() + '}';
3438
}
3539
}

agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/Scanner.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ public static void scanForGivenVulnerability(Vulnerabilities.Vulnerability vulne
4444
exception = Optional.of(detectorResult.getException());
4545
// Report attack :
4646
reportAttack(
47-
new Attack(operation, vulnerability, source, path, detectorResult.getMetadata(), userInput, getCurrentStackTrace()), ctx
47+
new Attack(
48+
operation, vulnerability, source,
49+
path, detectorResult.getMetadata(), userInput,
50+
getCurrentStackTrace(), ctx.getUser()), ctx
4851
);
4952
break;
5053
}

agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/ssrf/SSRFDetector.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ public Attack run(String hostname, int port, List<String> ipAddresses, String op
5454
"port", String.valueOf(port)
5555
),
5656
attackFindings.payload(),
57-
getCurrentStackTrace()
57+
getCurrentStackTrace(),
58+
context.getUser()
5859
);
5960
}
6061

agent_api/src/test/java/vulnerabilities/AttackTest.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package vulnerabilities;
22

3+
import dev.aikido.agent_api.context.User;
34
import dev.aikido.agent_api.vulnerabilities.Attack;
45
import dev.aikido.agent_api.vulnerabilities.Vulnerabilities;
56
import org.junit.jupiter.api.Test;
@@ -22,9 +23,10 @@ public void testAttackConstructor() {
2223
metadata.put("userId", "123");
2324
String payload = "SELECT * FROM users WHERE id = 1";
2425
String stack = "Stack trace here";
26+
User user = new User("id", "name", "1.1.1.1", 0);
2527

2628
// Act
27-
Attack attack = new Attack(operation, vulnerability, source, pathToPayload, metadata, payload, stack);
29+
Attack attack = new Attack(operation, vulnerability, source, pathToPayload, metadata, payload, stack, user);
2830

2931
// Assert
3032
assertEquals(operation, attack.operation);
@@ -34,8 +36,9 @@ public void testAttackConstructor() {
3436
assertEquals(metadata, attack.metadata);
3537
assertEquals(payload, attack.payload);
3638
assertEquals(stack, attack.stack);
39+
assertEquals(user, attack.user);
3740
assertEquals(
38-
"Attack{operation='SQL Injection', kind='sql_injection', source='User Input', pathToPayload='/api/vulnerable', metadata={userId=123}, payload='SELECT * FROM users WHERE id = 1', stack='Stack trace here'}",
41+
"Attack{operation='SQL Injection', kind='sql_injection', source='User Input', pathToPayload='/api/vulnerable', metadata={userId=123}, payload='SELECT * FROM users WHERE id = 1', stack='Stack trace here', user=id}",
3942
attack.toString()
4043
);
4144
}
@@ -50,9 +53,10 @@ public void testAttackWithEmptyMetadata() {
5053
Map<String, String> metadata = new HashMap<>(); // Empty metadata
5154
String payload = "<script>alert('XSS');</script>";
5255
String stack = "Stack trace here";
56+
User user = new User("123", "name", "1.1.1.1", 0);
5357

5458
// Act
55-
Attack attack = new Attack(operation, vulnerability, source, pathToPayload, metadata, payload, stack);
59+
Attack attack = new Attack(operation, vulnerability, source, pathToPayload, metadata, payload, stack, user);
5660

5761
// Assert
5862
assertEquals(operation, attack.operation);
@@ -63,7 +67,7 @@ public void testAttackWithEmptyMetadata() {
6367
assertEquals(payload, attack.payload);
6468
assertEquals(stack, attack.stack);
6569
assertEquals(
66-
"Attack{operation='XSS Attack', kind='sql_injection', source='User Input', pathToPayload='/api/vulnerable', metadata={}, payload='<script>alert('XSS');</script>', stack='Stack trace here'}",
70+
"Attack{operation='XSS Attack', kind='sql_injection', source='User Input', pathToPayload='/api/vulnerable', metadata={}, payload='<script>alert('XSS');</script>', stack='Stack trace here', user=123}",
6771
attack.toString()
6872
);
6973
}

end2end/spring_boot_mysql.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616

1717
event_handler = EventHandler()
1818
event_handler.reset()
19-
test_safe_vs_unsafe_payloads(payloads, urls) # Test MySQL driver
20-
test_safe_vs_unsafe_payloads(payloads, urls, "/mariadb") # Also test MariaDB driver
19+
test_safe_vs_unsafe_payloads(payloads, urls, user_id="123") # Test MySQL driver
20+
test_safe_vs_unsafe_payloads(payloads, urls, "/mariadb", user_id="456") # Also test MariaDB driver
2121

2222
# Test blocklists :
2323
test_ip_blocking("http://localhost:8082/")

end2end/spring_boot_mysql/test_two_sql_attacks.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,6 @@ def test_two_sql_attacks(event_handler):
1919
assert_eq(val1=attack1["source"], val2=attack2["source"], equals="body")
2020
# Different :
2121
assert_eq(attack1["operation"], equals="(MySQL Connector/J) java.sql.Connection.prepareStatement")
22-
assert_eq(attack2["operation"], equals="(MariaDB Connector/J) java.sql.Connection.prepareStatement")
22+
assert_eq(attack2["operation"], equals="(MariaDB Connector/J) java.sql.Connection.prepareStatement")
23+
assert_eq(attack1["user"]["id"], equals="123")
24+
assert_eq(attack2["user"]["id"], equals="456")

end2end/utils/make_requests.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
import urllib.parse
33

44
# Function to make a POST request
5-
def make_post_request(url, data, status_code):
6-
response = requests.post(url, json=data)
5+
def make_post_request(url, data, status_code, user_id=None):
6+
headers = {}
7+
if user_id is not None:
8+
headers['user'] = user_id
9+
response = requests.post(url, json=data, headers=headers)
710

811
# Assert that the status code is 200
912
assert response.status_code == status_code, f"Expected status code {status_code} but got {response.status_code}"

end2end/utils/test_safe_vs_unsafe_payloads.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
from .make_requests import make_post_request, make_path_var_request
22

3-
def test_safe_vs_unsafe_payloads(payloads, urls, route=""):
3+
def test_safe_vs_unsafe_payloads(payloads, urls, route="", user_id=None):
44
print("Safe req to : (1) " + urls["enabled"])
5-
make_post_request(urls["enabled"] + route, payloads["safe"], status_code=200)
5+
make_post_request(urls["enabled"] + route, payloads["safe"], status_code=200, user_id=user_id)
66
print("Safe req to : (0) " + urls["disabled"])
7-
make_post_request(urls["disabled"] + route, payloads["safe"], status_code=200)
7+
make_post_request(urls["disabled"] + route, payloads["safe"], status_code=200, user_id=user_id)
88
print("Unsafe req to : (1) " + urls["enabled"])
9-
make_post_request(urls["enabled"] + route, payloads["unsafe"], status_code=500)
9+
make_post_request(urls["enabled"] + route, payloads["unsafe"], status_code=500, user_id=user_id)
1010
print("Unsafe req to : (0) " + urls["disabled"])
11-
make_post_request(urls["disabled"] + route, payloads["unsafe"], status_code=200)
11+
make_post_request(urls["disabled"] + route, payloads["unsafe"], status_code=200, user_id=user_id)
1212

1313
def test_payloads_path_variables(payloads, urls, route=""):
1414
print("Safe req to : (1) " + urls["enabled"])

0 commit comments

Comments
 (0)