Skip to content

Commit 07e3eb2

Browse files
arorashivam96claude
andcommitted
fix: reject CR/LF/NUL in operation_context to prevent header injection
Validate operation_context at ODataClient init time — raise ValueError if the string contains \r, \n, or \x00. Prevents invalid HTTP headers and header injection via the User-Agent comment. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d4fbb18 commit 07e3eb2

2 files changed

Lines changed: 12 additions & 1 deletion

File tree

src/PowerPlatform/Dataverse/data/_odata.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,12 @@ def __init__(
206206
session=session,
207207
logger=self._http_logger,
208208
)
209-
self._operation_context = self.config.operation_context
209+
ctx = self.config.operation_context
210+
if ctx and any(c in ctx for c in "\r\n\x00"):
211+
raise ValueError(
212+
"operation_context must not contain CR, LF, or NUL characters."
213+
)
214+
self._operation_context = ctx
210215
self._logical_to_entityset_cache: dict[str, str] = {}
211216
# Cache: normalized table_schema_name (lowercase) -> primary id attribute (e.g. accountid)
212217
self._logical_primaryid_cache: dict[str, str] = {}

tests/unit/test_operation_context.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,9 @@ def test_empty_string_context_no_parentheses(self):
9797
odata = _ODataClient(self.dummy_auth, self.base_url, config=config)
9898
headers = odata._headers()
9999
self.assertNotIn("(", headers["User-Agent"])
100+
101+
def test_control_chars_rejected(self):
102+
for bad in ["has\rnewline", "has\nnewline", "has\x00null"]:
103+
config = DataverseConfig(operation_context=bad)
104+
with self.assertRaises(ValueError):
105+
_ODataClient(self.dummy_auth, self.base_url, config=config)

0 commit comments

Comments
 (0)