In version 6.0.7 of spring-expression there was a method added called checkRegexLength:

https://github.com/spring-projects/spring-framework/blob/69c8f8e9c7387d71ec1d08fb9d0b993f5b889866/spring-expression/src/main/java/org/springframework/expression/spel/ast/OperatorMatches.java#L120-L125

It is adding a 256 char limit check on a length of a regex in a SpEL expression. We actually use longer regexes. Why would you put this limit? Seems quite random.

Please remove this check or at least make that max regex length value configurable.

Comment From: quaff

https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS

Comment From: agolovenko

@quaff I understand the security concerns but then I'd suggest to make this max regex length value configurable: we do have some lengthy regexes that fail with the new version

Comment From: sbrannen

Hi @agolovenko,

Thanks for reporting the issue.

We may consider increasing the max size restriction, but before we do that could you please answer the following questions?

  1. Can you provide an example of one of the regular expressions you are using that are longer than 256 characters?
  2. In what contexts are the affected SpEL expressions used?
  3. For example: configuring bean properties via @Value, in Spring Integration pipelines, provided by external users via the web, etc.
  4. If we were to change the max size, what is the smallest "max size" that would be suitable for your application?

Comment From: agolovenko

Hi @sbrannen ,

  1. Here's the expression that fails at the moment, it's a generated expression and regex length is ~500 chars.
{'140','141','142','143','144','145','146','147','148','149','150','151','152','153','650','651','652','653','654','655','656','657','658','659','660','661','662','663','664','665','666','667','668','669','670','671','672','673','674','675','676','677','678','679','680','681'}.contains( $target.category_id:string ) and !( $target.brand:string matches '(?i).*(ABUS|ARLO|Artemide|AwoX|Axo\sLight|B\-Leuchten|Bankamp|Baulmann|Blaupunkt|David\sTrubridge|Decor\sWalther|Eglo\sconnect|Engel|Escale|EVE|Fatboy|Flos|Fontana\sArte|Foscarini|FRANDSEN|GUBI|Herzblut|Holtkötter|Homematic\sIP|Idual|Ingo\sMauerer|Innr\sLighting|Jieldé|Knapstein|LE\sKLINT|Ledvance\sSmart|LIFX|LiquidBeam|Louis\sPoulsen|Luke\sRoberts|LZF\sLamps|Marchetti|Masiero|Menu|Nanoleaf|NEMO|Ozonos|Philips|Philips\sHue|Q\-Smart\-Home|Rademacher|Schellenberg|Senic|Steinel|Tado|Tecnolumen|Tint|UMAGE|Wiz).*' ) and $target.price gt 17000
  1. We're creating SpELs using new SpelExpressionParser().parseExpression(expr)
  2. I guess 1024 would be acceptable. But here's the thing: what's OK for us might not be OK for some other user. I didn't ask to increase the limit on purpose: whichever value you end up with would be subjective. Hardcoding it is what makes this implementation weak. I suggest giving users a way of configuring this value. Then you could leave 256 as a default one.

Comment From: quaff

I suggest you extract this into a static method, then call method in SpEL like this T(com.acme.Util).validate(#input)

Comment From: sbrannen

Thanks for providing feedback, @agolovenko.

Out of curiosity, what do you mean by "generated"?

Is the expression generated by a custom tool that is internal to your application?

In other words, is the generator a trusted source?

Since you state that you are manually creating the SpelExpressionParser, that implies that you are likely evaluating those expressions against a StandardEvaluationContext. So, if that's the case then you are actually not limited by the recent max size restriction.

When evaluating against a StandardEvaluationContext, you can replace expressions like 'foo' matches 'regex' with 'foo'.matches('regex').

In addition, you can move more complex business logic to a static utility function that is invoked via the T() operator -- as pointed out by @quaff -- or to a method in a bean in the ApplicationContext that is invoked via the bean reference notation @myBean.myMethod(...) (if your expressions are evaluated against an ApplicationContext).

⚠️ Please note that the onus is on you to ensure that you are not evaluating expressions from untrusted sources when using a StandardEvaluationContext.

We do not plan to make any restrictions on SpEL operators configurable. In light of that, please let us know if either of the aforementioned alternatives works for you.

Thanks

Comment From: sbrannen

As mentioned previously, we do not have plans to make the max regex length configurable; however, we are willing to increase it from 256 to 1024 in order to support use cases where a regex may be rather lengthy due to inclusion of several options in an OR clause (such as (a|b|c|d|e|f|...)) or similar scenarios that result in a longer regex without necessarily increasing the complexity of the regex.

In light of that, I am repurposing this issue to address that.