mirror of
https://github.com/openappsec/openappsec.git
synced 2025-09-29 19:24:26 +03:00
sync code
This commit is contained in:
@@ -157,6 +157,9 @@ MatchQuery::load(cereal::JSONInputArchive &archive_in)
|
||||
dbgDebug(D_RULEBASE_CONFIG) << "Failed to compile regex. Error: " << e.what();
|
||||
}
|
||||
}
|
||||
if (isKeyTypeIp()) {
|
||||
sortAndMergeIpRangesValues();
|
||||
}
|
||||
first_value = *(value.begin());
|
||||
}
|
||||
break;
|
||||
@@ -301,7 +304,7 @@ MatchQuery::matchAttributes(
|
||||
bool negate = type == MatchQuery::Conditions::NotEquals || type == MatchQuery::Conditions::NotIn;
|
||||
bool match = false;
|
||||
|
||||
if (isIP()) {
|
||||
if (isKeyTypeIp()) {
|
||||
match = matchAttributesIp(values);
|
||||
} else if (isRegEx()) {
|
||||
match = matchAttributesRegEx(values, matched_override_keywords);
|
||||
@@ -352,10 +355,18 @@ MatchQuery::matchAttributesString(const set<string> &values) const
|
||||
bool
|
||||
MatchQuery::matchAttributesIp(const set<string> &values) const
|
||||
{
|
||||
for (const IPRange &rule_ip_range : ip_addr_value) {
|
||||
for (const string &requested_value : values) {
|
||||
IpAddress ip_addr = IPUtilities::createIpFromString(requested_value);
|
||||
if (IPUtilities::isIpAddrInRange(rule_ip_range, ip_addr)) return true;
|
||||
for (const string &requested_value : values) {
|
||||
int left = 0;
|
||||
int right = ip_addr_value.size() - 1;
|
||||
IpAddress ip_addr = IPUtilities::createIpFromString(requested_value);
|
||||
while (left <= right) {
|
||||
int mid = left + (right - left) / 2;
|
||||
if (IPUtilities::isIpAddrInRange(ip_addr_value[mid], ip_addr)) return true;
|
||||
if (ip_addr_value[mid].start < ip_addr) {
|
||||
left = mid + 1;
|
||||
} else {
|
||||
right = mid - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -367,8 +378,23 @@ MatchQuery::isRegEx() const
|
||||
return key != "protectionName";
|
||||
}
|
||||
|
||||
bool
|
||||
MatchQuery::isIP() const
|
||||
void
|
||||
MatchQuery::sortAndMergeIpRangesValues()
|
||||
{
|
||||
return key == "sourceIP" || key == "destinationIP";
|
||||
if (ip_addr_value.empty()) return;
|
||||
|
||||
sort(ip_addr_value.begin(), ip_addr_value.end());
|
||||
size_t mergedIndex = 0;
|
||||
for (size_t i = 1; i < ip_addr_value.size(); ++i) {
|
||||
if (ip_addr_value[i].start <= ip_addr_value[mergedIndex].end) {
|
||||
if (ip_addr_value[mergedIndex].end <= ip_addr_value[i].end) {
|
||||
ip_addr_value[mergedIndex].end = ip_addr_value[i].end;
|
||||
}
|
||||
} else {
|
||||
++mergedIndex;
|
||||
ip_addr_value[mergedIndex] = ip_addr_value[i];
|
||||
}
|
||||
}
|
||||
|
||||
ip_addr_value.resize(mergedIndex + 1);
|
||||
}
|
||||
|
@@ -22,7 +22,10 @@ bool
|
||||
operator<(const IpAddress &this_ip_addr, const IpAddress &other_ip_addr)
|
||||
{
|
||||
if (this_ip_addr.ip_type < other_ip_addr.ip_type) return true;
|
||||
if (this_ip_addr.ip_type == IP_VERSION_4) return this_ip_addr.addr4_t.s_addr < other_ip_addr.addr4_t.s_addr;
|
||||
if (this_ip_addr.ip_type > other_ip_addr.ip_type) return false;
|
||||
if (this_ip_addr.ip_type == IP_VERSION_4) {
|
||||
return ntohl(this_ip_addr.addr4_t.s_addr) < ntohl(other_ip_addr.addr4_t.s_addr);
|
||||
}
|
||||
return memcmp(&this_ip_addr.addr6_t, &other_ip_addr.addr6_t, sizeof(struct in6_addr)) < 0;
|
||||
}
|
||||
|
||||
@@ -33,6 +36,19 @@ operator==(const IpAddress &this_ip_addr, const IpAddress &other_ip_addr)
|
||||
if (this_ip_addr.ip_type == IP_VERSION_4) return this_ip_addr.addr4_t.s_addr == other_ip_addr.addr4_t.s_addr;
|
||||
return memcmp(&this_ip_addr.addr6_t, &other_ip_addr.addr6_t, sizeof(struct in6_addr)) == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
operator<=(const IpAddress &this_ip_addr, const IpAddress &other_ip_addr)
|
||||
{
|
||||
if (this_ip_addr < other_ip_addr || this_ip_addr == other_ip_addr) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
operator<(const IPRange &range1, const IPRange &range2)
|
||||
{
|
||||
return range1.start < range2.start || (range1.start == range2.start && range1.end < range2.end);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
Maybe<pair<string, int>>
|
||||
|
@@ -5,6 +5,8 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_KEYWORD);
|
||||
|
||||
static const string whitespaces = " \t";
|
||||
|
||||
static string
|
||||
@@ -14,6 +16,13 @@ getSubStrNoPadding(const string &str, uint start, uint end)
|
||||
auto r_end = str.find_last_not_of(whitespaces, end-1);
|
||||
|
||||
if (r_end==string::npos || r_start==string::npos || r_start>r_end) {
|
||||
dbgWarning(D_KEYWORD)
|
||||
<< "Can't extract substring from '"
|
||||
<< str
|
||||
<< "', padded start: "
|
||||
<< r_start
|
||||
<< ", padded end: "
|
||||
<< r_end;
|
||||
throw KeywordError("Found an empty section in the '"+ str + "'");
|
||||
}
|
||||
|
||||
@@ -45,13 +54,24 @@ split(const string &str, const string &delim, uint start = 0)
|
||||
}
|
||||
default:
|
||||
if (!in_string && delim.find(str[index])!=string::npos) {
|
||||
res.push_back(getSubStrNoPadding(str, part_start, index));
|
||||
if (part_start == index) {
|
||||
dbgTrace(D_KEYWORD) << "Encountered consecutive delimiter in: " << str;
|
||||
} else {
|
||||
res.push_back(getSubStrNoPadding(str, part_start, index));
|
||||
}
|
||||
part_start = index+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (escape||in_string) throw KeywordError("Split has ended in the middle of the parsing");
|
||||
if (escape||in_string) {
|
||||
dbgWarning(D_KEYWORD)
|
||||
<< "Failed to split "
|
||||
<< str
|
||||
<< ". Split ended in "
|
||||
<< (escape ? "escape" : "middle of string");
|
||||
throw KeywordError("Split has ended in the middle of the parsing");
|
||||
}
|
||||
|
||||
if (str.find_first_not_of(whitespaces, part_start)!=string::npos) {
|
||||
res.push_back(getSubStrNoPadding(str, part_start, str.size()));
|
||||
|
@@ -55,6 +55,13 @@ TEST_F(KeywordsRuleTest, data_basic_test) {
|
||||
EXPECT_FALSE(ruleRun("data: \"75\", part HTTP_RESPONSE_BODY;"));
|
||||
}
|
||||
|
||||
TEST_F(KeywordsRuleTest, consecutive_delimiter_test) {
|
||||
appendBuffer("HTTP_RESPONSE_BODY", "123456789");
|
||||
|
||||
EXPECT_TRUE(ruleRun("data: \"234\" , part HTTP_RESPONSE_BODY;"));
|
||||
EXPECT_FALSE(ruleRun("data: \"75\", part HTTP_RESPONSE_BODY;"));
|
||||
}
|
||||
|
||||
TEST_F(KeywordsRuleTest, data_relative_test) {
|
||||
appendBuffer("HTTP_RESPONSE_BODY", "1234567890");
|
||||
|
||||
|
Reference in New Issue
Block a user