Skip to content

[CALCITE-7740] Harden ModelHandler against content-dependent errors - #5221

Open
rubenada wants to merge 1 commit into
apache:mainfrom
rubenada:CALCITE-7740
Open

[CALCITE-7740] Harden ModelHandler against content-dependent errors#5221
rubenada wants to merge 1 commit into
apache:mainfrom
rubenada:CALCITE-7740

Conversation

@rubenada

Copy link
Copy Markdown
Contributor

Jira Link

CALCITE-7740

Changes Proposed

Harden ModelHandler against content-dependent errors: sanitize parse-error text for non-inline models, add optional calcite.model.baseDirectory system property, add some clarifications in this regard to the threat model.

@sonarqubecloud

Copy link
Copy Markdown

@xuzifu666 xuzifu666 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, only two comments regarding exception handling were left.

final Path basePath = Paths.get(baseDirectory).toAbsolutePath().normalize();
final Path path = basePath.resolve(uri).normalize();
if (!path.startsWith(basePath)) {
throw new SecurityException("Model file '" + uri + "' resolves"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using SecurityException to signal an "escape" rejection is somewhat unconventional. In JVM semantics, SecurityException is typically associated with the SecurityManager; using it here to indicate an "out-of-bounds path" could mislead operations staff when they examine the stack trace. Wouldn't it be more readable to use a dedicated RuntimeException (such as ModelBaseDirectoryException)?
That would also avoid confusion with potential SecurityManager behavior. Functionally, however, there are no issues.

root = mapper.readValue(new File(uri), JsonRoot.class);
try {
root = mapper.readValue(modelFile(uri), JsonRoot.class);
} catch (IOException e) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The catch block only covers IOException. In rare instances, mapper.readValue might throw unchecked exceptions containing payload data (such as RuntimeExceptions from custom deserializers), which would propagate directly to the client. Given that the vast majority of Jackson parsing or mapping errors are subclasses of IOException, the primary attack surface is already covered and the risk is low; however, for a stricter approach, one could add a catch-all for RuntimeException to suppress those as well.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants