# Code Smell 185 -  Evil Regular Expressions

> TL;DR: Try to minimize Regular Expression's recursive rules.

# Problems

- Security Issues

- Readability

- Premature Optimization

# Solutions

1. Cover the cases with tests to see if they halt

2. Use algorithms instead of regular expressions

3. Add timeout handlers

# Context

This is known as [ReDos](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS) attack, a subtype of a [Denial of Service](https://en.wikipedia.org/wiki/Denial-of-service_attack) attack.

ReDoS attacks can be divided into two types:

A string with an evil pattern is passed to an application. Then this string is used as a regex, which leads to ReDoS.

A string with a vector attack format is passed to an application. Then this string is evaluated by a vulnerable regex, which leads to ReDoS.

# Sample Code

## Wrong

[Gist Url]: # (https://gist.github.com/mcsee/a4e74fb3e18cde7ff7f15636e05ced89)
```go
package main

import (
    "regexp"
    "fmt"
)

func main() {
    var re = regexp.MustCompile(`^(([a-z])+.)+[A-Z]([a-z])+$`)
    var str = `aaaaaaaaaaaaaaaaaaaaaaaa!`
    
    for i, match := range re.FindAllString(str, -1) {
        fmt.Println(match, "found at index", i)
    }
}
```

![Regex 101](https://cdn.hashnode.com/res/hashnode/image/upload/v1670516111424/j4yOedFH2.PNG)

## Right

[Gist Url]: # (https://gist.github.com/mcsee/4ba06d514fb663f0ee628139d463f8c7)
```go
package main

import (
    "fmt"
    "strings"
)

func main() {
    var str = `aaaaaaaaaaaaaaaaaaaaaaaa!`
    
    words := strings.Fields(str)
    
    for i, word := range words {
        if len(word) >= 2 && word[0] >= 'a' && word[0] <= 'z' && word[len(word)-1] >= 'A' 
          && word[len(word)-1] <= 'Z' {
            fmt.Println(word, "found at index", i)
        }
    }
}
```

# Detection

[X] Semi-Automatic 

Many languages avoid this kind of regular expression.

We can also scan the code for this vulnerability.

# Tags

- Security

# Conclusion

Regular Expressions are tricky and hard to debug. 

We should avoid them as much as possible.

# Relations

%[https://maximilianocontieri.com/code-smell-41-regular-expression-abusers]

# More Info

[Catastrophic backtracking: how can a regular expression cause a ReDoS vulnerability?](https://dev.to/unicorn_developer/catastrophic-backtracking-how-can-a-regular-expression-cause-a-redos-vulnerability-aia)

[https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS)

[Runaway Regular Expressions: Catastrophic Backtracking](https://www.regular-expressions.info/catastrophic.html)

# Disclaimer

Code Smells are just my [opinion](https://maximilianocontieri.com/i-wrote-more-than-90-articles-on-2021-here-is-what-i-learned).

# Credits

Photo by [engin akyurt](https://unsplash.com/@enginakyurt) on [Unsplash](https://unsplash.com/s/photos/regular-expression)  
  
* * *

> Some people, when confronted with a problem, think “I know, I’ll use regular expressions.” Now they have two problems.

_Jamie Zawinski_
 
%[https://maximilianocontieri.com/software-engineering-great-quotes]

* * *

This article is part of the CodeSmell Series.

%[https://maximilianocontieri.com/how-to-find-the-stinky-parts-of-your-code]
