Spicy Idea: Regex segments for routing
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 281
Description
## Idea
We have a routing feature called a *complex segment* - description [here](https://review.docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-3.1&branch=pr-en-us-16456#complex-segments).
Example: `/transactions/history/{mm}-{dd}-{yyyy}`
The reason why this documentation section is so long is that complex segments are really just **very** simplified regexes, and don't allow very much control over the matching behavior. In fact they have one of a *few* different kinds of matching behaviors that regexes support.
We get enough issues logged about this (all by-design) that I already know how to respond when I see an issue opened with a complex segment in the code.
> Sorry, it doesn't work that way. No we won't change it. The workaround is to not use routing for that.
---
There's clearly demand for a more sophisticated feature set for this problem space.
---
I'm going to propose that we add a new feature - *regex segments* which is a more powerful version of complex segments. There's precedent for this kind of feature - other routing systems and proxies/servers support regexes.
It could look something like this:
```
transactions/history/{~(\d{2})-(\d{2})-(\d{4})}
```
How this would work is that it would literally be processed by a .NET regular expression. We'd take all named captures and project them to route values.
## Security
Now this obviously raises security flags /cc @blowdart @GrabYourPitchforks
Usually any time anyone says regex, one of those people appear 😆. In the context of routing we usually say "be really careful running regexes on untrusted input because they can be a DOS vector".
However we have a feature *already* that allows you to use regexes with routing, it's just not as useful as what's being proposed here. I could already write this example to use a regex.
```
transactions/history/{date:regex((\d{2})-(\d{2})-(\d{4})}
```
What's missing the current feature set is that you can define a regex that must match, but not a way to extract the values.
---
So two questions:
- What's the set of regex features that we have security/dos concerns about (some info [here](https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices#take-charge-of-backtracking)
- Is it reasonable given the APIs available that routing could detect and ban those usages without having to reimplement the regex system
I don't have the answers to these questions, but this feature feels valuable enough to consider if we can make a secure version of it. Other similar technologies *do* support regexes. We already have regex-related features in routing, so if we can make this to *secure way* to do regexes then that's a big improvement.
@stephentoub as well, who's deeply immersed in regexes 👍
Contributor guide
Assessment
This issue has not been assessed yet.