Skip to content

Secure Source of Randomness #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions manage/_internal/IPython/extensions/tests/test_autoreload.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import tempfile
import textwrap
import shutil
import random
import time
from io import StringIO
from dataclasses import dataclass
Expand All @@ -31,6 +30,7 @@
from IPython.extensions.autoreload import AutoreloadMagics
from IPython.core.events import EventManager, pre_run_cell
from IPython.testing.decorators import skipif_not_numpy
import secrets

if platform.python_implementation() == "PyPy":
pytest.skip(
Expand Down Expand Up @@ -94,7 +94,7 @@ def tearDown(self):
self.shell = None

def get_module(self):
module_name = "tmpmod_" + "".join(random.sample(self.filename_chars, 20))
module_name = "tmpmod_" + "".join(secrets.SystemRandom().sample(self.filename_chars, 20))
if module_name in sys.modules:
del sys.modules[module_name]
file_name = os.path.join(self.test_dir, module_name + ".py")
Expand Down
5 changes: 2 additions & 3 deletions manage/_internal/astroid/brain/brain_random.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

from __future__ import annotations

import random

from astroid import helpers
from astroid.context import InferenceContext
from astroid.exceptions import UseInferenceDefault
Expand All @@ -21,6 +19,7 @@
Set,
Tuple,
)
import secrets

ACCEPTED_ITERABLES_FOR_SAMPLE = (List, Set, Tuple)

Expand Down Expand Up @@ -63,7 +62,7 @@ def infer_random_sample(node, context: InferenceContext | None = None):
raise UseInferenceDefault

try:
elts = random.sample(inferred_sequence.elts, inferred_length.value)
elts = secrets.SystemRandom().sample(inferred_sequence.elts, inferred_length.value)
except ValueError as exc:
raise UseInferenceDefault from exc

Expand Down
4 changes: 2 additions & 2 deletions manage/_internal/django/core/cache/backends/filebased.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import glob
import os
import pickle
import random
import tempfile
import time
import zlib
Expand All @@ -11,6 +10,7 @@
from django.core.files import locks
from django.core.files.move import file_move_safe
from django.utils.crypto import md5
import secrets


class FileBasedCache(BaseCache):
Expand Down Expand Up @@ -108,7 +108,7 @@ def _cull(self):
if self._cull_frequency == 0:
return self.clear() # Clear the cache when CULL_FREQUENCY = 0
# Delete a random selection of entries
filelist = random.sample(filelist, int(num_entries / self._cull_frequency))
filelist = secrets.SystemRandom().sample(filelist, int(num_entries / self._cull_frequency))
for fname in filelist:
self._delete(fname)

Expand Down
4 changes: 2 additions & 2 deletions manage/_internal/django/core/cache/backends/redis.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"""Redis cache backend."""

import pickle
import random
import re

from django.core.cache.backends.base import DEFAULT_TIMEOUT, BaseCache
from django.utils.functional import cached_property
from django.utils.module_loading import import_string
import secrets


class RedisSerializer:
Expand Down Expand Up @@ -65,7 +65,7 @@ def _get_connection_pool_index(self, write):
# otherwise read from the first server.
if write or len(self._servers) == 1:
return 0
return random.randint(1, len(self._servers) - 1)
return secrets.SystemRandom().randint(1, len(self._servers) - 1)

def _get_connection_pool(self, write):
index = self._get_connection_pool_index(write)
Expand Down
4 changes: 2 additions & 2 deletions manage/_internal/django/template/defaultfilters.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""Default variable filters."""
import random as random_module
import re
import types
from decimal import ROUND_HALF_UP, Context, Decimal, InvalidOperation
Expand All @@ -25,6 +24,7 @@

from .base import VARIABLE_ATTRIBUTE_SEPARATOR
from .library import Library
import secrets

register = Library()

Expand Down Expand Up @@ -620,7 +620,7 @@ def length_is(value, arg):
@register.filter(is_safe=True)
def random(value):
"""Return a random item from the list."""
return random_module.choice(value)
return secrets.choice(value)


@register.filter("slice", is_safe=True)
Expand Down
4 changes: 2 additions & 2 deletions manage/_internal/django/test/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import multiprocessing
import os
import pickle
import random
import sys
import textwrap
import unittest
Expand All @@ -29,6 +28,7 @@
from django.utils.crypto import new_hash
from django.utils.datastructures import OrderedSet
from django.utils.deprecation import RemovedInDjango50Warning
import secrets

try:
import ipdb as pdb
Expand Down Expand Up @@ -585,7 +585,7 @@ def _hash_text(cls, text):
def __init__(self, seed=None):
if seed is None:
# Limit seeds to 10 digits for simpler output.
seed = random.randint(0, 10**10 - 1)
seed = secrets.SystemRandom().randint(0, 10**10 - 1)
seed_source = "generated"
else:
seed_source = "given"
Expand Down
13 changes: 6 additions & 7 deletions manage/_internal/django/utils/lorem_ipsum.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
"""
Utility functions for generating "lorem ipsum" Latin text.
"""

import random
import secrets

COMMON_P = (
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod "
Expand Down Expand Up @@ -232,12 +231,12 @@ def sentence():
# Determine the number of comma-separated sections and number of words in
# each section for this sentence.
sections = [
" ".join(random.sample(WORDS, random.randint(3, 12)))
for i in range(random.randint(1, 5))
" ".join(secrets.SystemRandom().sample(WORDS, secrets.SystemRandom().randint(3, 12)))
for i in range(secrets.SystemRandom().randint(1, 5))
]
s = ", ".join(sections)
# Convert to sentence case and add end punctuation.
return "%s%s%s" % (s[0].upper(), s[1:], random.choice("?."))
return "%s%s%s" % (s[0].upper(), s[1:], secrets.choice("?."))


def paragraph():
Expand All @@ -246,7 +245,7 @@ def paragraph():

The paragraph consists of between 1 and 4 sentences, inclusive.
"""
return " ".join(sentence() for i in range(random.randint(1, 4)))
return " ".join(sentence() for i in range(secrets.SystemRandom().randint(1, 4)))


