Skip to content

Commit c496111

Browse files
committed
Enhance WAF result handling by adding keep and duration attributes, and refactor derivatives to attributes
zlib 1.3.1
1 parent 0e8d09f commit c496111

File tree

9 files changed

+66
-23
lines changed

9 files changed

+66
-23
lines changed

.github/workflows/actions.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ defaults:
1111
env:
1212
buildType: RelWithDebInfo
1313
tempdir: ${{ github.workspace }}/build
14-
libddwafVersion: 1.25.1
14+
libddwafVersion: 1.26.0
1515
jobs:
1616
Spotless:
1717
name: spotless
@@ -203,7 +203,7 @@ jobs:
203203
- uses: ilammy/msvc-dev-cmd@v1
204204
name: Setup x86_64 build
205205
with:
206-
toolset: 14.29
206+
toolset: 14.28
207207
arch: amd64
208208
- name: Prepare libddwaf
209209
run: |

libddwaf

Submodule libddwaf updated 89 files

src/main/c/output.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ static jstring _encode_json_gzip_base64_checked(JNIEnv *env,
629629
return ret;
630630
}
631631

632-
jobject output_convert_derivatives_checked(JNIEnv *env, const ddwaf_object *obj)
632+
jobject output_convert_attributes_checked(JNIEnv *env, const ddwaf_object *obj)
633633
{
634634
assert(obj->type == DDWAF_OBJ_MAP);
635635

src/main/c/output.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,5 @@ jobject output_convert_diagnostics_checked(JNIEnv *env,
2222

2323
struct json_segment *output_convert_json(const ddwaf_object *obj);
2424
struct json_segment *output_convert_json(const ddwaf_object *obj);
25-
jobject output_convert_derivatives_checked(JNIEnv *env,
26-
const ddwaf_object *obj);
25+
jobject output_convert_attributes_checked(JNIEnv *env, const ddwaf_object *obj);
2726
jobject convert_ddwaf_object_to_jobject(JNIEnv *env, const ddwaf_object *obj);

src/main/c/waf_jni.c

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,7 +1200,8 @@ static bool _cache_methods(JNIEnv *env)
12001200
"(Lcom/datadog/ddwaf/Waf$Result;"
12011201
"Ljava/lang/String;"
12021202
"Ljava/util/Map;"
1203-
"Ljava/util/Map;)V",
1203+
"Ljava/util/Map;"
1204+
"ZJ)V",
12041205
JMETHOD_CONSTRUCTOR)) {
12051206
goto error;
12061207
}
@@ -2138,7 +2139,24 @@ static jobject _create_result_checked(JNIEnv *env, DDWAF_RET_CODE code,
21382139
const ddwaf_object *ret)
21392140
{
21402141
if (code == DDWAF_OK && !_has_derivative(ret)) {
2141-
return _result_with_data_ok_null;
2142+
// Get keep and duration from the ddwaf_object structure for the OK case
2143+
const ddwaf_object *keep_obj = ddwaf_object_find(ret, "keep", 4);
2144+
jboolean keep = JNI_FALSE;
2145+
if (keep_obj != NULL && keep_obj->type == DDWAF_OBJ_BOOL) {
2146+
keep = (jboolean) ddwaf_object_get_bool(keep_obj);
2147+
}
2148+
2149+
const ddwaf_object *duration_obj =
2150+
ddwaf_object_find(ret, "duration", 8);
2151+
jlong duration = 0;
2152+
if (duration_obj != NULL && duration_obj->type == DDWAF_OBJ_UNSIGNED) {
2153+
duration = (jlong) ddwaf_object_get_unsigned(duration_obj);
2154+
}
2155+
2156+
// Create a new instance with the new constructor signature
2157+
return java_meth_call(env, &result_with_data_init, NULL, _action_ok,
2158+
NULL, _result_with_data_empty_map,
2159+
_result_with_data_empty_map, keep, duration);
21422160
}
21432161

21442162
// Get actions from the new ddwaf_object structure
@@ -2179,20 +2197,33 @@ static jobject _create_result_checked(JNIEnv *env, DDWAF_RET_CODE code,
21792197
// Get attributes (formerly derivatives) from the new ddwaf_object structure
21802198
const ddwaf_object *attributes_obj =
21812199
ddwaf_object_find(ret, "attributes", 10);
2182-
jobject derivatives = NULL;
2200+
jobject attributes = NULL;
21832201
if (attributes_obj != NULL && attributes_obj->type == DDWAF_OBJ_MAP &&
21842202
ddwaf_object_size(attributes_obj) > 0) {
2185-
derivatives = output_convert_derivatives_checked(env, attributes_obj);
2186-
if (!derivatives) {
2187-
java_wrap_exc("%s", "Failed encoding inferred derivatives");
2203+
attributes = output_convert_attributes_checked(env, attributes_obj);
2204+
if (!attributes) {
2205+
java_wrap_exc("%s", "Failed encoding inferred attributes");
21882206
goto err;
21892207
}
21902208
}
21912209

2210+
// Get keep and duration from the ddwaf_object structure
2211+
const ddwaf_object *keep_obj = ddwaf_object_find(ret, "keep", 4);
2212+
jboolean keep = JNI_FALSE;
2213+
if (keep_obj != NULL && keep_obj->type == DDWAF_OBJ_BOOL) {
2214+
keep = (jboolean) ddwaf_object_get_bool(keep_obj);
2215+
}
2216+
2217+
const ddwaf_object *duration_obj = ddwaf_object_find(ret, "duration", 8);
2218+
jlong duration = 0;
2219+
if (duration_obj != NULL && duration_obj->type == DDWAF_OBJ_UNSIGNED) {
2220+
duration = (jlong) ddwaf_object_get_unsigned(duration_obj);
2221+
}
2222+
21922223
jobject result =
21932224
java_meth_call(env, &result_with_data_init, NULL,
21942225
code == DDWAF_OK ? _action_ok : _action_match,
2195-
data_obj, actions_jmap, derivatives);
2226+
data_obj, actions_jmap, attributes, keep, duration);
21962227
if (del_actions_jmap) {
21972228
JNI(DeleteLocalRef, actions_jmap);
21982229
}

src/main/java/com/datadog/ddwaf/Waf.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import org.slf4j.LoggerFactory;
2121

2222
public final class Waf {
23-
public static final String LIB_VERSION = "1.25.1";
23+
public static final String LIB_VERSION = "1.26.0";
2424

2525
private static final Logger LOGGER = LoggerFactory.getLogger(Waf.class);
2626
static final boolean EXIT_ON_LEAK;
@@ -98,31 +98,38 @@ public static class ResultWithData {
9898

9999
// reuse this from JNI when there is no actions or data
100100
public static final ResultWithData OK_NULL =
101-
new ResultWithData(Result.OK, null, EMPTY_ACTIONS, null);
101+
new ResultWithData(Result.OK, null, EMPTY_ACTIONS, null, false, 0);
102102

103103
public final Result result;
104104
public final String data;
105105
public final Map<String, Map<String, Object>> actions;
106-
public final Map<String, String> derivatives;
106+
public final Map<String, String> attributes;
107+
private final boolean keep;
108+
public final long duration; // in nanoseconds
107109

108110
public ResultWithData(
109111
Result result,
110112
String data,
111113
Map<String, Map<String, Object>> actions,
112-
Map<String, String> derivatives) {
114+
Map<String, String> attributes,
115+
boolean keep,
116+
long duration) {
113117
this.result = result;
114118
this.data = data;
115119
this.actions = actions;
116-
this.derivatives = derivatives;
120+
this.attributes = attributes;
121+
this.keep = keep;
122+
this.duration = duration;
117123
}
118124

119125
@Override
120126
public String toString() {
121127
final StringBuilder sb = new StringBuilder("ResultWithData{");
122128
sb.append("result=").append(result);
129+
sb.append(", keep=").append(keep);
123130
sb.append(", data='").append(data).append('\'');
124131
sb.append(", actions='").append(Arrays.asList(actions)).append('\'');
125-
sb.append(", derivatives='").append(derivatives).append('\'');
132+
sb.append(", attributes='").append(attributes).append('\'');
126133
sb.append('}');
127134
return sb.toString();
128135
}

src/test/groovy/com/datadog/ddwaf/FingerprintTests.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ class FingerprintTests implements WafTrait {
9898
metrics
9999
)
100100
assertThat res.result, is(Waf.Result.MATCH)
101-
assertThat res.derivatives.keySet(), contains('_dd.appsec.fp.http.endpoint')
102-
assertThat res.derivatives['_dd.appsec.fp.http.endpoint'], matchesPattern('http-get-.*')
101+
assertThat res.attributes.keySet(), contains('_dd.appsec.fp.http.endpoint')
102+
assertThat res.attributes['_dd.appsec.fp.http.endpoint'], matchesPattern('http-get-.*')
103103
}
104104
}
105105

src/test/groovy/com/datadog/ddwaf/SchemaTests.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,9 @@ class SchemaTests implements WafTrait {
146146
handle = builder.buildWafHandleInstance()
147147
context = new WafContext(handle)
148148
Waf.ResultWithData awd = context.run(data, limits, metrics)
149-
assertThat awd.derivatives, isA(Map)
149+
assertThat awd.attributes, isA(Map)
150150

151-
def schema = new JsonSlurper().parseText(decodeGzipBase64(awd.derivatives['_dd.appsec.s.req.body']))
151+
def schema = new JsonSlurper().parseText(decodeGzipBase64(awd.attributes['_dd.appsec.s.req.body']))
152152
assert deepSortLists(schema) == [
153153
[
154154
'a':[8],

src/test/groovy/com/datadog/ddwaf/WafContextTest.groovy

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ class WafContextTest implements WafTrait {
9494
def result = context.run([:], limits, metrics)
9595
assert result != null
9696
assert result.result == Waf.Result.OK
97+
assert result.keep instanceof Boolean
98+
assert result.duration instanceof Long
99+
assert result.duration >= 0
97100
}
98101

99102
@Test
@@ -104,6 +107,9 @@ class WafContextTest implements WafTrait {
104107

105108
def result = context.run(['server.request.headers.no_cookies': ['user-agent': 'Arachni/v1']], limits, metrics)
106109
assert result.result == Waf.Result.MATCH
110+
assert result.keep instanceof Boolean
111+
assert result.duration instanceof Long
112+
assert result.duration > 0
107113
}
108114

109115
@Test

0 commit comments

Comments
 (0)