Skip to content

Commit 6f971b6

Browse files
author
Sayan Shaw
committed
Merge branch 'main' of https://github.com/microsoft/onnxruntime-extensions into sayanshaw/decode-image-icm
2 parents 01400bb + 64f04ee commit 6f971b6

3 files changed

Lines changed: 51 additions & 2 deletions

File tree

operators/azure/cloud_base_kernel.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "cloud_base_kernel.hpp"
55

6+
#include <algorithm>
67
#include <sstream>
78

89
#include "narrow.h"
@@ -78,6 +79,11 @@ std::string CloudBaseKernel::GetAuthToken(const ortc::Variadic& inputs) const {
7879
}
7980

8081
std::string auth_token{static_cast<const char*>(inputs[0]->DataRaw())};
82+
83+
// Sanitize CRLF to prevent HTTP header injection (CWE-113).
84+
auth_token.erase(std::remove_if(auth_token.begin(), auth_token.end(), [](char c) { return c == '\r' || c == '\n'; }),
85+
auth_token.end());
86+
8187
return auth_token;
8288
}
8389

operators/azure/curl_invoker.hpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License.
33

44
#pragma once
5+
#include <cstring>
56
#include <memory>
67

78
#include "curl/curl.h"
@@ -19,7 +20,17 @@ class CurlHandler {
1920
~CurlHandler() = default;
2021

2122
void AddHeader(const char* data) {
22-
headers_.reset(curl_slist_append(headers_.release(), data));
23+
// Defense-in-depth: reject headers containing CRLF to prevent HTTP header injection.
24+
if (std::strchr(data, '\r') || std::strchr(data, '\n')) {
25+
ORTX_CXX_API_THROW("HTTP header line must not contain CR or LF characters", ORT_INVALID_ARGUMENT);
26+
}
27+
curl_slist* current = headers_.release();
28+
curl_slist* updated = curl_slist_append(current, data);
29+
if (updated == nullptr) {
30+
headers_.reset(current);
31+
ORTX_CXX_API_THROW("Failed to append HTTP header (out of memory)", ORT_RUNTIME_EXCEPTION);
32+
}
33+
headers_.reset(updated);
2334
}
2435

2536
template <typename... Args>

test/static_test/test_utils.cc

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4+
#include <algorithm>
5+
46
#include "gtest/gtest.h"
57
#ifdef ENABLE_RE2_REGEX
68
#include "re2/re2.h"
@@ -67,4 +69,34 @@ TEST(utils, utf8) {
6769
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
6870
EXPECT_EQ(lowered[i], lower);
6971
}
70-
}
72+
}
73+
74+
// Regression test for CRLF injection sanitization in auth_token (CWE-113).
75+
// Verifies the erase-remove pattern used in CloudBaseKernel::GetAuthToken().
76+
TEST(utils, crlf_sanitization) {
77+
auto sanitize = [](std::string token) {
78+
token.erase(std::remove_if(token.begin(), token.end(), [](char c) { return c == '\r' || c == '\n'; }), token.end());
79+
return token;
80+
};
81+
82+
// Clean token passes through unchanged
83+
EXPECT_EQ(sanitize("Bearer abc123"), "Bearer abc123");
84+
85+
// CR and LF are stripped
86+
EXPECT_EQ(sanitize("fake\r\nX-Injected: pwned"), "fakeX-Injected: pwned");
87+
88+
// Lone CR stripped
89+
EXPECT_EQ(sanitize("token\rinjected"), "tokeninjected");
90+
91+
// Lone LF stripped
92+
EXPECT_EQ(sanitize("token\ninjected"), "tokeninjected");
93+
94+
// Multiple CRLF sequences stripped
95+
EXPECT_EQ(sanitize("a\r\nb\r\nc"), "abc");
96+
97+
// Empty string is fine
98+
EXPECT_EQ(sanitize(""), "");
99+
100+
// Token that is only CRLF
101+
EXPECT_EQ(sanitize("\r\n\r\n"), "");
102+
}

0 commit comments

Comments
 (0)