Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
58fc3da
Update libinjection to v4.0.0
Mar 29, 2026
e1a527e
Make detect_sqli and detect_xss compatible with libinjection v4
Mar 29, 2026
d2cef41
Update regression tests for libinjection v4 compatibility
Mar 29, 2026
9e66822
syntax adjustment
Mar 30, 2026
633f2eb
Add capture/non-capture regression coverage for detectSQLi/XSS
Easton97-Jens Mar 30, 2026
b264dbf
Merge pull request #27 from Easton97-Jens/codex/add-regression-tests-…
Easton97-Jens Mar 30, 2026
7cd1d67
Fix Windows test include path and case-insensitive override matching
Easton97-Jens Mar 31, 2026
2aed15b
Merge pull request #31 from Easton97-Jens/codex/add-regression-tests-…
Easton97-Jens Mar 31, 2026
0af7e13
Update libinjection_adapter.cc
Easton97-Jens Apr 1, 2026
d8c7395
Merge branch 'owasp-modsecurity:v3/master' into v3/master-libinjectio…
Easton97-Jens Apr 1, 2026
d6648d1
Add libinjection_error.h to Makefile.am
Easton97-Jens Apr 1, 2026
19ea6d0
Isolate transaction state in multithreaded unit tests
Easton97-Jens Apr 1, 2026
e152a09
Merge pull request #32 from Easton97-Jens/codex/review-multithreaded-…
Easton97-Jens Apr 1, 2026
719d172
Merge branch 'v3/master' into v3/master-libinjection-v4.0-final
Easton97-Jens Apr 1, 2026
468f681
Update libinjection_adapter.cc
Easton97-Jens Apr 1, 2026
d19f58b
Update libinjection_adapter.h
Easton97-Jens Apr 1, 2026
91fbf35
Hide testing override functions from symbol table
Easton97-Jens Apr 3, 2026
e10e9e0
Log input in hex format for SQLi detection
Easton97-Jens Apr 3, 2026
29a461b
Add logging for input in XSS detection
Easton97-Jens Apr 3, 2026
7c104e4
Update multithreaded unit test implementation
Easton97-Jens Apr 3, 2026
0cf4f3c
Update libinjection_adapter.h
Easton97-Jens Apr 3, 2026
3e98c81
Guard log-only detect operator variables under NO_LOGS
Easton97-Jens Apr 3, 2026
e500702
Merge pull request #42 from Easton97-Jens/codex/fix-cppcheck-unreadva…
Easton97-Jens Apr 3, 2026
383da50
Harden libinjection result handling to fail-safe defaults
Easton97-Jens Apr 3, 2026
e6ce0f8
Merge pull request #44 from Easton97-Jens/codex/review-libinjection-r…
Easton97-Jens Apr 3, 2026
098ae12
operators: use shared safeLogValue in DetectXSS/DetectSQLi
Easton97-Jens Apr 4, 2026
9493ea3
Merge pull request #45 from Easton97-Jens/codex/review-xss-and-sqli-p…
Easton97-Jens Apr 4, 2026
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
2 changes: 1 addition & 1 deletion others/libinjection
Submodule libinjection updated 155 files
79 changes: 52 additions & 27 deletions src/operators/detect_sqli.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,45 +17,70 @@

#include <string>
#include <list>
#include <array>

#include "src/operators/operator.h"
#include "src/operators/libinjection_utils.h"
#include "libinjection/src/libinjection.h"
#include "libinjection/src/libinjection_error.h"

