<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Xoifail</title>
    <description>The latest articles on Forem by Xoifail (@xoifail).</description>
    <link>https://forem.com/xoifail</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3715846%2F537ad292-3ccb-49a8-9d4b-5a09fb9462c1.gif</url>
      <title>Forem: Xoifail</title>
      <link>https://forem.com/xoifail</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/xoifail"/>
    <language>en</language>
    <item>
      <title>Your Java Regex Can Be Weaponized (And How To Stop It)</title>
      <dc:creator>Xoifail</dc:creator>
      <pubDate>Sat, 17 Jan 2026 03:38:59 +0000</pubDate>
      <link>https://forem.com/xoifail/your-java-regex-can-be-weaponized-and-how-to-stop-it-ke4</link>
      <guid>https://forem.com/xoifail/your-java-regex-can-be-weaponized-and-how-to-stop-it-ke4</guid>
      <description>&lt;p&gt;Most developers don't realize their input validation is a denial of service vulnerability waiting to happen. Let me show you what I mean.&lt;/p&gt;

&lt;p&gt;Take this innocent looking regex that validates email addresses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"^([a-zA-Z0-9]+)+@[a-zA-Z0-9]+\\.[a-zA-Z]{2,}$"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;Pattern&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;matcher&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks fine right? Now feed it this input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your CPU just pegged at 100% and stayed there. This is called ReDoS (Regular Expression Denial of Service) and it happens because Java's regex engine uses backtracking. Certain patterns cause exponential time complexity when matching fails in specific ways.&lt;/p&gt;

&lt;p&gt;Attackers know about this. They send crafted inputs to your validation endpoints and watch your servers melt.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Backtracking Problem
&lt;/h2&gt;

&lt;p&gt;Java's &lt;code&gt;java.util.regex&lt;/code&gt; uses an NFA (Nondeterministic Finite Automaton) with backtracking. When a match fails partway through, the engine backtracks and tries alternative paths. With nested quantifiers like &lt;code&gt;([a-zA-Z0-9]+)+&lt;/code&gt; the number of paths explodes exponentially.&lt;/p&gt;

&lt;p&gt;The input &lt;code&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!&lt;/code&gt; has 33 characters. The regex engine will try somewhere around 2^33 combinations before giving up. That's 8 billion operations for one validation call.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;p&gt;There's a different kind of regex engine called RE2 that Google built. It uses a DFA (Deterministic Finite Automaton) which guarantees linear time matching. No matter how evil the pattern or input, it finishes in O(n) time where n is the input length.&lt;/p&gt;

&lt;p&gt;I've been working on a Java validation library called &lt;a href="https://github.com/XoifaiI/Rules" rel="noopener noreferrer"&gt;Rules&lt;/a&gt; that bundles a patched fork of RE2J (the Java port of RE2). The fork includes fixes for some vulnerabilities found in the original implementation.&lt;/p&gt;

&lt;p&gt;Using it looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Rule&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StringRules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;ValidationResult&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userInput&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isValid&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// safe to use&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same pattern, but now it can't be weaponized. The underlying RE2J engine simply won't allow catastrophic backtracking because it doesn't backtrack at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Else Can Go Wrong
&lt;/h2&gt;

&lt;p&gt;While we're on the topic of input validation attacks, regex isn't the only vector:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HashDoS&lt;/strong&gt; : Attackers can make keys that all hash to the same bucket, turning your O(1) HashMap lookups into O(n). The library includes &lt;code&gt;SecureHashMap&lt;/code&gt; which uses SipHash-2-4 with random keys to prevent this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Timing Attacks&lt;/strong&gt; : Comparing secrets with &lt;code&gt;equals()&lt;/code&gt; leaks information through timing differences. Character by character comparison bails early on mismatch so attackers can guess passwords one character at a time. The library has constant time comparison functions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack Overflow via Recursion&lt;/strong&gt; : Self referential data structures can blow your stack during validation. The library tracks depth and detects cycles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Example
&lt;/h2&gt;

&lt;p&gt;Here's validating a user registration with multiple rules composed together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Rule&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Rules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;all&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;StringRules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;notBlank&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
    &lt;span class="nc"&gt;StringRules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lengthBetween&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;StringRules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"^[a-zA-Z0-9_]+$"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;Rule&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Rules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;all&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;StringRules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;minLength&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;StringRules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[A-Z]"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;StringRules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[a-z]"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;StringRules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[0-9]"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user_dev"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;isValid&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SecurePass123"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;isValid&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Getting It
&lt;/h2&gt;

&lt;p&gt;Maven:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.github.xoifaii&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;rules&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or clone from &lt;a href="https://github.com/XoifaiI/Rules" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; if you want to poke around. Full API docs are in the wiki.&lt;/p&gt;

&lt;p&gt;Zero dependencies. The RE2J fork is bundled in.&lt;/p&gt;




&lt;p&gt;If you've got a public facing Java app doing input validation with regex, it's worth checking whether your patterns are vulnerable. Tools like &lt;a href="https://makenowjust-labs.github.io/recheck/" rel="noopener noreferrer"&gt;recheck&lt;/a&gt; can analyze patterns for ReDoS, very useful.&lt;/p&gt;

