Skip to content

Commit

Permalink
Merge pull request jtmelton#79 from dscrobonia/feature-storage-integr…
Browse files Browse the repository at this point in the history
…ations-2

rule integration with influxdb storage
  • Loading branch information
jtmelton authored Jun 15, 2017
2 parents deed8de + a933041 commit 65a609b
Show file tree
Hide file tree
Showing 7 changed files with 381 additions and 181 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import javax.inject.Inject;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
Expand All @@ -23,16 +25,20 @@
import org.owasp.appsensor.core.Threshold;
import org.owasp.appsensor.core.User;
import org.owasp.appsensor.core.analysis.EventAnalysisEngine;
import org.owasp.appsensor.core.configuration.server.ServerConfiguration;
import org.owasp.appsensor.core.criteria.SearchCriteria;
import org.owasp.appsensor.core.rule.Clause;
import org.owasp.appsensor.core.rule.Rule;
import org.owasp.appsensor.core.rule.MonitorPoint;
import org.owasp.appsensor.core.rule.Rule;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
* Basic test for the {@link AggregateEventAnalysisEngine}.
* Basic test for the {@link AggregateEventAnalysisEngine}. Built to be extended by other components
* to test integration with the rules engine.
*
* Tests should finish with the last event triggering an attack, so that each test can start
* assuming that only the events created in each test will count towards the attack threshold.
* todo: fix this by clearing events or adding time before each test
*
* @author David Scrobonia ([email protected])
* @author John Melton ([email protected]) http://www.jtmelton.com/
Expand All @@ -42,21 +48,23 @@
@ContextConfiguration(locations={"classpath:base-context.xml"})
public class SimpleAggregateEventAnalysisEngineTest {

private static User bob = new User("bob");
protected static User bob = new User("bob");

private static DetectionPoint detectionPoint1 = new DetectionPoint();
protected static ArrayList<DetectionPoint> detectionPoints = null;

private static Collection<String> detectionSystems1 = new ArrayList<String>();
protected static Collection<String> detectionSystems1 = new ArrayList<String>();

private static DetectionSystem detectionSystem1 = new DetectionSystem("localhostme");
protected static DetectionSystem detectionSystem1 = new DetectionSystem("localhostme");

private static HashMap<String, SearchCriteria> criteria = new HashMap<String, SearchCriteria>();
protected static HashMap<String, SearchCriteria> criteria = new HashMap<String, SearchCriteria>();

private static AggregateEventAnalysisEngine myEngine = null;
protected static AggregateEventAnalysisEngine rulesEngine = null;

private static ArrayList<Rule> rules = null;
protected static ArrayList<Rule> rules = null;

protected int sleepAmount = 10;
protected static DateTime time;

protected static int SLEEP_AMOUNT = 10;

@Inject
AppSensorServer appSensorServer;
Expand All @@ -66,108 +74,107 @@ public class SimpleAggregateEventAnalysisEngineTest {

@BeforeClass
public static void doSetup() {
detectionPoint1.setCategory(DetectionPoint.Category.INPUT_VALIDATION);
detectionPoint1.setLabel("IE1");
// instantiate member variables

detectionSystems1.add(detectionSystem1.getDetectionSystemId());

detectionPoints = generateDetectionPoints();

rules = generateRules();

criteria.put("all", new SearchCriteria().setDetectionSystemIds(detectionSystems1));

criteria.put("dp1", new SearchCriteria().
setUser(bob).
setDetectionPoint(detectionPoint1).
setDetectionPoint(new DetectionPoint(DetectionPoint.Category.INPUT_VALIDATION, "IE1")).
setDetectionSystemIds(detectionSystems1));

rules = generateRules();

criteria.put("rule1", new SearchCriteria().
setUser(bob).
setRule(rules.get(0)).
setDetectionSystemIds(detectionSystems1));

time = DateTime.now().minusMinutes(2).toDateTime(DateTimeZone.UTC);
}

@Before
public void initializeTest() {
if (myEngine == null) {
initialSetup();
}
rulesEngine = getRulesEngine();

// clear any existing rules & detection points
ArrayList<Rule> emptyRules = new ArrayList<Rule>();
appSensorServer.getConfiguration().setRules(emptyRules);

// clear rules
setRule(appSensorServer, null);
ArrayList<DetectionPoint> emptyDps = new ArrayList<DetectionPoint>();
appSensorServer.getConfiguration().setDetectionPoints(emptyDps);
}

public void initialSetup() {
//instantiate server
ServerConfiguration updatedConfiguration = appSensorServer.getConfiguration();
updatedConfiguration.setDetectionPoints(loadMockedDetectionPoints());
appSensorServer.setConfiguration(updatedConfiguration);
@Test
public void test1_DP1() throws Exception {
// add rules/detection points
ArrayList<Rule> rulesToAdd = new ArrayList<Rule>();
rulesToAdd.add(rules.get(0));
appSensorServer.getConfiguration().setRules(rulesToAdd);

Collection<EventAnalysisEngine> engines = appSensorServer.getEventAnalysisEngines();
// add detection point
ArrayList<DetectionPoint> dpsToAdd = new ArrayList<DetectionPoint>();
dpsToAdd.add(detectionPoints.get(0));
appSensorServer.getConfiguration().setDetectionPoints(dpsToAdd);

for (EventAnalysisEngine engine : engines) {
if (engine instanceof AggregateEventAnalysisEngine){
myEngine = (AggregateEventAnalysisEngine)engine;
}
}
DetectionPoint detectionPoint1 = detectionPoints.get(0);

setRule(appSensorServer, null);
}
// get events and attacks
int numEvents = appSensorServer.getEventStore().findEvents(criteria.get("dp1")).size();
int numDPAttacks = appSensorServer.getAttackStore().findAttacks(criteria.get("dp1")).size();
int numRuleAttacks = appSensorServer.getAttackStore().findAttacks(criteria.get("rule1")).size();

@Test
public void test1_DP1() throws Exception {
//Add rule
setRule(appSensorServer, rules.get(0));
// useless sanity check
assertEquals(numEvents, appSensorServer.getEventStore().findEvents(criteria.get("dp1")).size());
assertEquals(numDPAttacks, appSensorServer.getAttackStore().findAttacks(criteria.get("dp1")).size());
assertEquals(numRuleAttacks, appSensorServer.getAttackStore().findAttacks(criteria.get("rule1")).size());

//is empty
assertEventsAndAttacks(0, 0, criteria.get("all"));

// 3 events and triggered attack
generateEvents(sleepAmount*3, detectionPoint1, 3, "rule1");
assertEventsAndAttacks(3, 1, criteria.get("dp1"));
assertEquals(1, appSensorServer.getAttackStore().findAttacks(criteria.get("rule1")).size());
addEvents(bob, detectionPoint1, 3);
numEvents += 3; numDPAttacks++; numRuleAttacks++;

assertEquals(numEvents, appSensorServer.getEventStore().findEvents(criteria.get("dp1")).size());
assertEquals(numDPAttacks, appSensorServer.getAttackStore().findAttacks(criteria.get("dp1")).size());
assertEquals(numRuleAttacks, appSensorServer.getAttackStore().findAttacks(criteria.get("rule1")).size());

// 1 event and no new attack
generateEvents(sleepAmount, detectionPoint1, 1, "rule1");
assertEventsAndAttacks(4, 1, criteria.get("dp1"));
assertEquals(1, appSensorServer.getAttackStore().findAttacks(criteria.get("rule1")).size());
addEvent(bob, detectionPoint1);
numEvents += 1;

assertEquals(numEvents, appSensorServer.getEventStore().findEvents(criteria.get("dp1")).size());
assertEquals(numDPAttacks, appSensorServer.getAttackStore().findAttacks(criteria.get("dp1")).size());
assertEquals(numRuleAttacks, appSensorServer.getAttackStore().findAttacks(criteria.get("rule1")).size());

// 2 events and 2 total attack
generateEvents(sleepAmount*2, detectionPoint1, 2, "rule1");
assertEventsAndAttacks(6, 2, criteria.get("dp1"));
assertEquals(2, appSensorServer.getAttackStore().findAttacks(criteria.get("rule1")).size());
addEvents(bob, detectionPoint1, 2);
numEvents += 2; numDPAttacks++; numRuleAttacks++;

assertEquals(numEvents, appSensorServer.getEventStore().findEvents(criteria.get("dp1")).size());
assertEquals(numDPAttacks, appSensorServer.getAttackStore().findAttacks(criteria.get("dp1")).size());
assertEquals(numRuleAttacks, appSensorServer.getAttackStore().findAttacks(criteria.get("rule1")).size());
}

//assumes no rules will be triggered until last event
private void generateEvents (int time, DetectionPoint detectionPoint, int eventCount, String ruleName) throws Exception {
int attackCount = appSensorServer.getAttackStore().findAttacks(criteria.get(ruleName)).size();
protected void addEvent(User user, DetectionPoint detectionPoint) {
appSensorClient.getEventManager().addEvent(new Event(user, detectionPoint, time.toString(), detectionSystem1));
time = time.plusMillis(SLEEP_AMOUNT);

for (int i = 0; i < eventCount; i++) {
assertEquals(attackCount, appSensorServer.getAttackStore().findAttacks(criteria.get(ruleName)).size());
appSensorClient.getEventManager().addEvent(new Event(bob, detectionPoint, new DetectionSystem("localhostme")));
Thread.sleep(time/eventCount);
}
}

private void assertEventsAndAttacks (int eventCount, int attackCount, SearchCriteria criteria) {
if (criteria.getRule() == null) {
assertEquals(eventCount, appSensorServer.getEventStore().findEvents(criteria).size());
protected void addEvents(User user, DetectionPoint detectionPoint, int count) {
for (int i=0; i<count; i++) {
appSensorClient.getEventManager().addEvent(new Event(user, detectionPoint, time.toString(), detectionSystem1));
time = time.plusMillis(SLEEP_AMOUNT);
}
assertEquals(attackCount, appSensorServer.getAttackStore().findAttacks(criteria).size());
}

private void setRule(AppSensorServer server, Rule rule) {
Collection<Rule> rules = new ArrayList<Rule>();
rules.add(rule);
ServerConfiguration updatedConfiguration = appSensorServer.getConfiguration();
updatedConfiguration.setRules(rules);
appSensorServer.setConfiguration(updatedConfiguration);
}

private static ArrayList<Rule> generateRules() {
final ArrayList<Rule> configuredRules = new ArrayList<Rule>();
// intervals
Interval minutes5 = new Interval(5, Interval.MINUTES);
Interval minutes16 = new Interval(16, Interval.MINUTES);

// detection points
MonitorPoint point1 = new MonitorPoint(new DetectionPoint(DetectionPoint.Category.INPUT_VALIDATION, "IE1", new Threshold(3, minutes5)));
Expand All @@ -182,7 +189,7 @@ private static ArrayList<Rule> generateRules() {
// responses
ArrayList<Response> responses = generateResponses();

//rule 1: DP1
// rule 1: DP1
ArrayList<Clause> clauses1 = new ArrayList<Clause>();
clauses1.add(clause1);

Expand All @@ -191,25 +198,25 @@ private static ArrayList<Rule> generateRules() {
ArrayList<org.owasp.appsensor.core.rule.Expression> expressions1 = new ArrayList<org.owasp.appsensor.core.rule.Expression>();
expressions1.add(expression1);

configuredRules.add(new Rule("00000000-0000-0000-0000-000000000011", minutes16, expressions1, responses, "Rule 1"));
configuredRules.add(new Rule("00000000-0000-0000-0000-000000000011", minutes5, expressions1, responses, "Rule 1"));

return configuredRules;
}

private static Collection<DetectionPoint> loadMockedDetectionPoints() {
final Collection<DetectionPoint> configuredDetectionPoints = new ArrayList<DetectionPoint>();

ArrayList<Response> responses = generateResponses();

Interval minutes5 = new Interval(5, Interval.MINUTES);
private static ArrayList<DetectionPoint> generateDetectionPoints() {
ArrayList<DetectionPoint> detectionPoints = new ArrayList<DetectionPoint>();

Threshold events3minutes5 = new Threshold(3, minutes5);
// dp1: 3 events in 5 minutes
DetectionPoint detectionPoint1 = new DetectionPoint();

DetectionPoint point1 = new DetectionPoint(DetectionPoint.Category.INPUT_VALIDATION, "IE1", events3minutes5, responses);
detectionPoint1.setCategory(DetectionPoint.Category.INPUT_VALIDATION);
detectionPoint1.setLabel("IE1");
detectionPoint1.setThreshold(new Threshold(3, new Interval(5, Interval.MINUTES)));
detectionPoint1.setResponses(generateResponses());

configuredDetectionPoints.add(point1);
detectionPoints.add(detectionPoint1);

return configuredDetectionPoints;
return detectionPoints;
}

private static ArrayList<Response> generateResponses() {
Expand Down Expand Up @@ -242,4 +249,15 @@ private static ArrayList<Response> generateResponses() {
return responses;
}

public AggregateEventAnalysisEngine getRulesEngine() {
Collection<EventAnalysisEngine> engines = appSensorServer.getEventAnalysisEngines();

for (EventAnalysisEngine engine : engines) {
if (engine instanceof AggregateEventAnalysisEngine){
return (AggregateEventAnalysisEngine)engine;
}
}

return null;
}
}
11 changes: 9 additions & 2 deletions storage-providers/appsensor-storage-influxdb/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-analysis-rules</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.owasp.appsensor</groupId>
Expand Down Expand Up @@ -91,5 +98,5 @@
<artifactId>appsensor-parent</artifactId>
<version>2.3.2</version>
</parent>
</project>

</project>
Loading

0 comments on commit 65a609b

Please sign in to comment.