Skip to content

[Enhancement] Add structural limits for deserialization filter - #5721

Open
RyanL1997 wants to merge 3 commits into
opensearch-project:mainfrom
RyanL1997:add-structural-limits-deserialization-filter
Open

[Enhancement] Add structural limits for deserialization filter#5721
RyanL1997 wants to merge 3 commits into
opensearch-project:mainfrom
RyanL1997:add-structural-limits-deserialization-filter

Conversation

@RyanL1997

Copy link
Copy Markdown
Collaborator

Description

Follow-up to #5469. Adds structural limits (maxdepth, maxrefs, maxbytes) to the filter created by DeserializationFilterUtil, bounding the size and shape of the deserialized object graph, and logs structural-limit rejections (depth/refs/bytes) alongside the existing class-rejection logging.

Related Issues

Follow-up to #5469

Check List

  • New functionality includes testing.
  • Commits are signed per the DCO using --signoff.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Follow-up to opensearch-project#5469. Bounds the deserialized object graph with
maxdepth/maxrefs/maxbytes limits and logs structural-limit rejections
alongside the existing class-rejection logging.

Signed-off-by: Jialiang Liang <jiallian@amazon.com>
@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

PR Reviewer Guide 🔍

(Review updated until commit 6143db0)

Here are some key observations to aid the review process:

🧪 PR contains tests
🔒 No security concerns identified
✅ No TODO sections
🔀 No multiple PR themes
⚡ Recommended focus areas for review

Structural limits order

The structural limits are appended after additionalPatterns in the filter pattern string. If additionalPatterns contains a wildcard rejection (e.g., '!*'), it would block the structural limits from being parsed. While unlikely in typical usage, this could silently disable the intended protections if a caller passes such a pattern.

String fullPattern = BASE_ALLOWLIST + additionalPatterns + STRUCTURAL_LIMITS + "!*";

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

PR Code Suggestions ✨

Latest suggestions up to 6143db0

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Make structural limits configurable

The structural limits may be too restrictive for legitimate use cases. Consider
making these limits configurable through system properties or configuration files to
allow tuning based on deployment requirements without code changes.

core/src/main/java/org/opensearch/sql/utils/DeserializationFilterUtil.java [50]

-private static final String STRUCTURAL_LIMITS = "maxdepth=20;maxrefs=1000;maxbytes=15000;";
+private static final String STRUCTURAL_LIMITS = 
+    String.format("maxdepth=%s;maxrefs=%s;maxbytes=%s;",
+        System.getProperty("opensearch.sql.deserialization.maxdepth", "20"),
+        System.getProperty("opensearch.sql.deserialization.maxrefs", "1000"),
+        System.getProperty("opensearch.sql.deserialization.maxbytes", "15000"));
Suggestion importance[1-10]: 5

__

Why: The suggestion to make structural limits configurable is valid and could improve flexibility. However, the improved_code changes a static final String to be dynamically computed, which may have initialization order implications and doesn't match the original constant declaration pattern. The suggestion addresses a minor enhancement rather than a critical issue.

Low

Previous suggestions

Suggestions up to commit ec32115
CategorySuggestion                                                                                                                                    Impact
General
Make structural limits configurable

The structural limits are hardcoded as constants. Consider making these configurable
through system properties or configuration files to allow administrators to adjust
limits based on their security requirements and application needs without code
changes.

core/src/main/java/org/opensearch/sql/utils/DeserializationFilterUtil.java [50]

-private static final String STRUCTURAL_LIMITS = "maxdepth=20;maxrefs=300;maxbytes=15000;";
+private static final int DEFAULT_MAX_DEPTH = 20;
+private static final int DEFAULT_MAX_REFS = 300;
+private static final int DEFAULT_MAX_BYTES = 15000;
 
+private static final String STRUCTURAL_LIMITS = String.format(
+    "maxdepth=%d;maxrefs=%d;maxbytes=%d;",
+    Integer.getInteger("opensearch.sql.deserialization.maxdepth", DEFAULT_MAX_DEPTH),
+    Integer.getInteger("opensearch.sql.deserialization.maxrefs", DEFAULT_MAX_REFS),
+    Integer.getInteger("opensearch.sql.deserialization.maxbytes", DEFAULT_MAX_BYTES)
+);
+
Suggestion importance[1-10]: 5

__

Why: While making security limits configurable could be useful for flexibility, this suggestion introduces complexity and potential security risks if misconfigured. The current hardcoded approach is acceptable for security-critical constants. The suggestion is valid but represents a design choice rather than a bug fix.

Low
Suggestions up to commit f73ca59
CategorySuggestion                                                                                                                                    Impact
Possible issue
Verify filter pattern ordering

The order of pattern concatenation places structural limits after class patterns but
before the reject-all pattern. Verify that this ordering is correct according to
ObjectInputFilter specification, as structural limits typically should appear before
class patterns.

core/src/main/java/org/opensearch/sql/utils/DeserializationFilterUtil.java [83]

-String fullPattern = BASE_ALLOWLIST + additionalPatterns + STRUCTURAL_LIMITS + "!*";
+String fullPattern = STRUCTURAL_LIMITS + BASE_ALLOWLIST + additionalPatterns + "!*";
Suggestion importance[1-10]: 7

__

Why: This suggestion raises a valid concern about the ordering of filter patterns. According to ObjectInputFilter specification, structural limits should typically be placed before class patterns. This could affect the filter's behavior and should be verified.

Medium
General
Make structural limits configurable

The structural limits may be too restrictive for legitimate use cases. Consider
making these limits configurable through system properties or configuration files to
allow adjustment based on deployment requirements without code changes.

core/src/main/java/org/opensearch/sql/utils/DeserializationFilterUtil.java [50]

-private static final String STRUCTURAL_LIMITS = "maxdepth=20;maxrefs=300;maxbytes=15000;";
+private static final String STRUCTURAL_LIMITS = 
+    "maxdepth=" + System.getProperty("opensearch.sql.deserialization.maxdepth", "20") + ";"
+    + "maxrefs=" + System.getProperty("opensearch.sql.deserialization.maxrefs", "300") + ";"
+    + "maxbytes=" + System.getProperty("opensearch.sql.deserialization.maxbytes", "15000") + ";";
Suggestion importance[1-10]: 5

__

Why: While making limits configurable adds flexibility, the suggestion is more of an enhancement than addressing a critical issue. The current hardcoded values are reasonable defaults, and the change adds complexity without evidence that configurability is needed.

Low

@RyanL1997 RyanL1997 changed the title Add structural limits for deserialization filter [Enhancement] Add structural limits for deserialization filter Aug 25, 2026
@RyanL1997 RyanL1997 added the enhancement New feature or request label Aug 25, 2026
Directly exercises maxdepth, maxrefs, and maxbytes rejections
plus the allowlist/additional-pattern paths via ObjectInputFilter.FilterInfo.

Signed-off-by: Jialiang Liang <jiallian@amazon.com>
@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit ec32115

The previous cap rejected legitimate paginated cursors (a SELECT * ...
ORDER BY query serializes to 301 refs), causing PaginationIT failures.
1000 leaves comfortable headroom for real cursors while remaining well
below deserialization-bomb scale. Test updated to match the new bound.

Signed-off-by: Jialiang Liang <jiallian@amazon.com>
@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit 6143db0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant