Skip to content

upgrade libddwaf java #8584

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
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
7 changes: 3 additions & 4 deletions dd-java-agent/appsec/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ dependencies {
implementation project(':internal-api')
implementation project(':communication')
implementation project(':telemetry')
implementation group: 'io.sqreen', name: 'libsqreen', version: '12.0.0'
implementation group: 'io.sqreen', name: 'libsqreen', version: '14.0.0-SNAPSHOT'
implementation libs.moshi

testImplementation libs.bytebuddy
Expand Down Expand Up @@ -68,8 +68,8 @@ ext {
minimumInstructionCoverage = 0.8
excludedClassesCoverage = [
'com.datadog.appsec.config.MergedAsmData.InvalidAsmDataException',
'com.datadog.appsec.powerwaf.LibSqreenInitialization',
'com.datadog.appsec.powerwaf.PowerWAFModule.PowerWAFDataCallback',
'com.datadog.appsec.ddwaf.LibSqreenInitialization',
'com.datadog.appsec.ddwaf.WAFModule.WAFDataCallback',
'com.datadog.appsec.report.*',
'com.datadog.appsec.config.AppSecConfigServiceImpl.SubscribeFleetServiceRunnable.1',
'com.datadog.appsec.util.StandardizedLogging',
Expand All @@ -89,7 +89,6 @@ ext {
'com.datadog.appsec.config.CurrentAppSecConfig',
// equals() / hashCode() are not well covered
'com.datadog.appsec.config.AppSecConfig.Helper',
'com.datadog.appsec.powerwaf.PowerWAFModule.PowerWAFEventsCallback',
// assert never fails
'com.datadog.appsec.util.StandardizedLogging',
'com.datadog.appsec.util.AbortStartupException',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package datadog.appsec.benchmark;

import ch.qos.logback.classic.Logger;
import io.sqreen.powerwaf.Powerwaf;
import io.sqreen.powerwaf.exception.AbstractPowerwafException;
import io.sqreen.powerwaf.exception.UnsupportedVMException;
import java.lang.reflect.UndeclaredThrowableException;
import com.datadog.appsec.ddwaf.LibSqreenInitialization;
import org.slf4j.LoggerFactory;

public class BenchmarkUtil {
private static final org.slf4j.Logger log = LoggerFactory.getLogger(BenchmarkUtil.class);

public static void disableLogging() {
org.slf4j.Logger root = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
if (root instanceof Logger) {
Expand All @@ -16,13 +15,9 @@ public static void disableLogging() {
}
}

public static void initializePowerwaf() {
try {
Powerwaf.initialize(false);
} catch (AbstractPowerwafException e) {
throw new UndeclaredThrowableException(e);
} catch (UnsupportedVMException e) {
throw new UndeclaredThrowableException(e);
public static void initializeWaf() {
if (!LibSqreenInitialization.WAF) {
log.info("Waf initialization encountered an error");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
import com.datadog.appsec.config.AppSecConfig;
import com.datadog.appsec.config.AppSecConfigDeserializer;
import com.datadog.appsec.event.data.KnownAddresses;
import io.sqreen.powerwaf.Additive;
import io.sqreen.powerwaf.Powerwaf;
import io.sqreen.powerwaf.PowerwafContext;
import io.sqreen.powerwaf.PowerwafMetrics;
import io.sqreen.powerwaf.exception.AbstractPowerwafException;
import com.datadog.ddwaf.NativeWafHandle;
import com.datadog.ddwaf.RuleSetInfo;
import com.datadog.ddwaf.Waf;
import com.datadog.ddwaf.WafBuilder;
import com.datadog.ddwaf.WafMetrics;
import com.datadog.ddwaf.exception.AbstractWafException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
Expand All @@ -37,46 +38,45 @@
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(MICROSECONDS)
@Fork(value = 3)
public class PowerwafBenchmark {
public class WafBenchmark {

static {
BenchmarkUtil.disableLogging();
BenchmarkUtil.initializePowerwaf();
BenchmarkUtil.initializeWaf();
}

PowerwafContext ctx;
WafBuilder wafBuilder;
Map<String, Object> wafData = new HashMap<>();
Powerwaf.Limits limits = new Powerwaf.Limits(50, 500, 1000, 5000000, 5000000);
Waf.Limits limits = new Waf.Limits(50, 500, 1000, 5000000, 5000000);

@Benchmark
public void withMetrics() throws Exception {
PowerwafMetrics metricsCollector = ctx.createMetrics();
Additive add = ctx.openAdditive();
try {
add.run(wafData, limits, metricsCollector);
} finally {
add.close();
WafMetrics metricsCollector = new WafMetrics();
NativeWafHandle nativeWafHandle = wafBuilder.buildNativeWafHandleInstance(null);
Waf.runRules(wafData, limits, metricsCollector, nativeWafHandle);
if (nativeWafHandle != null && nativeWafHandle.isOnline()) {
nativeWafHandle.destroy();
}
}

@Benchmark
public void withoutMetrics() throws Exception {
Additive add = ctx.openAdditive();
try {
add.run(wafData, limits, null);
} finally {
add.close();
NativeWafHandle nativeWafHandle = wafBuilder.buildNativeWafHandleInstance(null);
Waf.runRules(wafData, limits, null, nativeWafHandle);
if (nativeWafHandle != null && nativeWafHandle.isOnline()) {
nativeWafHandle.destroy();
}
}

@Setup(Level.Trial)
public void setUp() throws AbstractPowerwafException, IOException {
public void setUp() throws IOException, AbstractWafException {
InputStream stream = getClass().getClassLoader().getResourceAsStream("test_multi_config.json");
Map<String, AppSecConfig> cfg =
Collections.singletonMap("waf", AppSecConfigDeserializer.INSTANCE.deserialize(stream));
AppSecConfig waf = cfg.get("waf");
ctx = Powerwaf.createContext("waf", waf.getRawConfig());

AppSecConfig wafRules = cfg.get("waf");
wafBuilder = new WafBuilder();
RuleSetInfo[] infoRef = new RuleSetInfo[1];
wafBuilder.addOrUpdateRuleConfig(wafRules.getRawConfig(), infoRef);
wafData.put(KnownAddresses.REQUEST_METHOD.getKey(), "POST");
wafData.put(
KnownAddresses.REQUEST_URI_RAW.getKey(), "/foo/bar?foo=bar&foo=xpto&foo=%3cscript%3e");
Expand Down Expand Up @@ -112,6 +112,8 @@ public void setUp() throws AbstractPowerwafException, IOException {

@TearDown(Level.Trial)
public void teardown() {
ctx.close();
if (wafBuilder != null && wafBuilder.isOnline()) {
wafBuilder.destroy();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
import com.datadog.appsec.blocking.BlockingServiceImpl;
import com.datadog.appsec.config.AppSecConfigService;
import com.datadog.appsec.config.AppSecConfigServiceImpl;
import com.datadog.appsec.ddwaf.WAFModule;
import com.datadog.appsec.event.EventDispatcher;
import com.datadog.appsec.event.ReplaceableEventProducerService;
import com.datadog.appsec.gateway.GatewayBridge;
import com.datadog.appsec.powerwaf.PowerWAFModule;
import com.datadog.appsec.util.AbortStartupException;
import com.datadog.appsec.util.StandardizedLogging;
import com.datadog.ddwaf.exception.AbstractWafException;
import datadog.appsec.api.blocking.Blocking;
import datadog.appsec.api.blocking.BlockingService;
import datadog.communication.ddagent.SharedCommunicationObjects;
Expand Down Expand Up @@ -141,7 +142,13 @@ private static void loadModules(EventDispatcher eventDispatcher, Monitoring moni
EventDispatcher.DataSubscriptionSet dataSubscriptionSet =
new EventDispatcher.DataSubscriptionSet();

final List<AppSecModule> modules = Collections.singletonList(new PowerWAFModule(monitoring));
final List<AppSecModule> modules;
try {
modules = Collections.singletonList(new WAFModule(monitoring));
} catch (AbstractWafException e) {
log.debug("Failed to load modules, appsec module encountered an error ", e);
return;
}
for (AppSecModule module : modules) {
log.debug("Starting appsec module {}", module.getName());
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ private void setAppSecActivation(final AppSecFeatures.Asm asm) {
AppSecSystem.setActive(newState);
if (AppSecSystem.isActive()) {
// On remote activation, we need to re-distribute the last known configuration.
// This may trigger initializations, including PowerWAF if it was lazy loaded.
// This may trigger initializations, including WAF if it was lazy loaded.
this.currentAppSecConfig.dirtyStatus.markAllDirty();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public AppSecConfig getMergedUpdateConfig() throws IOException {
if (dirtyStatus.data) {
final AppSecData data = mergedAsmData.getMergedData();
mso.put("rules_data", data.getRules());
mso.put("exclusion_data", data.getExclusion());
mso.put("exclusions", data.getExclusion());
}
if (dirtyStatus.actions) {
mso.put("actions", getMergedActions());
Expand All @@ -122,13 +122,12 @@ public AppSecConfig getMergedUpdateConfig() throws IOException {
if (log.isDebugEnabled()) {
log.debug(
"Providing WAF config with: "
+ "rules: {}, custom_rules: {}, exclusions: {}, ruleOverrides: {}, rules_data: {}, exclusion_data: {}, actions: {}",
+ "rules: {}, custom_rules: {}, exclusions: {}, ruleOverrides: {}, rules_data: {}, actions: {}",
debugRuleSummary(mso),
debugCustomRuleSummary(mso),
debugExclusionsSummary(mso),
debugRuleOverridesSummary(mso),
debugRulesDataSummary(mso),
debugExclusionDataSummary(mso),
debugActionsSummary(mso));
}
return AppSecConfig.valueOf(mso);
Expand Down Expand Up @@ -160,20 +159,6 @@ private static String debugRulesDataSummary(Map<String, Object> mso) {
+ "]";
}

private static String debugExclusionDataSummary(Map<String, Object> mso) {
List<Map<String, Object>> exclusionData = (List<Map<String, Object>>) mso.get("exclusion_data");
if (exclusionData == null) {
return "<absent>";
}
return "["
+ exclusionData.size()
+ " exclusion data sets with ids "
+ exclusionData.stream()
.map(rd -> String.valueOf(rd.get("id")))
.collect(Collectors.joining(", "))
+ "]";
}

private static String debugRuleOverridesSummary(Map<String, Object> mso) {
List<Map<String, Object>> overrides = (List<Map<String, Object>>) mso.get("rules_override");
if (overrides == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
package com.datadog.appsec.powerwaf;
package com.datadog.appsec.ddwaf;

import com.datadog.appsec.util.StandardizedLogging;
import io.sqreen.powerwaf.Powerwaf;
import com.datadog.ddwaf.Waf;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LibSqreenInitialization {
public static final boolean ONLINE = initPowerWAF();
public static final boolean WAF = initWAF();

private static boolean initPowerWAF() {
private static boolean initWAF() {
try {
boolean simpleLoad = System.getProperty("POWERWAF_SIMPLE_LOAD") != null;
Powerwaf.initialize(simpleLoad);
Waf.initialize(simpleLoad);
} catch (Exception e) {
Logger logger = LoggerFactory.getLogger(LibSqreenInitialization.class);
logger.warn("Error initializing WAF library", e);
StandardizedLogging.libddwafCannotBeLoaded(logger, getLibc());
return false;
}

return true;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
package com.datadog.appsec.powerwaf;
package com.datadog.appsec.ddwaf;

import com.datadog.appsec.config.TraceSegmentPostProcessor;
import com.datadog.appsec.gateway.AppSecRequestContext;
import com.datadog.appsec.report.AppSecEvent;
import com.datadog.ddwaf.RuleSetInfo;
import com.datadog.ddwaf.Waf;
import com.squareup.moshi.JsonAdapter;
import com.squareup.moshi.Moshi;
import com.squareup.moshi.Types;
import datadog.trace.api.internal.TraceSegment;
import datadog.trace.bootstrap.instrumentation.api.Tags;
import io.sqreen.powerwaf.Powerwaf;
import io.sqreen.powerwaf.RuleSetInfo;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

public class PowerWAFInitializationResultReporter implements TraceSegmentPostProcessor {
public class WAFInitializationResultReporter implements TraceSegmentPostProcessor {
private static final String WAF_VERSION = "_dd.appsec.waf.version";
private static final String RULE_ERRORS = "_dd.appsec.event_rules.errors";
private static final String RULES_LOADED = "_dd.appsec.event_rules.loaded";
Expand Down Expand Up @@ -48,7 +48,7 @@ public void processTraceSegment(
segment.setTagTop(RULE_ERRORS, RULES_ERRORS_ADAPTER.toJson(report.getErrors()));
segment.setTagTop(RULES_LOADED, report.getNumRulesOK());
segment.setTagTop(RULE_ERROR_COUNT, report.getNumRulesError());
segment.setTagTop(WAF_VERSION, Powerwaf.LIB_VERSION);
segment.setTagTop(WAF_VERSION, Waf.LIB_VERSION);

segment.setTagTop(Tags.ASM_KEEP, true);
}
Expand Down
Loading