Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,6 @@ public static Res report(ContextObject newContext) {
if (blockedUARes != null)
return blockedUARes;

// Check for attack waves
if (AttackWaveDetectorStore.check(newContext)) {
AttackQueue.add(
DetectedAttackWave.createAPIEvent(newContext)
);
StatisticsStore.incrementAttackWavesDetected();
}

return null;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package dev.aikido.agent_api.collectors;

import dev.aikido.agent_api.api_discovery.APISpec;
import dev.aikido.agent_api.background.cloud.api.events.DetectedAttackWave;
import dev.aikido.agent_api.context.Context;
import dev.aikido.agent_api.context.ContextObject;
import dev.aikido.agent_api.context.RouteMetadata;
import dev.aikido.agent_api.storage.AttackQueue;
import dev.aikido.agent_api.storage.attack_wave_detector.AttackWaveDetectorStore;
import dev.aikido.agent_api.storage.routes.RoutesStore;
import dev.aikido.agent_api.storage.statistics.StatisticsStore;

import static dev.aikido.agent_api.api_discovery.GetApiInfo.getApiInfo;
import static dev.aikido.agent_api.helpers.url.IsUsefulRoute.isUsefulRoute;
Expand All @@ -20,9 +24,22 @@ private WebResponseCollector() {}
*/
public static void report(int statusCode) {
ContextObject context = Context.get();
if (statusCode <= 0 || context == null) {
if (context == null) {
return;
}

// Check for attack waves
if (AttackWaveDetectorStore.check(context)) {
Comment thread
bitterpanda63 marked this conversation as resolved.
AttackQueue.add(
DetectedAttackWave.createAPIEvent(context)
);
StatisticsStore.incrementAttackWavesDetected();
}

if (statusCode <= 0) {
return; // Status code below or equal to zero: Invalid request
}

RouteMetadata routeMetadata = context.getRouteMetadata();
if (routeMetadata == null || !isUsefulRoute(statusCode, context.getRoute(), context.getMethod())) {
return;
Expand All @@ -37,4 +54,4 @@ public static void report(int statusCode) {
RoutesStore.updateApiSpec(routeMetadata, apiSpec);
}
}
}
}
38 changes: 0 additions & 38 deletions agent_api/src/test/java/collectors/WebRequestCollectorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -260,42 +260,4 @@ void testReport_ipNotAllowedUsingLists_Ip_Bypassed() {
assertNull(response);
assertNull(Context.get());
}

@Test
void testReport_WithAttackWaveContext() throws InterruptedException {
ContextObject attackWaveCtx = new EmptySampleContextObject("/wp-config.php", "BADMETHOD", Map.of());

WebRequestCollector.Res response = WebRequestCollector.report(attackWaveCtx);
assertNull(response);
assertEquals(0, AttackQueue.getSize());
assertEquals(0, StatisticsStore.getStatsRecord().requests().attackWaves().total());

// 2...14
WebRequestCollector.report(attackWaveCtx);
WebRequestCollector.report(attackWaveCtx);
WebRequestCollector.report(attackWaveCtx);
WebRequestCollector.report(attackWaveCtx);
WebRequestCollector.report(attackWaveCtx);
WebRequestCollector.report(attackWaveCtx);
WebRequestCollector.report(attackWaveCtx);
WebRequestCollector.report(attackWaveCtx);
WebRequestCollector.report(attackWaveCtx);
WebRequestCollector.report(attackWaveCtx);
WebRequestCollector.report(attackWaveCtx);
WebRequestCollector.report(attackWaveCtx);
WebRequestCollector.report(attackWaveCtx);

WebRequestCollector.Res response2 = WebRequestCollector.report(attackWaveCtx);
assertNull(response2);
assertEquals(1, AttackQueue.getSize());
DetectedAttackWave.DetectedAttackWaveEvent event = (DetectedAttackWave.DetectedAttackWaveEvent) AttackQueue.get();
assertEquals("192.168.1.1", event.request().ipAddress());
assertEquals("web", event.request().source());
assertEquals(null, event.request().userAgent());
assertEquals("detected_attack_wave", event.type());
assertEquals(null, event.attack().user());
assertEquals(0, event.attack().metadata().size());
// check stats changed
assertEquals(1, StatisticsStore.getStatsRecord().requests().attackWaves().total());
}
}
47 changes: 47 additions & 0 deletions agent_api/src/test/java/collectors/WebResponseCollectorTest.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
package collectors;

import dev.aikido.agent_api.SetUser;
import dev.aikido.agent_api.background.cloud.api.events.DetectedAttackWave;
import dev.aikido.agent_api.collectors.WebRequestCollector;
import dev.aikido.agent_api.collectors.WebResponseCollector;
import dev.aikido.agent_api.context.Context;
import dev.aikido.agent_api.context.ContextObject;
import dev.aikido.agent_api.context.RouteMetadata;
import dev.aikido.agent_api.storage.AttackQueue;
import dev.aikido.agent_api.storage.routes.RoutesStore;
import dev.aikido.agent_api.storage.statistics.StatisticsStore;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.Test;
import utils.EmptySampleContextObject;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.*;

Expand Down Expand Up @@ -92,5 +99,45 @@ public void testResponseCollectorWithInvalidMethodOrStatusCode() throws SQLExcep
WebResponseCollector.report(-200);
assertEquals(0, RoutesStore.getRoutesAsList().length);
}
@Test
void testReport_WithAttackWaveContext() throws InterruptedException {
ContextObject attackWaveCtx = new EmptySampleContextObject("/wp-config.php", "BADMETHOD", Map.of());
Context.set(attackWaveCtx);

SetUser.setUser(new SetUser.UserObject("123", "Jane Doe"));

WebResponseCollector.report(500);
assertEquals(0, AttackQueue.getSize());
assertEquals(0, StatisticsStore.getStatsRecord().requests().attackWaves().total());

// 2...14
WebResponseCollector.report(500);
WebResponseCollector.report(500);
WebResponseCollector.report(500);
WebResponseCollector.report(500);
WebResponseCollector.report(500);
WebResponseCollector.report(500);
WebResponseCollector.report(500);
WebResponseCollector.report(500);
WebResponseCollector.report(500);
WebResponseCollector.report(500);
WebResponseCollector.report(500);
WebResponseCollector.report(500);
WebResponseCollector.report(500);

WebResponseCollector.report(500);
assertEquals(1, AttackQueue.getSize());
DetectedAttackWave.DetectedAttackWaveEvent event = (DetectedAttackWave.DetectedAttackWaveEvent) AttackQueue.get();
assertEquals("192.168.1.1", event.request().ipAddress());
assertEquals("web", event.request().source());
assertEquals(null, event.request().userAgent());
assertEquals("detected_attack_wave", event.type());
assertEquals("123", event.attack().user().id());
assertEquals("Jane Doe", event.attack().user().name());

assertEquals(0, event.attack().metadata().size());
// check stats changed
assertEquals(1, StatisticsStore.getStatsRecord().requests().attackWaves().total());
}
}