ArticleslgStudy

computer science

ReDoS

ReDoS is a computer science topic covered in the lgStudy science library. This page brings together a partial reference excerpt, illustrations, worked examples, real-world applications and a short study plan, so you can understand ReDoS rather than just read about it. In short: A regular expression denial of service (ReDoS) is an algorithmic complexity attack that produces a denial-of-service by providing a regular expression (regex) and/or an input that takes a long time to evaluate. The attack exploits the fact that many regular expression implementations have super-linear worst-case complexity; on certain regex-input pairs, the time taken can grow polynomially or exponentially in relati…

Key takeaways

  • ReDoS belongs to computer science; place it in that map before memorising details.
  • Learn the definition first, then one example that makes the definition concrete.
  • Connect ReDoS to a quantity you can measure, compute or draw — that is where exam questions come from.
  • Reproduce the core statement of ReDoS from memory before moving on to harder problems.

Reference excerpt

A regular expression denial of service (ReDoS) is an algorithmic complexity attack that produces a denial-of-service by providing a regular expression (regex) and/or an input that takes a long time to evaluate. The attack exploits the fact that many regular expression implementations have super-linear worst-case complexity; on certain regex-input pairs, the time taken can grow polynomially or exponentially in relation to the input size. An attacker can thus cause a program to spend substantial time by providing a specially crafted regular expression and/or input. The program will then slow down or become unresponsive.

Description Regular expression ("regex") matching can be done by building a finite-state automaton. Regex can be easily converted to nondeterministic automata (NFAs), in which, for each state and input symbol, there may be several possible next states. After building the automaton, several possibilities exist:

the engine may convert it to a deterministic finite-state automaton (DFA) and run the input through the result; the engine may try all the possible paths one by one until a match is found or until all the paths are tried and fail ("backtracking"). the engine may consider all possible paths through the nondeterministic automaton in parallel; the engine may convert the nondeterministic automaton to a DFA lazily (i.e., on the fly, during the match). Of the above algorithms, the first two are problematic. The first is problematic because a deterministic automaton could have up to 2 m {\displaystyle 2^{m}} states where m {\displaystyle m} is the number of states in the nondeterministic automaton; thus, the conversion from NFA to DFA may take exponential time. The second is problematic because a nondeterministic automaton could have an exponential number of paths of length n {\displaystyle n} , so that walking through an input of length n {\displaystyle n} will also take exponential time. The last two algorithms, however, do not exhibit pathological behavior. Note that for non-pathological regular expressions, the problematic algorithms are usually fast, and in practice, one can expect them to "compile" a regex in O ( m ) {\displaystyle O(m)} time and match it in O ( n ) {\displaystyle O(n)} time; instead, simulation of an NFA and lazy computation of the DFA have O ( m ⋅ 2 n ) {\displaystyle O(m\cdot 2^{n})} worst-case complexity. Regex denial of service occurs when these expectations are applied to a regex provided by the user, and malicious regular expressions provided by the user trigger the worst-case complexity of the regex matcher. While regex algorithms can be written in an efficient way, most regex engines in existence extend the regex languages with additional constructs that cannot always be solved efficiently. Such extended patterns essentially force the implementation of regex in most programming languages to use backtracking.

Examples

Exponential backtracking The most severe type of problem happens with backtracking regular expression matches, where some patterns have a runtime that is exponential in the length of the input string. For strings of n {\displaystyle n} characters, the runtime is O ( 2 n ) {\displaystyle O(2^{n})} . This happens when a regular expression has three properties:

the regular expression applies repetition (+, *) to a subexpression; the subexpression can match the same input in multiple ways, or the subexpression can match an input string which is a prefix of a longer possible match; and after the repeated subexpression, there is an expression that matches something which the subexpression does not match. The second condition is best explained with two examples:

