Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to use user input for Python's regular expressions?

I would like to let my users use regular expressions for some features. I'm curious what the implications are of passing user input to re.compile(). I assume there is no way for a user to give me a string that could let them execute arbitrary code. The dangers I have thought of are:

  1. The user could pass input that raises an exception.
    • The user could pass input that causes the regex engine to take a long time, or to use a lot of memory.

The solution to 1. is easy: catch exceptions. I'm not sure if there is a good solution to 2. Perhaps just limiting the length of the regex would work.

Is there anything else I need to worry about?

like image 270
Skeletron Avatar asked Jan 04 '10 07:01

Skeletron


People also ask

How do you take Regular Expressions into input in Python?

import re string_to_look_in = 'This is a string with a " " tab character. ' print("String to look into:", string_to_look_in) print("String to look into:", repr(string_to_look_in), "\n") user_input = input("Input regex:") # check console, it is expecting your input print("\nUser typed: '{}'.

Are Regular Expressions useful in Python?

Regex is very useful in searching through large texts, emails, and documents. Regex is also called “programming language for the string matching”. Before diving into the regular expressions and their implementation in python, it is important to know their applications in the real world.

Does Python replace use regex?

To replace a string in Python, the regex sub() method is used. It is a built-in Python method in re module that returns replaced string. Don't forget to import the re module. This method searches the pattern in the string and then replace it with a new given expression.

Which library is used for regular expression in Python?

Python has a built-in package called re , which can be used to work with Regular Expressions.


2 Answers

I have worked on a program that allows users to enter their own regex and you are right - they can (and do) enter regex that can take a long time to finish - sometimes longer than than the lifetime of the universe. What is worse, while processing a regex Python holds the GIL, so it will not only hang the thread that is running the regex, but the entire program.

Limiting the length of the regex will not work, since the problem is backtracking. For example, matching the regex r"(\S+)+x" on a string of length N that does not contain an "x" will backtrack 2**N times. On my system this takes about a second to match against "a"*21 and the time doubles for each additional character, so a string of 100 characters would take approximately 19167393131891000 years to complete (this is an estimate, I have not timed it).

For more information read the O'Reilly book "Mastering Regular Expressions" - this has a couple of chapters on performance.

edit To get round this we wrote a regex analysing function that tried to catch and reject some of the more obvious degenerate cases, but it is impossible to get all of them.

Another thing we looked at was patching the re module to raise an exception if it backtracks too many times. This is possible, but requires changing the Python C source and recompiling, so is not portable. We also submitted a patch to release the GIL when matching against python strings, but I don't think it was accepted into the core (python only holds the GIL because regex can be run against mutable buffers).

like image 129
Dave Kirby Avatar answered Sep 21 '22 05:09

Dave Kirby


It's much simpler for casual users to give them a subset language. The shell's globbing rules in fnmatch, for example. The SQL LIKE condition rules are another example.

Translate the user's language into a proper regex for execution at runtime.

like image 37
S.Lott Avatar answered Sep 19 '22 05:09

S.Lott