Skip to content

Commit fd1c681

Browse files
sethmlarsonmcepl
authored andcommitted
[CVE-2026-0864] Normalize all line endings (CR, CRLF, and LF) in configparser
This normalizes all line endings (CR, CRLF, and LF) to multiline continuation format (LF+TAB), preventing configuration injection vulnerabilities across mixed platform environments. Fixes: bsc#1269066 (CVE-2026-0864) Fixes: gh#python#143927 From-PR: gh#python/cpython!143929 Patch: CVE-2026-0864-normalize-LFTAB-configparser.patch
1 parent adfbd38 commit fd1c681

3 files changed

Lines changed: 16 additions & 1 deletion

File tree

‎Lib/configparser.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,9 @@ def _write_section(self, fp, section_name, section_items, delimiter):
925925
value = self._interpolation.before_write(self, section_name, key,
926926
value)
927927
if value is not None or not self._allow_no_value:
928-
value = delimiter + str(value).replace('\n', '\n\t')
928+
# Convert all possible line-endings into '\n\t'
929+
value = (delimiter + str(value).replace('\r\n', '\n')
930+
.replace('\r', '\n').replace('\n', '\n\t'))
929931
else:
930932
value = ""
931933
fp.write("{}{}\n".format(key, value))

‎Lib/test/test_configparser.py‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,17 @@ def test_default_case_sensitivity(self):
520520
cf.get(self.default_section, "Foo"), "Bar",
521521
"could not locate option, expecting case-insensitive defaults")
522522

523+
def test_crlf_normalization(self):
524+
cf = self.newconfig({"key1": "a\nb","key2": "a\rb", "key3": "a\r\nb", "key4": "a\r\nb"})
525+
buf = io.StringIO()
526+
cf.write(buf)
527+
cf_str = buf.getvalue()
528+
self.assertNotIn("\r", cf_str)
529+
self.assertNotIn("\r\n", cf_str)
530+
self.assertEqual(cf_str.count("\n"), 10)
531+
self.assertEqual(cf_str.count("\n\t"), 4)
532+
self.assertTrue(cf_str.endswith("\n\n"))
533+
523534
def test_parse_errors(self):
524535
cf = self.newconfig()
525536
self.parse_error(cf, configparser.ParsingError,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Normalize all line endings (CR, CRLF, and LF) to LF+TAB when writing
2+
multi-line configparser values.

0 commit comments

Comments
 (0)