dotnet / dotnet/aspnetcore

Spicy Idea: Regex segments for routing

Open
#19,772 10 comments 2 reactions 0 assignees View on GitHub
affected-medium area-mvc enhancement feature-routing severity-major
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.