Skip to content

Commit

Permalink
fix: pass usedforsecurity to hashlib.md5 to fix error on FIPS-enabled…
Browse files Browse the repository at this point in the history
… systems (#1366)

See #1365 

Co-authored-by: Tom Christie <tom@tomchristie.com>
  • Loading branch information
adriangb and tomchristie committed Dec 17, 2021
1 parent 58a104e commit 0aef172
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
26 changes: 26 additions & 0 deletions starlette/_compat.py
@@ -0,0 +1,26 @@
import hashlib

# Compat wrapper to always include the `usedforsecurity=...` parameter,
# which is only added from Python 3.9 onwards.
# We use this flag to indicate that we use `md5` hashes only for non-security
# cases (our ETag checksums).
# If we don't indicate that we're using MD5 for non-security related reasons,
# then attempting to use this function will raise an error when used
# environments which enable a strict "FIPs mode".
#
# See issue: https://github.com/encode/starlette/issues/1365
try:

hashlib.md5(b"data", usedforsecurity=True) # type: ignore[call-arg]

def md5_hexdigest(
data: bytes, *, usedforsecurity: bool = True
) -> str: # pragma: no cover
return hashlib.md5( # type: ignore[call-arg]
data, usedforsecurity=usedforsecurity
).hexdigest()

except TypeError: # pragma: no cover

def md5_hexdigest(data: bytes, *, usedforsecurity: bool = True) -> str:
return hashlib.md5(data).hexdigest()
4 changes: 2 additions & 2 deletions starlette/responses.py
@@ -1,4 +1,3 @@
import hashlib
import http.cookies
import json
import os
Expand All @@ -12,6 +11,7 @@

import anyio

from starlette._compat import md5_hexdigest
from starlette.background import BackgroundTask
from starlette.concurrency import iterate_in_threadpool
from starlette.datastructures import URL, MutableHeaders
Expand Down Expand Up @@ -287,7 +287,7 @@ def set_stat_headers(self, stat_result: os.stat_result) -> None:
content_length = str(stat_result.st_size)
last_modified = formatdate(stat_result.st_mtime, usegmt=True)
etag_base = str(stat_result.st_mtime) + "-" + str(stat_result.st_size)
etag = hashlib.md5(etag_base.encode()).hexdigest()
etag = md5_hexdigest(etag_base.encode(), usedforsecurity=False)

self.headers.setdefault("content-length", content_length)
self.headers.setdefault("last-modified", last_modified)
Expand Down

0 comments on commit 0aef172

Please sign in to comment.