Skip to content

Commit 022dfb7

Browse files
committed
fix: preserve value in t:base64Decode when input is not valid base64
Add Base64::tryDecode() that checks mbedtls return value before replacing the variable. On invalid input, the original value is now preserved and transform returns false.
1 parent e5d00df commit 022dfb7

3 files changed

Lines changed: 29 additions & 2 deletions

File tree

src/actions/transformations/base64_decode.cc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,14 @@ namespace modsecurity::actions::transformations {
2323

2424
bool Base64Decode::transform(std::string &value, const Transaction *trans) const {
2525
if (value.empty()) return false;
26-
value = Utils::Base64::decode(value);
26+
27+
std::string decoded;
28+
if (!Utils::Base64::tryDecode(value, decoded)) {
29+
return false;
30+
}
31+
32+
value = std::move(decoded);
2733
return true;
2834
}
2935

30-
3136
} // namespace modsecurity::actions::transformations

src/utils/base64.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,27 @@ std::string Base64::decode(const std::string& data) {
6363
return base64Helper(data.c_str(), strlen(data.c_str()), mbedtls_base64_decode);
6464
}
6565

66+
bool Base64::tryDecode(const std::string& data, std::string &out) {
67+
size_t out_len = 0;
68+
const auto *src = reinterpret_cast<const unsigned char *>(data.c_str());
69+
const size_t slen = strlen(data.c_str());
70+
71+
const int ret = mbedtls_base64_decode(nullptr, 0, &out_len, src, slen);
72+
73+
if (ret != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) {
74+
return false;
75+
}
76+
77+
out.resize(out_len);
78+
if (mbedtls_base64_decode(
79+
reinterpret_cast<unsigned char *>(out.data()),
80+
out.size(), &out_len, src, slen) != 0) {
81+
return false;
82+
}
83+
84+
out.resize(out_len);
85+
return true;
86+
}
6687

6788
std::string Base64::decode_forgiven(const std::string& data) {
6889
return base64Helper(data.c_str(), data.size(), decode_forgiven_engine);

src/utils/base64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class Base64 {
3030

3131
static std::string decode(const std::string& data, bool forgiven);
3232
static std::string decode(const std::string& data);
33+
static bool tryDecode(const std::string& data, std::string &out);
3334
static std::string decode_forgiven(const std::string& data);
3435

3536
static void decode_forgiven_engine(unsigned char *plain_text,

0 commit comments

Comments
 (0)