This is an automated email from the ASF dual-hosted git repository.

mibo pushed a commit to branch regex-fix
in repository https://gitbox.apache.org/repos/asf/olingo-odata4.git

commit 6c2e7db47b4faa0966fae026343e542abd1b6463
Author: mibo <[email protected]>
AuthorDate: Thu Mar 13 23:00:12 2025 +0100

    [OLINGO-1640] ENUM regex fix
---
 .../apache/olingo/client/core/uri/URIUtils.java    |  2 +-
 .../client/core/uri/ExampleUriGeneratorTest.java   | 95 ++++++++++++++++++++++
 2 files changed, 96 insertions(+), 1 deletion(-)

diff --git 
a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIUtils.java 
b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIUtils.java
index cbc461865..c3d719821 100644
--- 
a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIUtils.java
+++ 
b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIUtils.java
@@ -72,7 +72,7 @@ public final class URIUtils {
    * Logger.
    */
 
-  private static final Pattern ENUM_VALUE = Pattern.compile("(.+\\.)?.+'.+'");
+  private static final Pattern ENUM_VALUE = 
Pattern.compile("([^']+\\.[^']+)?'[^']+'");
   private static final String URI_OPTIONS = "/$";
 
   private URIUtils() {
diff --git 
a/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/ExampleUriGeneratorTest.java
 
b/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/ExampleUriGeneratorTest.java
new file mode 100644
index 000000000..f845a8d09
--- /dev/null
+++ 
b/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/ExampleUriGeneratorTest.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.client.core.uri;
+
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.core.ODataClientFactory;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ExampleUriGeneratorTest {
+    /**
+     * This test demonstrates the normal behavior of encapsulating a string 
with single quotes
+     * <p>
+     * The test succeeds
+     */
+    @Test
+    public void testHappyPath() {
+        String uri = ExampleUriGenerator.filterPersonByName("henk");
+
+        // Expected: https://example.com/Person?$filter=(name eq 'henk')
+        
assertEquals("https://example.com/Person?%24filter=%28name%20eq%20'henk'%29", 
uri);
+    }
+
+
+    /**
+     * This test demonstrates that some String literals are not encapsulated 
(quoted) correctly. This happens because
+     * {@link org.apache.olingo.client.core.uri.URIUtils#quoteString(String, 
boolean)} incorrectly determines the string
+     * to be an enum using a poorly designed regex, causing it to not 
encapsulate the string with single quotes. This
+     * can be abused to circumvent filters as illustrated in the example below.
+     * <p>
+     * The test <b>fails</b>
+     */
+    @Test
+    public void testODataInjection() {
+        String uri = ExampleUriGenerator.filterPersonByName("' or name ne '");
+
+        // Expected: https://example.com/Person?$filter=(name eq ''' or name 
ne ''')
+        
assertEquals("https://example.com/Person?%24filter=%28name%20eq%20'''%20or%20name%20ne%20'''%29",
 uri);
+
+        // Actual:  
https://example.com/Person?%24filter=%28name%20eq%20''%20or%20name%20ne%20''%29
+        //          https://example.com/Person?$filter=(name eq '' or name ne 
'')
+    }
+
+    static final class ExampleUriGenerator {
+        private static final ODataClient client = 
ODataClientFactory.getClient();
+
+        private ExampleUriGenerator() {
+        }
+
+        static String filterPersonByName(String name) {
+            // OLingo does not escape string literals so we do it ourselves
+            String escapedName = escape(name);
+
+            String filter = client.getFilterFactory() //
+                .eq("name", escapedName) //
+                .build();
+
+            return client.newURIBuilder("https://example.com/";) //
+                .appendEntitySetSegment("Person") //
+                .filter(filter) //
+                .build().toString();
+        }
+
+        //CHECKSTYLE:OFF
+        /**
+         * Escapes a string literal by representing a single quote in a string 
literal as two consecutive single quotes,
+         * as per the <a 
href="https://docs.oasis-open.org/odata/odata/v4.01/os/part2-url-conventions/odata-v4.01-os-part2-url-conventions.html#sec_URLSyntax";>OData
 4.01 URL Conventions</a>
+         *
+         * @param value the value to escape
+         * @return the escaped value
+         */
+        //CHECKSTYLE:ON
+        private static String escape(String value) {
+            return value.replaceAll("'", "''");
+        }
+    }
+
+}

Reply via email to