Skip to content

[CDAP-21270] Handle JEXL security violations and fail pipeline immediately - #1055

Merged
sahusanket merged 1 commit into
developfrom
fix/jexl-error-handling
Sep 24, 2026
Merged

sahusanket merged 1 commit into
developfrom
fix/jexl-error-handling

Conversation

@riyaa14

@riyaa14 riyaa14 commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a dedicated ELSecurityException to handle JEXL sandbox security violations, ensuring that security violations immediately fail the pipeline regardless of the configured on-error strategy. It updates exception handling in EL, RecipePipelineExecutor, and Wrangler to propagate and detect these security exceptions, and adds corresponding unit tests. The review feedback highlights a bug where normal runtime exceptions wrapped in JEXL exceptions could be misclassified as security violations, suggesting a check for e.getCause() == null. Additionally, it is recommended to add a serialVersionUID to ELSecurityException to prevent serialization issues in distributed environments.

Comment on lines 210 to 213
private static boolean isJexlSecurityViolation(JexlException e, boolean allowlistEnabled) {
return allowlistEnabled
&& (e instanceof JexlException.Method || e instanceof JexlException.Property);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

If a method or property is successfully resolved (i.e., it is allowlisted) but its invocation throws a runtime exception (e.g., NullPointerException, IllegalArgumentException, etc.), JEXL wraps it in a JexlException.Method or JexlException.Property with a non-null cause.

Without checking e.getCause() == null, these normal runtime errors will be incorrectly classified as security violations, causing the pipeline to fail immediately and bypassing the configured onError strategy (such as send-to-error-port or skip-on-error). Adding e.getCause() == null ensures we only treat actual sandbox resolution blocks (which have no cause) as security violations.

Suggested change
private static boolean isJexlSecurityViolation(JexlException e, boolean allowlistEnabled) {
return allowlistEnabled
&& (e instanceof JexlException.Method || e instanceof JexlException.Property);
}
private static boolean isJexlSecurityViolation(JexlException e, boolean allowlistEnabled) {
return allowlistEnabled
&& e.getCause() == null
&& (e instanceof JexlException.Method || e instanceof JexlException.Property);
}

* Exception thrown when a JEXL expression violates security restrictions
* (e.g., accessing unallowlisted classes, methods, or properties).
*/
public class ELSecurityException extends RuntimeException {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Since ELSecurityException extends RuntimeException (which is Serializable) and is used in a distributed environment (CDAP pipelines running on MapReduce/Spark), it is highly recommended to define a serialVersionUID to prevent serialization/deserialization issues across JVM boundaries.

public class ELSecurityException extends RuntimeException {

  private static final long serialVersionUID = 1L;

@riyaa14
riyaa14 force-pushed the fix/jexl-error-handling branch 3 times, most recently from 99dbc6d to 8c7a775 Compare September 24, 2026 16:23
if (isJexlPermissionViolation(e, allowlistEnabled)) {
throw new ELPermissionException(
String.format(
"Disallowed Expression: %s Make sure the JEXL transformation uses only allowlisted "

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Remove this from message:

"Disallowed Expression: %s Make sure the JEXL transformation uses only allowlisted classes, methods, and properties.

Propagate the error details and let the user act on it by either allowlisting or fixing expression. The cause exception already has the details.

}

return new ELException(
String.format("%s Make sure the JEXL transformation is valid.", baseErrorMessage), e);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Don't format and remove

Make sure the JEXL transformation is valid.

Propagate the error details and let the user act on it by either allowlisting or fixing expression. The cause exception already has the details.

@riyaa14
riyaa14 force-pushed the fix/jexl-error-handling branch from 8c7a775 to 5ea4399 Compare September 24, 2026 19:35
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.

3 participants