3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ReDoSがPythonでも可能か調べてみた

Posted at

ReDoSとは

なにこれこわい

検証

ipythonでやってみる

import re
from datetime import datetime


n = 5
while n < 12:
    s = "username@host{}.".format(".abcde" * n)
    start = datetime.now()
    print(re.match(r"\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z", s, flags=re.IGNORECASE))
    print('{}: {}'.format(len(s), (datetime.now() - start).total_seconds()))
    n += 1

実行結果

None
44: 0.085964
None
50: 0.41799
None
56: 2.106463
None
62: 10.319476
None
68: 57.825968
None
74: 269.451777
None
80: 1400.865988

まじで指数関数的に増えてる。こえー

Django の EmailValidator でもやってみる

from datetime import datetime
from django.core.exceptions import ValidationError
from django.core.validators import EmailValidator


validator = EmailValidator()
n = 5
while n < 12:
    s = "username@host{}.".format(".abcde" * n)
    start = datetime.now()
    try:
        validator(s)
        print(True)
    except ValidationError:
        print(False)

    print('{}: {}'.format(len(s), (datetime.now() - start).total_seconds()))
    n += 1

実行結果

False
44: 0.015296
False
50: 0.000116
False
56: 9.3e-05
False
62: 0.000127
False
68: 0.00016
False
74: 0.000122
False
80: 0.000125

お、大丈夫そう。

ついでに自作のValidatorもやってみる

import re
from datetime import datetime
from django.core.exceptions import ValidationError
from django.core.validators import EmailValidator


class JapaneseEmailValidator(EmailValidator):
    user_regex = re.compile(
        r"(^[-.!#$%&'*+/=?^_`{}|~0-9A-Z]+$"  # dot-atom
        r"|^\"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*\"$)",  # quoted-string
        re.IGNORECASE
    )


validator = JapaneseEmailValidator()
n = 5
while n < 12:
    s = "username@host{}.".format(".abcde" * n)
    start = datetime.now()
    try:
        validator(s)
        print(True)
    except ValidationError:
        print(False)

    print('{}: {}'.format(len(s), (datetime.now() - start).total_seconds()))
    n += 1

実行結果

False
44: 0.00613
False
50: 9.8e-05
False
56: 8.6e-05
False
62: 9.9e-05
False
68: 0.000127
False
74: 0.000145
False
80: 0.000105

まとめ

セキュアプログラミングとか気をつけないとね
よくわからないときは、Django公式のvalidatorとかにしておけばいいんじゃね
80文字で1400sec(23min20sec)とかないわー

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?