A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/django/django/commit/b3e4494d759202a3b6bf247fd34455bf13be5b80 below:

[3.2.x] Fixed CVE-2022-36359 -- Escaped filename in Content-Dispositi… · django/django@b3e4494 · GitHub

File tree Expand file treeCollapse file tree 3 files changed

+45

-2

lines changed

Filter options

Expand file treeCollapse file tree 3 files changed

+45

-2

lines changed Original file line number Diff line number Diff line change

@@ -485,7 +485,9 @@ def set_headers(self, filelike):

485 485

disposition = 'attachment' if self.as_attachment else 'inline'

486 486

try:

487 487

filename.encode('ascii')

488 -

file_expr = 'filename="{}"'.format(filename)

488 +

file_expr = 'filename="{}"'.format(

489 +

filename.replace('\\', '\\\\').replace('"', r'\"')

490 +

)

489 491

except UnicodeEncodeError:

490 492

file_expr = "filename*=utf-8''{}".format(quote(filename))

491 493

self.headers['Content-Disposition'] = '{}; {}'.format(disposition, file_expr)

Original file line number Diff line number Diff line change

@@ -6,4 +6,10 @@ Django 3.2.15 release notes

6 6 7 7

Django 3.2.15 fixes a security issue with severity "high" in 3.2.14.

8 8 9 -

...

9 +

CVE-2022-36359: Potential reflected file download vulnerability in ``FileResponse``

10 +

===================================================================================

11 + 12 +

An application may have been vulnerable to a reflected file download (RFD)

13 +

attack that sets the Content-Disposition header of a

14 +

:class:`~django.http.FileResponse` when the ``filename`` was derived from

15 +

user-supplied input. The ``filename`` is now escaped to avoid this possibility.

Original file line number Diff line number Diff line change

@@ -89,3 +89,38 @@ def test_unicode_attachment(self):

89 89

response.headers['Content-Disposition'],

90 90

"attachment; filename*=utf-8''%E7%A5%9D%E6%82%A8%E5%B9%B3%E5%AE%89.odt"

91 91

)

92 + 93 +

def test_content_disposition_escaping(self):

94 +

# fmt: off

95 +

tests = [

96 +

(

97 +

'multi-part-one";\" dummy".txt',

98 +

r"multi-part-one\";\" dummy\".txt"

99 +

),

100 +

]

101 +

# fmt: on

102 +

# Non-escape sequence backslashes are path segments on Windows, and are

103 +

# eliminated by an os.path.basename() check in FileResponse.

104 +

if sys.platform != "win32":

105 +

# fmt: off

106 +

tests += [

107 +

(

108 +

'multi-part-one\\";\" dummy".txt',

109 +

r"multi-part-one\\\";\" dummy\".txt"

110 +

),

111 +

(

112 +

'multi-part-one\\";\\\" dummy".txt',

113 +

r"multi-part-one\\\";\\\" dummy\".txt"

114 +

)

115 +

]

116 +

# fmt: on

117 +

for filename, escaped in tests:

118 +

with self.subTest(filename=filename, escaped=escaped):

119 +

response = FileResponse(

120 +

io.BytesIO(b"binary content"), filename=filename, as_attachment=True

121 +

)

122 +

response.close()

123 +

self.assertEqual(

124 +

response.headers["Content-Disposition"],

125 +

f'attachment; filename="{escaped}"',

126 +

)

You can’t perform that action at this time.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4