[Enhancement] Add structural limits for deserialization filter - #5721
Conversation
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>
PR Reviewer Guide 🔍(Review updated until commit bc9bc19)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to bc9bc19 Explore these optional code suggestions:
Previous suggestionsSuggestions up to commit 76943f3
Suggestions up to commit a70d0db
Suggestions up to commit 1d89079
Suggestions up to commit 6143db0
Suggestions up to commit ec32115
|
Directly exercises maxdepth, maxrefs, and maxbytes rejections plus the allowlist/additional-pattern paths via ObjectInputFilter.FilterInfo. Signed-off-by: Jialiang Liang <jiallian@amazon.com>
|
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>
|
Persistent review updated to latest commit 6143db0 |
Replace the hardcoded maxdepth/maxrefs/maxbytes with dynamic cluster settings so operators can tune them without a code change: plugins.query.deserialization.max_depth (default 20) plugins.query.deserialization.max_refs (default 1000) plugins.query.deserialization.max_bytes (default 15000) Values are injected via Settings (same pattern as AstBuildGuard): the pagination path receives Settings through Planner/DefaultImplementor, and the script-engine paths receive a Supplier<Settings> because the script engine is constructed before plugin settings are initialized. createFilter falls back to the defaults when no Settings is available (serialize-only call sites and tests). Signed-off-by: Jialiang Liang <jiallian@amazon.com>
|
Persistent review updated to latest commit 1d89079 |
Verify the three plugins.query.deserialization.* settings have the expected defaults, are dynamically updatable, and are registered in pluginSettings(). Signed-off-by: Jialiang Liang <jiallian@amazon.com>
|
Persistent review updated to latest commit a70d0db |
Verifies a DefaultExpressionSerializer wired with a Supplier<Settings> enforces the configured maxrefs during real deserialization, while the default serializer round-trips the same payload. Signed-off-by: Jialiang Liang <jiallian@amazon.com>
|
Persistent review updated to latest commit 76943f3 |
Per review feedback, the settings-based createFilter now requires a non-null Settings (the deserialize paths always provide one). Add an explicit createFilter(String) overload that uses the built-in defaults for serialize-only call sites and tests, and let each serializer pick the overload based on whether it has settings. Signed-off-by: Jialiang Liang <jiallian@amazon.com>
|
Persistent review updated to latest commit bc9bc19 |
Description
Follow-up to #5469. Bounds the size and shape of the object graph produced during deserialization in
DeserializationFilterUtilwith structural limits (maxdepth,maxrefs,maxbytes), and logs structural-limit rejections (depth/refs/bytes) alongside the existing class-rejection logging.The limits are exposed as dynamic cluster settings so they can be tuned at runtime without a code change:
plugins.query.deserialization.max_depthplugins.query.deserialization.max_refsplugins.query.deserialization.max_bytesThe values are resolved from
Settingsat the call sites (the pagination path receivesSettingsthroughPlanner/DefaultImplementor; the script-engine paths receive a lazily-resolvedSupplier<Settings>because the script engine is constructed before plugin settings are initialized).createFilterfalls back to the defaults when noSettingsis available (serialize-only call sites and tests).Related Issues
Follow-up to #5469
Check List
--signoff.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.