&lt;p&gt;Or just use an engine that makes the problem impossible in the first place.&lt;/p&gt;

</description>
      <category>java</category>
      <category>cybersecurity</category>
      <category>security</category>
    </item>
    <item>
      <title>Your Java Regex Can Be Weaponized (And How To Stop It)</title>
      <dc:creator>Xoifail</dc:creator>
      <pubDate>Sat, 17 Jan 2026 03:38:59 +0000</pubDate>
      <link>https://forem.com/xoifail/your-java-regex-can-be-weaponized-and-how-to-stop-it-cp9</link>
      <guid>https://forem.com/xoifail/your-java-regex-can-be-weaponized-and-how-to-stop-it-cp9</guid>
      <description>&lt;p&gt;Most developers don't realize their input validation is a denial of service vulnerability waiting to happen. Let me show you what I mean.&lt;/p&gt;

&lt;p&gt;Take this innocent looking regex that validates email addresses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"^([a-zA-Z0-9]+)+@[a-zA-Z0-9]+\\.[a-zA-Z]{2,}$"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;Pattern&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;matcher&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks fine right? Now feed it this input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your CPU just pegged at 100% and stayed there. This is called ReDoS (Regular Expression Denial of Service) and it happens because Java's regex engine uses backtracking. Certain patterns cause exponential time complexity when matching fails in specific ways.&lt;/p&gt;

&lt;p&gt;Attackers know about this. They send crafted inputs to your validation endpoints and watch your servers melt.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Backtracking Problem
&lt;/h2&gt;

&lt;p&gt;Java's &lt;code&gt;java.util.regex&lt;/code&gt; uses an NFA (Nondeterministic Finite Automaton) with backtracking. When a match fails partway through, the engine backtracks and tries alternative paths. With nested quantifiers like &lt;code&gt;([a-zA-Z0-9]+)+&lt;/code&gt; the number of paths explodes exponentially.&lt;/p&gt;

&lt;p&gt;The input &lt;code&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!&lt;/code&gt; has 33 characters. The regex engine will try somewhere around 2^33 combinations before giving up. That's 8 billion operations for one validation call.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;p&gt;There's a different kind of regex engine called RE2 that Google built. It uses a DFA (Deterministic Finite Automaton) which guarantees linear time matching. No matter how evil the pattern or input, it finishes in O(n) time where n is the input length.&lt;/p&gt;

&lt;p&gt;I've been working on a Java validation library called &lt;a href="https://github.com/XoifaiI/Rules" rel="noopener noreferrer"&gt;Rules&lt;/a&gt; that bundles a patched fork of RE2J (the Java port of RE2). The fork includes fixes for some vulnerabilities found in the original implementation.&lt;/p&gt;

&lt;p&gt;Using it looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Rule&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StringRules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;ValidationResult&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userInput&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isValid&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// safe to use&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same pattern, but now it can't be weaponized. The underlying RE2J engine simply won't allow catastrophic backtracking because it doesn't backtrack at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Else Can Go Wrong
&lt;/h2&gt;

&lt;p&gt;While we're on the topic of input validation attacks, regex isn't the only vector:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HashDoS&lt;/strong&gt; : Attackers can make keys that all hash to the same bucket, turning your O(1) HashMap lookups into O(n). The library includes &lt;code&gt;SecureHashMap&lt;/code&gt; which uses SipHash-2-4 with random keys to prevent this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Timing Attacks&lt;/strong&gt; : Comparing secrets with &lt;code&gt;equals()&lt;/code&gt; leaks information through timing differences. Character by character comparison bails early on mismatch so attackers can guess passwords one character at a time. The library has constant time comparison functions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack Overflow via Recursion&lt;/strong&gt; : Self referential data structures can blow your stack during validation. The library tracks depth and detects cycles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Example
&lt;/h2&gt;

&lt;p&gt;Here's validating a user registration with multiple rules composed together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Rule&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Rules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;all&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;StringRules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;notBlank&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
    &lt;span class="nc"&gt;StringRules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lengthBetween&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;StringRules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"^[a-zA-Z0-9_]+$"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;Rule&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Rules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;all&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;StringRules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;minLength&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;StringRules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[A-Z]"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;StringRules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[a-z]"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;StringRules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[0-9]"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user_dev"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;isValid&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SecurePass123"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;isValid&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Getting It
&lt;/h2&gt;

&lt;p&gt;Maven:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.github.xoifaii&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;rules&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or clone from &lt;a href="https://github.com/XoifaiI/Rules" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; if you want to poke around. Full API docs are in the wiki.&lt;/p&gt;

&lt;p&gt;Zero dependencies. The RE2J fork is bundled in.&lt;/p&gt;




&lt;p&gt;If you've got a public facing Java app doing input validation with regex, it's worth checking whether your patterns are vulnerable. Tools like &lt;a href="https://makenowjust-labs.github.io/recheck/" rel="noopener noreferrer"&gt;recheck&lt;/a&gt; can analyze patterns for ReDoS, very useful.&lt;/p&gt;

&lt;p&gt;Or just use an engine that makes the problem impossible in the first place.&lt;/p&gt;

</description>
      <category>java</category>
      <category>cybersecurity</category>
      <category>security</category>
    </item>
  </channel>
</rss>