namespace modsecurity {
namespace operators {

namespace modsecurity::operators {

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

issqli = libinjection_sqli(input.c_str(), input.length(), fingerprint);
std::array<char, 8> fingerprint{};

const injection_result_t sqli_result =
libinjection_sqli(input.c_str(), input.length(), fingerprint.data());

if (!t) {
goto tisempty;
if (t == nullptr) {
return isMaliciousLibinjectionResult(sqli_result);
}

if (issqli) {
t->m_matched.push_back(fingerprint);
ms_dbg_a(t, 4, "detected SQLi using libinjection with " \
"fingerprint '" + std::string(fingerprint) + "' at: '" +
input + "'");
if (rule && rule->hasCaptureAction()) {
t->m_collections.m_tx_collection->storeOrUpdateFirst(
"0", std::string(fingerprint));
ms_dbg_a(t, 7, "Added DetectSQLi match TX.0: " + \
std::string(fingerprint));
}
} else {
ms_dbg_a(t, 9, "detected SQLi: not able to find an " \
"inject on '" + input + "'");
switch (sqli_result) {
case LIBINJECTION_RESULT_TRUE:
t->m_matched.emplace_back(fingerprint.data());

ms_dbg_a(t, 4,
std::string("detected SQLi using libinjection with fingerprint '")
+ fingerprint.data() + "' at: '" + input + "'")

if (rule != nullptr && rule->hasCaptureAction()) {
t->m_collections.m_tx_collection->storeOrUpdateFirst(
"0", std::string(fingerprint.data()));

ms_dbg_a(t, 7,
std::string("Added DetectSQLi match TX.0: ")
+ fingerprint.data())
}
break;

case LIBINJECTION_RESULT_ERROR:
ms_dbg_a(t, 4,
std::string("libinjection parser error during SQLi analysis (")
+ libinjectionResultToString(sqli_result)
+ "); treating as match (fail-safe). Input: '"
+ input + "'")

if (rule != nullptr && rule->hasCaptureAction()) {
t->m_collections.m_tx_collection->storeOrUpdateFirst(
"0", input);

ms_dbg_a(t, 7,
std::string("Added DetectSQLi error input TX.0: ")
+ input)
}
break;

case LIBINJECTION_RESULT_FALSE:
ms_dbg_a(t, 9,
std::string("libinjection was not able to find any SQLi in: ")
+ input)
break;
}

tisempty:
return issqli != 0;
return isMaliciousLibinjectionResult(sqli_result);
}


} // namespace operators
} // namespace modsecurity
} // namespace modsecurity::operators
60 changes: 37 additions & 23 deletions src/operators/detect_xss.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,50 @@
#include <string>

#include "src/operators/operator.h"
#include "src/operators/libinjection_utils.h"
#include "libinjection/src/libinjection.h"
#include "libinjection/src/libinjection_error.h"


namespace modsecurity {
namespace operators {

namespace modsecurity::operators {

bool DetectXSS::evaluate(Transaction *t, RuleWithActions *rule,
const std::string& input, RuleMessage &ruleMessage) {
int is_xss;

is_xss = libinjection_xss(input.c_str(), input.length());

if (t) {
if (is_xss) {
ms_dbg_a(t, 5, "detected XSS using libinjection.");
if (rule && rule->hasCaptureAction()) {
t->m_collections.m_tx_collection->storeOrUpdateFirst(
"0", std::string(input));
ms_dbg_a(t, 7, "Added DetectXSS match TX.0: " + \
std::string(input));

const injection_result_t xss_result =
libinjection_xss(input.c_str(), input.length());

if (t == nullptr) {
return isMaliciousLibinjectionResult(xss_result);
}

switch (xss_result) {
case LIBINJECTION_RESULT_TRUE:
ms_dbg_a(t, 5, std::string("detected XSS using libinjection."))
if (rule != nullptr && rule->hasCaptureAction()) {
t->m_collections.m_tx_collection->storeOrUpdateFirst("0", input);
ms_dbg_a(t, 7, std::string("Added DetectXSS match TX.0: ") + input)
}
} else {
ms_dbg_a(t, 9, "libinjection was not able to " \
"find any XSS in: " + input);
break;

case LIBINJECTION_RESULT_ERROR:
ms_dbg_a(t, 4,
std::string("libinjection parser error during XSS analysis (")
+ libinjectionResultToString(xss_result)
+ "); treating as match (fail-safe). Input: "
+ input)
if (rule != nullptr && rule->hasCaptureAction()) {
t->m_collections.m_tx_collection->storeOrUpdateFirst("0", input);
ms_dbg_a(t, 7, std::string("Added DetectXSS error input TX.0: ") + input)
}
break;

case LIBINJECTION_RESULT_FALSE:
ms_dbg_a(t, 9,
std::string("libinjection was not able to find any XSS in: ") + input)
break;
}
return is_xss != 0;
}

return isMaliciousLibinjectionResult(xss_result);
}

} // namespace operators
} // namespace modsecurity
} // namespace modsecurity::operators
48 changes: 48 additions & 0 deletions src/operators/libinjection_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* ModSecurity, http://www.modsecurity.org/
* Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)
*
* You may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* If any of the files related to licensing are missing or if you have any
* other questions related to licensing please contact Trustwave Holdings, Inc.
* directly using the email address security@modsecurity.org.
*
*/

#ifndef SRC_OPERATORS_LIBINJECTION_UTILS_H_
#define SRC_OPERATORS_LIBINJECTION_UTILS_H_

#include "libinjection/src/libinjection_error.h"

namespace modsecurity::operators {

/*
* libinjection parser errors are handled in fail-safe mode as suspicious
* results, so callers can block on both confirmed detections and parser
* failures.
*/
static inline bool isMaliciousLibinjectionResult(injection_result_t result) {
return result == LIBINJECTION_RESULT_TRUE
|| result == LIBINJECTION_RESULT_ERROR;
}

static inline const char *libinjectionResultToString(injection_result_t result) {
switch (result) {
case LIBINJECTION_RESULT_TRUE:
return "attack-detected";
case LIBINJECTION_RESULT_FALSE:
return "no-attack";
case LIBINJECTION_RESULT_ERROR:
return "parser-error";
}

return "unexpected-result";
}

} // namespace modsecurity::operators

#endif // SRC_OPERATORS_LIBINJECTION_UTILS_H_
Loading
Loading