From 4a02ed566fe60ba7bd10e0f794aea0ccfcb068c5 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Mon, 29 Aug 2016 19:10:01 +0200 Subject: [PATCH] Use get_random_string everywhere (#210) Django's get_random_string tries really hard to either use sysrandom or be otherwise as unpredictable as possible. Thanks to David Gullasch for pointing out both the problem and the solution. --- src/pretix/base/models/invoices.py | 4 ++-- src/pretix/base/models/orders.py | 8 ++++---- src/pretix/base/models/vouchers.py | 5 ++--- src/pretix/plugins/pretixdroid/views.py | 6 ++---- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/pretix/base/models/invoices.py b/src/pretix/base/models/invoices.py index c5f6867d94..620ca527c0 100644 --- a/src/pretix/base/models/invoices.py +++ b/src/pretix/base/models/invoices.py @@ -1,15 +1,15 @@ -import random import string from datetime import date from decimal import Decimal from django.db import DatabaseError, models from django.db.models import Max +from django.utils.crypto import get_random_string from django.utils.functional import cached_property def invoice_filename(instance, filename: str) -> str: - secret = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(16)) + secret = get_random_string(length=16, allowed_chars=string.ascii_letters + string.digits) return 'invoices/{org}/{ev}/{no}-{code}-{secret}.pdf'.format( org=instance.event.organizer.slug, ev=instance.event.slug, no=instance.number, code=instance.order.code, secret=secret diff --git a/src/pretix/base/models/orders.py b/src/pretix/base/models/orders.py index d6ce2ec785..369fee3534 100644 --- a/src/pretix/base/models/orders.py +++ b/src/pretix/base/models/orders.py @@ -1,5 +1,4 @@ import copy -import random import string from datetime import datetime from decimal import Decimal @@ -7,6 +6,7 @@ from typing import List, Union from django.conf import settings from django.db import models +from django.utils.crypto import get_random_string from django.utils.timezone import now from django.utils.translation import ugettext_lazy as _ @@ -17,12 +17,12 @@ from .items import Item, ItemVariation, Question, QuestionOption, Quota def generate_secret(): - return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(16)) + return get_random_string(length=16, allowed_chars=string.ascii_letters + string.digits) def generate_position_secret(): # Exclude o,0,1,i,l to avoid confusion with bad fonts/printers - return ''.join(random.choice('abcdefghjkmnpqrstuvwxyz23456789') for _ in range(settings.ENTROPY['ticket_secret'])) + return get_random_string(length=settings.ENTROPY['ticket_secret'], allowed_chars='abcdefghjkmnpqrstuvwxyz23456789') class Order(LoggedModel): @@ -201,7 +201,7 @@ class Order(LoggedModel): def assign_code(self): charset = list('ABCDEFGHKLMNPQRSTUVWXYZ23456789') while True: - code = "".join([random.choice(charset) for i in range(settings.ENTROPY['order_code'])]) + code = get_random_string(length=settings.ENTROPY['order_code'], allowed_chars=charset) if not Order.objects.filter(event=self.event, code=code).exists(): self.code = code return diff --git a/src/pretix/base/models/vouchers.py b/src/pretix/base/models/vouchers.py index 0920718d56..3a845fcefb 100644 --- a/src/pretix/base/models/vouchers.py +++ b/src/pretix/base/models/vouchers.py @@ -1,8 +1,7 @@ -import random - from django.conf import settings from django.core.exceptions import ValidationError from django.db import models +from django.utils.crypto import get_random_string from django.utils.translation import ugettext_lazy as _ from .base import LoggedModel @@ -14,7 +13,7 @@ from .orders import CartPosition, OrderPosition def generate_code(): charset = list('ABCDEFGHKLMNPQRSTUVWXYZ23456789') while True: - code = "".join([random.choice(charset) for i in range(settings.ENTROPY['voucher_code'])]) + code = get_random_string(length=settings.ENTROPY['voucher_code'], allowed_chars=charset) if not Voucher.objects.filter(code=code).exists(): return code diff --git a/src/pretix/plugins/pretixdroid/views.py b/src/pretix/plugins/pretixdroid/views.py index e62fc34fb7..ae41f36380 100644 --- a/src/pretix/plugins/pretixdroid/views.py +++ b/src/pretix/plugins/pretixdroid/views.py @@ -1,11 +1,11 @@ import json import logging -import random import string from django.http import ( HttpResponseForbidden, HttpResponseNotFound, JsonResponse, ) +from django.utils.crypto import get_random_string from django.views.generic import TemplateView, View from pretix.base.models import Event, Order, OrderPosition @@ -23,9 +23,7 @@ class ConfigView(EventPermissionRequiredMixin, TemplateView): ctx = super().get_context_data() key = self.request.event.settings.get('pretixdroid_key') if not key or 'flush_key' in self.request.GET: - key = ''.join( - random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in - range(32)) + key = get_random_string(length=32, allowed_chars=string.ascii_uppercase + string.ascii_lowercase + string.digits) self.request.event.settings.set('pretixdroid_key', key) ctx['qrdata'] = json.dumps({