def paragraphs(count, common=True):
Expand Down Expand Up @@ -280,7 +279,7 @@ def words(count, common=True):
while count > 0:
c = min(count, len(WORDS))
count -= c
word_list += random.sample(WORDS, c)
word_list += secrets.SystemRandom().sample(WORDS, c)
else:
word_list = word_list[:count]
return " ".join(word_list)
11 changes: 5 additions & 6 deletions manage/_internal/visualization/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import json
import plotly.express as px
import json
import random
from django.contrib import messages
import os
from django.core.files import File
Expand All @@ -22,7 +21,6 @@
from django.contrib.sessions.models import Session
from shapely.geometry import shape, Point
import matplotlib.pyplot as plt
import random
import matplotlib.patches as mpatches
import branca
import colorsys
Expand All @@ -44,6 +42,7 @@
import inspect
from django.contrib.auth.decorators import login_required
from app.json_serializable import json_to_geodataframe, json_to_dataframe, dataframe_to_json
import secrets

def preview_dataframe(df, limit=10):
return df.head(limit)
Expand Down Expand Up @@ -300,9 +299,9 @@ def generate_dark_random_colors(num_colors):
colors = []
while len(colors) < num_colors:
# Generate random HSL color with fixed saturation and lightness (to get darker colors)
h = random.randint(0, 360)
h = secrets.SystemRandom().randint(0, 360)
s = 80 # Fixed saturation
l = random.randint(30, 50) # Restricted lightness for darker colors
l = secrets.SystemRandom().randint(30, 50) # Restricted lightness for darker colors

# Convert HSL to RGB
r, g, b = colorsys.hls_to_rgb(h / 360, l / 100, s / 100)
Expand All @@ -314,7 +313,7 @@ def generate_dark_random_colors(num_colors):
colors.append(color)

# Randomly shuffle the colors to get unique and random colors
random.shuffle(colors)
secrets.SystemRandom().shuffle(colors)
return colors

def format_popup_content(lat, lon, district, hover_data, size, dt_bin):
Expand Down Expand Up @@ -873,4 +872,4 @@ def save_forecasts_dataframe_to_db(request, df, name, filtered_by_val=[], period

return HttpResponse("CSV file uploaded to the database successfully.")



11 changes: 5 additions & 6 deletions visualization/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import json
import plotly.express as px
import json
import random
from django.contrib import messages
import os
from django.core.files import File
Expand All @@ -22,7 +21,6 @@
from django.contrib.sessions.models import Session
from shapely.geometry import shape, Point
import matplotlib.pyplot as plt
import random
import matplotlib.patches as mpatches
import branca
import colorsys
Expand All @@ -44,6 +42,7 @@
import inspect
from django.contrib.auth.decorators import login_required
from app.json_serializable import json_to_geodataframe, json_to_dataframe, dataframe_to_json
import secrets

def preview_dataframe(df, limit=10):
return df.head(limit)
Expand Down Expand Up @@ -300,9 +299,9 @@ def generate_dark_random_colors(num_colors):
colors = []
while len(colors) < num_colors:
# Generate random HSL color with fixed saturation and lightness (to get darker colors)
h = random.randint(0, 360)
h = secrets.SystemRandom().randint(0, 360)
s = 80 # Fixed saturation
l = random.randint(30, 50) # Restricted lightness for darker colors
l = secrets.SystemRandom().randint(30, 50) # Restricted lightness for darker colors

# Convert HSL to RGB
r, g, b = colorsys.hls_to_rgb(h / 360, l / 100, s / 100)
Expand All @@ -314,7 +313,7 @@ def generate_dark_random_colors(num_colors):
colors.append(color)

# Randomly shuffle the colors to get unique and random colors
random.shuffle(colors)
secrets.SystemRandom().shuffle(colors)
return colors

def format_popup_content(lat, lon, district, hover_data, size, dt_bin):
Expand Down Expand Up @@ -873,4 +872,4 @@ def save_forecasts_dataframe_to_db(request, df, name, filtered_by_val=[], period

return HttpResponse("CSV file uploaded to the database successfully.")