Skip to content

Incorrect E-Mail validation #64

Closed

Description

@tempico

Hello guys,

I think something is wrong with e-mail validation. Can we brainstorm this issue?

Python 3.6.1 (default, Apr  4 2017, 09:40:21)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.38)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import validators
>>> validators.email("test@test.com")
True
>>> validators.email("test@test.co1m")
True
>>> validators.email("test@testqqq.co1mq<script>q")
True
>>> validators.email("test@testqqqmq<script>q")
ValidationFailure(func=email, args={'value': 'test@testqqqmq<script>q', 'whitelist': None})

Activity

  1. tempico commented on Sep 11, 2017

    @tempico
    Author

    bypass PoC with flask

    @app.route('/email/', methods=['GET'])
    def page_email():
    	email = request.args["email"]
    	if validators.email(email):
    		return make_response(email, 200)
    

    screen shot 2017-09-11 at 10 06 05

  2. abentley commented on Feb 23, 2018

    @abentley

    So I think what's happening is that the $ is misplaced for domains. The part of the regex that deals with actual domains (rather than IP addresses) is r'(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+' r'(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?$)'

    The problem is that this permits arbitrary trailing characters, such as '>' after a valid domain, because it matches just the domain, not the invalid trailing characters.

    >>> re.match(r'(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+' r'(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?$)', 'example.org>', re.IGNORECASE).group(0)
    'example.org'
    

    Later, the code tests whether there was a match, not whether the input was matched perfectly.

    It appears that the intent was that the second part of the pattern would ensure termination, because it has a $. But the $ is part of a regex group that is not necessary to match 'example.org', so that group is ignored and 'example.org>' matches the regex just fine. Moving the $ after the second part of the pattern does solve this:

    >>> re.match(r'(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+' r'(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)$', 'example.org>', re.IGNORECASE).group(0)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'NoneType' object has no attribute 'group'
    >>> re.match(r'(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+' r'(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)$', 'example.org', re.IGNORECASE).group(0)
    'example.org'
    >>> 
    

    Checking whether match.group(0) == domain_part would also solve this, and might be more robust.

  3. added 3 commits that reference this issue on Mar 3, 2023
    7264636
    6ae7a7f
    0321a40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIssue: Works not as designed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions