Skip to content

Commit e1a527e

Browse files
author
jens
committed
Make detect_sqli and detect_xss compatible with libinjection v4
1 parent 58fc3da commit e1a527e

3 files changed

Lines changed: 137 additions & 50 deletions

File tree

src/operators/detect_sqli.cc

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,45 +17,70 @@
1717

1818
#include <string>
1919
#include <list>
20+
#include <array>
2021

2122
#include "src/operators/operator.h"
23+
#include "src/operators/libinjection_utils.h"
2224
#include "libinjection/src/libinjection.h"
25+
#include "libinjection/src/libinjection_error.h"
2326

24-
namespace modsecurity {
25-
namespace operators {
26-
27+
namespace modsecurity::operators {
2728

2829
bool DetectSQLi::evaluate(Transaction *t, RuleWithActions *rule,
2930
const std::string& input, RuleMessage &ruleMessage) {
30-
char fingerprint[8];
31-
int issqli;
3231

33-
issqli = libinjection_sqli(input.c_str(), input.length(), fingerprint);
32+
std::array<char, 8> fingerprint{};
33+
34+
const injection_result_t sqli_result =
35+
libinjection_sqli(input.c_str(), input.length(), fingerprint.data());
3436

35-
if (!t) {
36-
goto tisempty;
37+
if (t == nullptr) {
38+
return isMaliciousLibinjectionResult(sqli_result);
3739
}
3840

39-
if (issqli) {
40-
t->m_matched.push_back(fingerprint);
41-
ms_dbg_a(t, 4, "detected SQLi using libinjection with " \
42-
"fingerprint '" + std::string(fingerprint) + "' at: '" +
43-
input + "'");
44-
if (rule && rule->hasCaptureAction()) {
45-
t->m_collections.m_tx_collection->storeOrUpdateFirst(
46-
"0", std::string(fingerprint));
47-
ms_dbg_a(t, 7, "Added DetectSQLi match TX.0: " + \
48-
std::string(fingerprint));
49-
}
50-
} else {
51-
ms_dbg_a(t, 9, "detected SQLi: not able to find an " \
52-
"inject on '" + input + "'");
41+
switch (sqli_result) {
42+
case LIBINJECTION_RESULT_TRUE:
43+
t->m_matched.emplace_back(fingerprint.data());
44+
45+
ms_dbg_a(t, 4,
46+
std::string("detected SQLi using libinjection with fingerprint '")
47+
+ fingerprint.data() + "' at: '" + input + "'")
48+
49+
if (rule != nullptr && rule->hasCaptureAction()) {
50+
t->m_collections.m_tx_collection->storeOrUpdateFirst(
51+
"0", std::string(fingerprint.data()));
52+
53+
ms_dbg_a(t, 7,
54+
std::string("Added DetectSQLi match TX.0: ")
55+
+ fingerprint.data())
56+
}
57+
break;
58+
59+
case LIBINJECTION_RESULT_ERROR:
60+
ms_dbg_a(t, 4,
61+
std::string("libinjection parser error during SQLi analysis (")
62+
+ libinjectionResultToString(sqli_result)
63+
+ "); treating as match (fail-safe). Input: '"
64+
+ input + "'")
65+
66+
if (rule != nullptr && rule->hasCaptureAction()) {
67+
t->m_collections.m_tx_collection->storeOrUpdateFirst(
68+
"0", input);
69+
70+
ms_dbg_a(t, 7,
71+
std::string("Added DetectSQLi error input TX.0: ")
72+
+ input)
73+
}
74+
break;
75+
76+
case LIBINJECTION_RESULT_FALSE:
77+
ms_dbg_a(t, 9,
78+
std::string("libinjection was not able to find any SQLi in: ")
79+
+ input)
80+
break;
5381
}
5482

55-
tisempty:
56-
return issqli != 0;
83+
return isMaliciousLibinjectionResult(sqli_result);
5784
}
5885

59-
60-
} // namespace operators
61-
} // namespace modsecurity
86+
} // namespace modsecurity::operators

src/operators/detect_xss.cc

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,36 +18,50 @@
1818
#include <string>
1919

2020
#include "src/operators/operator.h"
21+
#include "src/operators/libinjection_utils.h"
2122
#include "libinjection/src/libinjection.h"
23+
#include "libinjection/src/libinjection_error.h"
2224

23-
24-
namespace modsecurity {
25-
namespace operators {
26-
25+
namespace modsecurity::operators {
2726

2827
bool DetectXSS::evaluate(Transaction *t, RuleWithActions *rule,
2928
const std::string& input, RuleMessage &ruleMessage) {
30-
int is_xss;
31-
32-
is_xss = libinjection_xss(input.c_str(), input.length());
33-
34-
if (t) {
35-
if (is_xss) {
36-
ms_dbg_a(t, 5, "detected XSS using libinjection.");
37-
if (rule && rule->hasCaptureAction()) {
38-
t->m_collections.m_tx_collection->storeOrUpdateFirst(
39-
"0", std::string(input));
40-
ms_dbg_a(t, 7, "Added DetectXSS match TX.0: " + \
41-
std::string(input));
29+
30+
const injection_result_t xss_result =
31+
libinjection_xss(input.c_str(), input.length());
32+
33+
if (t == nullptr) {
34+
return isMaliciousLibinjectionResult(xss_result);
35+
}
36+
37+
switch (xss_result) {
38+
case LIBINJECTION_RESULT_TRUE:
39+
ms_dbg_a(t, 5, std::string("detected XSS using libinjection."))
40+
if (rule != nullptr && rule->hasCaptureAction()) {
41+
t->m_collections.m_tx_collection->storeOrUpdateFirst("0", input);
42+
ms_dbg_a(t, 7, std::string("Added DetectXSS match TX.0: ") + input)
4243
}
43-
} else {
44-
ms_dbg_a(t, 9, "libinjection was not able to " \
45-
"find any XSS in: " + input);
44+
break;
45+
46+
case LIBINJECTION_RESULT_ERROR:
47+
ms_dbg_a(t, 4,
48+
std::string("libinjection parser error during XSS analysis (")
49+
+ libinjectionResultToString(xss_result)
50+
+ "); treating as match (fail-safe). Input: "
51+
+ input)
52+
if (rule != nullptr && rule->hasCaptureAction()) {
53+
t->m_collections.m_tx_collection->storeOrUpdateFirst("0", input);
54+
ms_dbg_a(t, 7, std::string("Added DetectXSS error input TX.0: ") + input)
4655
}
56+
break;
57+
58+
case LIBINJECTION_RESULT_FALSE:
59+
ms_dbg_a(t, 9,
60+
std::string("libinjection was not able to find any XSS in: ") + input)
61+
break;
4762
}
48-
return is_xss != 0;
49-
}
5063

64+
return isMaliciousLibinjectionResult(xss_result);
65+
}
5166

52-
} // namespace operators
53-
} // namespace modsecurity
67+
} // namespace modsecurity::operators

src/operators/libinjection_utils.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* ModSecurity, http://www.modsecurity.org/
3+
* Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)
4+
*
5+
* You may not use this file except in compliance with
6+
* the License. You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* If any of the files related to licensing are missing or if you have any
11+
* other questions related to licensing please contact Trustwave Holdings, Inc.
12+
* directly using the email address security@modsecurity.org.
13+
*
14+
*/
15+
16+
#ifndef SRC_OPERATORS_LIBINJECTION_UTILS_H_
17+
#define SRC_OPERATORS_LIBINJECTION_UTILS_H_
18+
19+
#include "libinjection/src/libinjection_error.h"
20+
21+
namespace modsecurity::operators {
22+
23+
/*
24+
* libinjection parser errors are handled in fail-safe mode as suspicious
25+
* results, so callers can block on both confirmed detections and parser
26+
* failures.
27+
*/
28+
static inline bool isMaliciousLibinjectionResult(injection_result_t result) {
29+
return result == LIBINJECTION_RESULT_TRUE
30+
|| result == LIBINJECTION_RESULT_ERROR;
31+
}
32+
33+
static inline const char *libinjectionResultToString(injection_result_t result) {
34+
switch (result) {
35+
case LIBINJECTION_RESULT_TRUE:
36+
return "attack-detected";
37+
case LIBINJECTION_RESULT_FALSE:
38+
return "no-attack";
39+
case LIBINJECTION_RESULT_ERROR:
40+
return "parser-error";
41+
}
42+
43+
return "unexpected-result";
44+
}
45+
46+
} // namespace modsecurity::operators
47+
48+
#endif // SRC_OPERATORS_LIBINJECTION_UTILS_H_

0 commit comments

Comments
 (0)