Skip to content

Commit c012b33

Browse files
authored
use secrets.token_urlsafe for salt (#3167)
2 parents e397792 + a852be7 commit c012b33

3 files changed

Lines changed: 8 additions & 12 deletions

File tree

CHANGES.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ Version 3.2.0
8181
- Use SHA3-256 instead of SHA-1 for generating ETags and the debugger pin.
8282
SHA-1 is not available FIPS 140. This may invalidate some caches since the
8383
ETag will be different. :pr:`3164`
84+
- ``generate_password_hash`` uses ``secrets.token_urlsafe`` to generate salt.
85+
The private ``gen_salt`` method is removed. :pr:`3167`
8486

8587

8688
Version 3.1.8

src/werkzeug/debug/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import os
77
import pkgutil
88
import re
9+
import secrets
910
import subprocess
1011
import sys
1112
import time
@@ -24,7 +25,6 @@
2425
from ..exceptions import SecurityError
2526
from ..http import parse_cookie
2627
from ..sansio.utils import host_is_trusted
27-
from ..security import gen_salt
2828
from ..utils import send_file
2929
from ..wrappers.request import Request
3030
from ..wrappers.response import Response
@@ -284,7 +284,7 @@ def __init__(
284284
self.console_path = console_path
285285
self.console_init_func = console_init_func
286286
self.show_hidden_frames = show_hidden_frames
287-
self.secret = gen_salt(20)
287+
self.secret = secrets.token_urlsafe(20)
288288
self._failed_pin_auth = Value("B")
289289

290290
self.pin_logging = pin_logging

src/werkzeug/security.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import posixpath
77
import secrets
88

9-
SALT_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
109
DEFAULT_PBKDF2_ITERATIONS = 1_000_000
1110

1211
_os_alt_seps: list[str] = list(
@@ -25,14 +24,6 @@
2524
}
2625

2726

28-
def gen_salt(length: int) -> str:
29-
"""Generate a random string of SALT_CHARS with specified ``length``."""
30-
if length <= 0:
31-
raise ValueError("Salt length must be at least 1.")
32-
33-
return "".join(secrets.choice(SALT_CHARS) for _ in range(length))
34-
35-
3627
def _hash_internal(method: str, salt: str, password: str) -> tuple[str, str]:
3728
method, *args = method.split(":")
3829
salt_bytes = salt.encode()
@@ -115,7 +106,10 @@ def generate_password_hash(
115106
.. versionchanged:: 2.3
116107
The default iterations for pbkdf2 was increased to 600,000.
117108
"""
118-
salt = gen_salt(salt_length)
109+
if salt_length <= 0:
110+
raise ValueError("Salt length must be at least 1.")
111+
112+
salt = secrets.token_urlsafe(salt_length)
119113
h, actual_method = _hash_internal(method, salt, password)
120114
return f"{actual_method}${salt}${h}"
121115

0 commit comments

Comments
 (0)