in (a|a)+$, repetition is applied to the subexpression a|a, which can match a in two ways on each side of the alternation. in (a+)*$, repetition is applied to the subexpression a+, which can match a or aa, etc. In both of these examples we used $ to match the end of the string, satisfying the third condition, but it is also possible to use another character for this. For example (a|aa)*c has the same problematic structure. All three of the above regular expressions will exhibit exponential runtime when applied to strings of the form a . . . a x {\displaystyle a...ax} . For example, trying to match them against aaaaaaaaaaaaaaaaaaaaaaaax on a backtracking expression engine, it will take a significantly long time to complete, and the runtime will approximately double for each extra a before the x. It is also possible to have backtracking which is polynomial time O ( n x ) {\displaystyle O(n^{x})} , instead of exponential. This can also cause problems for long enough inputs, though less attention has been paid to this problem as malicious input must be much longer to have a significant effect. An example of such a pattern is "a*b?a*c", when the input is an arbitrarily long sequence of "a"s.

Vulnerable regexes in online repositories So-called "evil" or vulnerable regexes have been found in online regular expression repositories. Note that it is enough to find a vulnerable subexpression in order to attack the full regex:

RegExLib, id=1757 (email validation) – see red part^([a-zA-Z0-9])(([\-.]|[_]+)?([a-zA-Z0-9]+))*(@){1}[a-z0-9]+[.]{1}(([a-z]{2,3})|([a-z]{2,3}[.]{1}[a-z]{2,3}))$ OWASP Validation Regex Repository, Java Classname – see red part^(([a-z])+.)+[A-Z]([a-z])+$ These two examples are also susceptible to the input aaaaaaaaaaaaaaaaaaaaaaaa!.

… excerpt ends here. Continue reading the full article.

Worked examples

Example 1 — a first encounter with ReDoS

Start with the simplest possible case. Write down what ReDoS claims or describes in one sentence, then invent the smallest concrete situation in which that sentence is true. In computer science, the smallest case is usually a single object, a single equation or a single measurement. Check that every symbol or term in your sentence has a meaning in that case.

Example 2 — changing one variable

Take the situation from Example 1 and change exactly one quantity: double it, halve it, or set it to zero. Predict what should happen to ReDoS before you calculate. Comparing your prediction with the result is the fastest way to find out whether you understand the idea or only the words.

Example 3 — an exam-style question

Typical questions about ReDoS ask you to (a) state it precisely, (b) apply it to given data, and (c) explain a limitation. Practise writing all three answers in under five minutes; the third part is what separates a full-mark answer from an average one.

Applications of ReDoS

In research
ReDoS appears in computer science research whenever the underlying quantities have to be modelled precisely. Papers usually cite it as a starting assumption and then explore where it breaks down.
In technology and industry
Engineering practice reuses ReDoS in design rules, simulations and safety margins. Knowing the idea lets you read a specification sheet and understand why the numbers look the way they do.
In the classroom
ReDoS is common in secondary-school and first-year university syllabi. It links to neighbouring topics Algorithmic complexity attacks, Denial-of-service attacks, Pattern matching, so understanding it makes those chapters shorter.
In everyday life
Look for ReDoS outside the textbook — in sport, cooking, traffic, electronics or the sky above you. An example you found yourself is remembered far longer than one you were given.

Affiliate

Preply — study more efficiently by working with a personal tutor. 50% off.

How to study ReDoS in 20 minutes

  1. Read the reference excerpt below once, without taking notes.
  2. Close the page and write down what ReDoS means in your own words.
  3. Compare your version with the excerpt and mark what you missed.
  4. Work through the three examples above with pen and paper.
  5. Explain ReDoS out loud to somebody else — or to Teacher Smith in the lgStudy chat.

Frequently asked questions

What is ReDoS in simple terms?

A regular expression denial of service (ReDoS) is an algorithmic complexity attack that produces a denial-of-service by providing a regular expression (regex) and/or an input that takes a long time to evaluate. The attack exploits the fact that many regular expression implementations have super-lin…

Why does ReDoS matter?

Because it connects several computer science ideas at once: it gives you a definition you can apply, a quantity you can calculate, and a way to check whether a result is plausible.

How should I study ReDoS?

Read the excerpt, restate it from memory, then work through the examples and applications listed on this page. The five-step study plan above takes about twenty minutes.

What does this page cover?

It gives you a compact reference excerpt plus original lgStudy explanations, examples, applications and study material on ReDoS.

Tags

  • Algorithmic complexity attacks
  • Denial-of-service attacks
  • Pattern matching
  • Regular expressions

Keep exploring