Repository navigation
feat/CUS-10876-Added If Condition Evaluator action for dynamic IF expressions - #343
Conversation
📝 WalkthroughWalkthroughThis PR introduces a new Maven module for Changes
Sequence Diagram(s)sequenceDiagram
participant Test as Test Step
participant Action as IfConditionEvaluator<br/>Action
participant Engine as JavaScript<br/>ScriptEngine
participant Result as Test Result
Test->>Action: execute(testData: condition)
activate Action
alt Valid Input
Action->>Action: Validate condition non-empty
Action->>Action: Transform operators<br/>(AND→&&, OR→||,<br/>CONTAINS→indexOf)
Action->>Engine: eval(transformedCondition)
activate Engine
Engine-->>Action: Boolean/Numeric result
deactivate Engine
alt Condition Evaluates True
Action->>Action: Set SUCCESS message
Action->>Result: return Result.SUCCESS
else Condition Evaluates False
Action->>Action: Set FAILED message
Action->>Result: return Result.FAILED
end
else Invalid/Missing Input
Action->>Action: Catch Exception
Action->>Action: Set error message
Action->>Result: return Result.FAILED
end
deactivate Action
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 10
♻️ Duplicate comments (5)
if_condition_evaluator/src/main/java/com/testsigma/addons/restapi/IfConditionEvaluatorAction.java (1)
63-102: SameevaluateConditionissues apply here (script injection, CONTAINS bug, Nashorn deprecation).See the detailed comments on
windows/IfConditionEvaluatorAction.java— all apply identically to this file.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@if_condition_evaluator/src/main/java/com/testsigma/addons/restapi/IfConditionEvaluatorAction.java` around lines 63 - 102, The evaluateCondition method must not use engine.eval (ScriptEngine) due to injection and Nashorn issues and also has a CONTAINS conversion bug; replace the eval-based approach by parsing the condition string (method evaluateCondition) into tokens and evaluating in Java: convert logical operators (AND/OR/NOT) to boolean ops, convert CONTAINS/NOT CONTAINS to safe String.contains calls (use operand1.contains(operand2) and !operand1.contains(operand2) rather than indexOf comparisons), handle quoted literals vs variable lookups via a controlled resolver/whitelist, and remove the ScriptEngine/engine.eval usage (and the ScriptEngineManager instantiation) entirely so all evaluation is done safely in Java without executing arbitrary JS. Ensure operandPattern handling and the regex replacements for CONTAINS/NOT CONTAINS in this class (evaluateCondition, operandPattern) treat quoted strings correctly and do not inject raw text into executable code.if_condition_evaluator/src/main/java/com/testsigma/addons/web/IfConditionEvaluatorAction.java (1)
62-101: SameevaluateConditionissues apply here (script injection, CONTAINS bug, Nashorn deprecation).See the detailed comments on
windows/IfConditionEvaluatorAction.java.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@if_condition_evaluator/src/main/java/com/testsigma/addons/web/IfConditionEvaluatorAction.java` around lines 62 - 101, The evaluateCondition method currently builds and evals a JavaScript string (ScriptEngineManager/engine.eval), which is vulnerable to script injection, uses fragile regex-based CONTAINS/NOT CONTAINS replacements (operandPattern/CONTAINS/NOT CONTAINS) and relies on the Nashorn JavaScript engine; fix by replacing the eval approach with a safe expression evaluator (e.g., Apache Commons JEXL or MVEL) inside evaluateCondition, parse the input condition using the existing operandPattern to extract and validate operands (only allow alphanumerics, underscores, dots or quoted literals), implement CONTAINS/NOT CONTAINS as safe function calls (e.g., contains(left,right) or left.indexOf(right) >= 0) in the evaluator syntax instead of string replacements, bind variable values into the evaluator context rather than concatenating into the expression, and remove usage of ScriptEngineManager/engine.eval to avoid Nashorn dependency.if_condition_evaluator/src/main/java/com/testsigma/addons/ios/IfConditionEvaluatorAction.java (1)
63-102: SameevaluateConditionissues apply here (script injection, CONTAINS bug, Nashorn deprecation).See the detailed comments on
windows/IfConditionEvaluatorAction.java.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@if_condition_evaluator/src/main/java/com/testsigma/addons/ios/IfConditionEvaluatorAction.java` around lines 63 - 102, The evaluateCondition method currently builds a JavaScript string from raw user input (operandPattern, CONTAINS/NOT CONTAINS replacements) and evals it via new ScriptEngineManager().getEngineByName("JavaScript"), which creates script-injection risk, incorrectly handles quoted/unquoted operands in some CONTAINS patterns, and relies on the deprecated Nashorn engine; fix by parsing the condition into a safe AST or token stream rather than string-replacing and eval-ing: use the existing operandPattern to extract operands and operators in evaluateCondition, evaluate CONTAINS/NOT CONTAINS by performing Java string operations on the extracted operands (avoid building JS code), ensure quoted literals are unquoted and escaped properly, and stop using ScriptEngineManager/engine.eval — either replace with a safe expression evaluator or implement direct boolean evaluation in evaluateCondition (use methods like String.contains or indexOf on the extracted operands); keep references to evaluateCondition, operandPattern, CONTAINS/NOT CONTAINS handling, and remove reliance on ScriptEngineManager/JavaScript so the code no longer depends on Nashorn.if_condition_evaluator/src/main/java/com/testsigma/addons/android/IfConditionEvaluatorAction.java (1)
63-102: SameevaluateConditionissues apply here (script injection, CONTAINS bug, Nashorn deprecation).See the detailed comments on
windows/IfConditionEvaluatorAction.java.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@if_condition_evaluator/src/main/java/com/testsigma/addons/android/IfConditionEvaluatorAction.java` around lines 63 - 102, The evaluateCondition method is currently vulnerable (uses engine.eval with unescaped input), mis-handles CONTAINS (uses String(...) JS calls) and relies on the (possibly absent) Nashorn JavaScript engine; replace the JS-eval approach with a safe Java-based evaluator: stop calling new ScriptEngineManager().getEngineByName("JavaScript") and engine.eval(condition), remove the JS-style CONTAINS/NOT CONTAINS replacements that produce String($1)..., and instead parse the condition using the existing operandPattern tokenization (or a small ExpressionParser) and evaluate operators (AND/OR/NOT, ==, !=, >, <, >=, <=, CONTAINS, NOT CONTAINS) in Java—treat quoted operands as string literals, unquoted operands as variables you resolve via the code’s variable lookup, implement CONTAINS as Java String.contains or Collection.contains, and ensure all variable values are escaped/validated to prevent injection; update evaluateCondition to return the boolean result from this Java evaluator and remove dependence on the ScriptEngine and engine variable.if_condition_evaluator/src/main/java/com/testsigma/addons/mobileweb/IfConditionEvaluatorAction.java (1)
62-101: SameevaluateConditionissues apply here (script injection, CONTAINS bug, Nashorn deprecation).See the detailed comments on
windows/IfConditionEvaluatorAction.java.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@if_condition_evaluator/src/main/java/com/testsigma/addons/mobileweb/IfConditionEvaluatorAction.java` around lines 62 - 101, The evaluateCondition method currently allows script injection, relies on deprecated Nashorn, and has fragile regex replacements for CONTAINS/NOT CONTAINS; update evaluateCondition to first validate and tokenize the incoming condition against a strict allowlist (only identifiers matching operandPattern, quoted string literals, AND/OR/NOT/CONTAINS, parentheses and comparison operators) and reject any other characters; replace the uses of String.replaceAll with a Matcher and appendReplacement/appendTail (or use Matcher.quoteReplacement) when substituting the CONTAINS/NOT CONTAINS patterns to avoid replacement side effects; remove direct ScriptEngine.eval usage (the engine lookup "JavaScript" / ScriptEngineManager) and either switch to a safe expression evaluator library (e.g., Apache Commons JEXL or MVEL) or use GraalVM's JS engine explicitly, mapping the sanitized tokens into the evaluator rather than injecting raw text; ensure NOT CONTAINS is transformed before CONTAINS and that replacements wrap operands safely as String conversions when building the evaluator expression (method: evaluateCondition, symbol: operandPattern, usages: ScriptEngine engine and engine.eval).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@if_condition_evaluator/pom.xml`:
- Around line 42-46: The TestNG dependency (groupId org.testng, artifactId
testng) in the pom is declared without <scope>test</scope> and uses an outdated
version (6.14.3) which will be included in the production artifact; change the
dependency to include <scope>test</scope> and update the version to a maintained
release (e.g., TestNG 7.x) or remove the TestNG dependency entirely if you are
using JUnit Jupiter instead (ensure only one test framework remains); update the
<dependency> entry for testng accordingly in the pom.xml.
- Line 17: Update the junit.jupiter.version Maven property in the POM from the
pre-release "5.8.0-M1" to the stable GA release "5.14.3"; edit the
<junit.jupiter.version> property value so the project builds and tests use the
latest JUnit 5.14.3 artifacts, and ensure any plugin or dependencyManagement
entries referencing junit.jupiter.version pick up the new value.
In
`@if_condition_evaluator/src/main/java/com/testsigma/addons/android/IfConditionEvaluatorAction.java`:
- Line 6: Remove the unused import of WebAction from IfConditionEvaluatorAction:
the class extends AndroidAction and never references WebAction, so delete the
line importing com.testsigma.sdk.WebAction to clean up unused imports in the
file.
In
`@if_condition_evaluator/src/main/java/com/testsigma/addons/ios/IfConditionEvaluatorAction.java`:
- Line 6: Remove the unused import com.testsigma.sdk.WebAction from
IfConditionEvaluatorAction.java; this class extends IOSAction and does not
reference WebAction anywhere (so delete the import line to eliminate the
unused-import warning).
In
`@if_condition_evaluator/src/main/java/com/testsigma/addons/restapi/IfConditionEvaluatorAction.java`:
- Line 6: Remove the unused import of com.testsigma.sdk.WebAction from
IfConditionEvaluatorAction.java; since the class extends RestApiAction and never
references WebAction, delete the import line for WebAction to clean up unused
imports and avoid warnings.
In
`@if_condition_evaluator/src/main/java/com/testsigma/addons/windows/IfConditionEvaluatorAction.java`:
- Around line 63-102: The evaluateCondition method is duplicated across platform
action classes; extract its logic into a single shared utility class
com.testsigma.addons.common.ConditionEvaluator with a public static boolean
evaluateCondition(String condition) throws Exception (preserve behavior:
operator conversions, CONTAINS/NOT CONTAINS regexes, JS engine eval and result
handling), replace the local private boolean evaluateCondition(...)
implementations in each platform action (e.g., IfConditionEvaluatorAction) with
calls to ConditionEvaluator.evaluateCondition(condition), and update imports
accordingly so all six platform action classes reuse the single implementation.
- Line 5: Remove the unused import of WebAction from
IfConditionEvaluatorAction.java: the class IfConditionEvaluatorAction extends
WindowsAction and does not reference WebAction, so delete the line importing
com.testsigma.sdk.WebAction to eliminate the unused import and clean up imports.
- Around line 63-81: The CONTAINS/NOT CONTAINS replacements in evaluateCondition
produce invalid JS for unquoted bare-word operands because operandPattern allows
bare words (e.g., Testsigma) and the replacement emits String(Testsigma)...; fix
by performing the replacement programmatically instead of a blind replaceAll:
compile the regexes used for
"(?i)"+operandPattern+"\\s+CONTAINS\\s+"+operandPattern and for NOT CONTAINS,
iterate matches with a Matcher, and for each captured operand ($1/$2) check if
it's already quoted or purely numeric—if not, wrap it in quotes before building
the replacement string ("String(\"operand\")..."). Update the code in
evaluateCondition to use these Matcher-based replacements for both CONTAINS and
NOT CONTAINS so only bare-word non-numeric operands are auto-quoted.
- Around line 85-91: The current use of ScriptEngineManager and
engine.eval(condition) in IfConditionEvaluatorAction executes untrusted
JavaScript and allows Java interop RCE and will break on modern JVMs; replace
this by removing engine.eval usage and implementing a safe, restricted
evaluator: either parse and validate the condition against a whitelist of
allowed operators/identifiers (no eval) or integrate a sandboxed expression
library such as Apache Commons JEXL with JexlSandbox or EvalEx (or use GraalVM
polyglot with strict host-access policies) in place of ScriptEngineManager,
ensuring the new code restricts available functions/classes and rejects any
input that isn't matched by the whitelist/parser (update the method that
currently calls engine.eval to use the new evaluator).
In `@if_condition_evaluator/src/main/resources/testsigma-sdk.properties`:
- Line 1: The committed JWT under the property key testsigma-sdk.api.key must be
removed and rotated: replace the literal value with a reference to an
environment variable or a secret lookup (e.g., read from process.env or your
secret manager) in the code that loads testsigma-sdk.api.key, add this
properties file to .gitignore so it won't be re-committed, rotate/invalidate the
exposed token immediately, and purge it from git history using a tool like git
filter-repo or BFG to ensure the secret is removed from the repository history.
---
Duplicate comments:
In
`@if_condition_evaluator/src/main/java/com/testsigma/addons/android/IfConditionEvaluatorAction.java`:
- Around line 63-102: The evaluateCondition method is currently vulnerable (uses
engine.eval with unescaped input), mis-handles CONTAINS (uses String(...) JS
calls) and relies on the (possibly absent) Nashorn JavaScript engine; replace
the JS-eval approach with a safe Java-based evaluator: stop calling new
ScriptEngineManager().getEngineByName("JavaScript") and engine.eval(condition),
remove the JS-style CONTAINS/NOT CONTAINS replacements that produce
String($1)..., and instead parse the condition using the existing operandPattern
tokenization (or a small ExpressionParser) and evaluate operators (AND/OR/NOT,
==, !=, >, <, >=, <=, CONTAINS, NOT CONTAINS) in Java—treat quoted operands as
string literals, unquoted operands as variables you resolve via the code’s
variable lookup, implement CONTAINS as Java String.contains or
Collection.contains, and ensure all variable values are escaped/validated to
prevent injection; update evaluateCondition to return the boolean result from
this Java evaluator and remove dependence on the ScriptEngine and engine
variable.
In
`@if_condition_evaluator/src/main/java/com/testsigma/addons/ios/IfConditionEvaluatorAction.java`:
- Around line 63-102: The evaluateCondition method currently builds a JavaScript
string from raw user input (operandPattern, CONTAINS/NOT CONTAINS replacements)
and evals it via new ScriptEngineManager().getEngineByName("JavaScript"), which
creates script-injection risk, incorrectly handles quoted/unquoted operands in
some CONTAINS patterns, and relies on the deprecated Nashorn engine; fix by
parsing the condition into a safe AST or token stream rather than
string-replacing and eval-ing: use the existing operandPattern to extract
operands and operators in evaluateCondition, evaluate CONTAINS/NOT CONTAINS by
performing Java string operations on the extracted operands (avoid building JS
code), ensure quoted literals are unquoted and escaped properly, and stop using
ScriptEngineManager/engine.eval — either replace with a safe expression
evaluator or implement direct boolean evaluation in evaluateCondition (use
methods like String.contains or indexOf on the extracted operands); keep
references to evaluateCondition, operandPattern, CONTAINS/NOT CONTAINS handling,
and remove reliance on ScriptEngineManager/JavaScript so the code no longer
depends on Nashorn.
In
`@if_condition_evaluator/src/main/java/com/testsigma/addons/mobileweb/IfConditionEvaluatorAction.java`:
- Around line 62-101: The evaluateCondition method currently allows script
injection, relies on deprecated Nashorn, and has fragile regex replacements for
CONTAINS/NOT CONTAINS; update evaluateCondition to first validate and tokenize
the incoming condition against a strict allowlist (only identifiers matching
operandPattern, quoted string literals, AND/OR/NOT/CONTAINS, parentheses and
comparison operators) and reject any other characters; replace the uses of
String.replaceAll with a Matcher and appendReplacement/appendTail (or use
Matcher.quoteReplacement) when substituting the CONTAINS/NOT CONTAINS patterns
to avoid replacement side effects; remove direct ScriptEngine.eval usage (the
engine lookup "JavaScript" / ScriptEngineManager) and either switch to a safe
expression evaluator library (e.g., Apache Commons JEXL or MVEL) or use
GraalVM's JS engine explicitly, mapping the sanitized tokens into the evaluator
rather than injecting raw text; ensure NOT CONTAINS is transformed before
CONTAINS and that replacements wrap operands safely as String conversions when
building the evaluator expression (method: evaluateCondition, symbol:
operandPattern, usages: ScriptEngine engine and engine.eval).
In
`@if_condition_evaluator/src/main/java/com/testsigma/addons/restapi/IfConditionEvaluatorAction.java`:
- Around line 63-102: The evaluateCondition method must not use engine.eval
(ScriptEngine) due to injection and Nashorn issues and also has a CONTAINS
conversion bug; replace the eval-based approach by parsing the condition string
(method evaluateCondition) into tokens and evaluating in Java: convert logical
operators (AND/OR/NOT) to boolean ops, convert CONTAINS/NOT CONTAINS to safe
String.contains calls (use operand1.contains(operand2) and
!operand1.contains(operand2) rather than indexOf comparisons), handle quoted
literals vs variable lookups via a controlled resolver/whitelist, and remove the
ScriptEngine/engine.eval usage (and the ScriptEngineManager instantiation)
entirely so all evaluation is done safely in Java without executing arbitrary
JS. Ensure operandPattern handling and the regex replacements for CONTAINS/NOT
CONTAINS in this class (evaluateCondition, operandPattern) treat quoted strings
correctly and do not inject raw text into executable code.
In
`@if_condition_evaluator/src/main/java/com/testsigma/addons/web/IfConditionEvaluatorAction.java`:
- Around line 62-101: The evaluateCondition method currently builds and evals a
JavaScript string (ScriptEngineManager/engine.eval), which is vulnerable to
script injection, uses fragile regex-based CONTAINS/NOT CONTAINS replacements
(operandPattern/CONTAINS/NOT CONTAINS) and relies on the Nashorn JavaScript
engine; fix by replacing the eval approach with a safe expression evaluator
(e.g., Apache Commons JEXL or MVEL) inside evaluateCondition, parse the input
condition using the existing operandPattern to extract and validate operands
(only allow alphanumerics, underscores, dots or quoted literals), implement
CONTAINS/NOT CONTAINS as safe function calls (e.g., contains(left,right) or
left.indexOf(right) >= 0) in the evaluator syntax instead of string
replacements, bind variable values into the evaluator context rather than
concatenating into the expression, and remove usage of
ScriptEngineManager/engine.eval to avoid Nashorn dependency.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
if_condition_evaluator/pom.xmlif_condition_evaluator/src/main/java/com/testsigma/addons/android/IfConditionEvaluatorAction.javaif_condition_evaluator/src/main/java/com/testsigma/addons/ios/IfConditionEvaluatorAction.javaif_condition_evaluator/src/main/java/com/testsigma/addons/mobileweb/IfConditionEvaluatorAction.javaif_condition_evaluator/src/main/java/com/testsigma/addons/restapi/IfConditionEvaluatorAction.javaif_condition_evaluator/src/main/java/com/testsigma/addons/web/IfConditionEvaluatorAction.javaif_condition_evaluator/src/main/java/com/testsigma/addons/windows/IfConditionEvaluatorAction.javaif_condition_evaluator/src/main/resources/testsigma-sdk.properties
| <maven.compiler.source>11</maven.compiler.source> | ||
| <maven.compiler.target>11</maven.compiler.target> | ||
| <testsigma.sdk.version>1.2.24_cloud</testsigma.sdk.version> | ||
| <junit.jupiter.version>5.8.0-M1</junit.jupiter.version> |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
JUnit Jupiter 5.8 stable release version
💡 Result:
The latest stable (GA) release in the JUnit Jupiter 5.8.x line is 5.8.2, released November 28, 2021. [1][2]
🌐 Web query:
JUnit 5 latest stable release 2025 2026
💡 Result:
As of February 24, 2026, the latest stable JUnit 5 (JUnit Jupiter) release is 5.14.3, published February 15, 2026. [1][2]
Latest stable JUnit 5 releases by year:
- 2026: 5.14.3 (Feb 15, 2026) [1][2]
- 2025: 5.14.1 (Oct 31, 2025) [3]
Sources
- Maven Central directory listing for
org.junit.jupiter:junit-jupiter-engine(shows5.14.3dated 2026-02-15): [1] - MVNRepository versions table for
org.junit.jupiter:junit-jupiter-api(shows5.14.3dated Feb 15, 2026): [2] - JUnit “Release Notes” for 5.14.1 (release date Oct 31, 2025): [3]
Upgrade to JUnit 5.14.3 (latest stable release).
JUnit 5.8.0-M1 is a milestone pre-release from 2021. Use a stable GA release instead; the current latest stable version is 5.14.3 (released February 15, 2026).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@if_condition_evaluator/pom.xml` at line 17, Update the junit.jupiter.version
Maven property in the POM from the pre-release "5.8.0-M1" to the stable GA
release "5.14.3"; edit the <junit.jupiter.version> property value so the project
builds and tests use the latest JUnit 5.14.3 artifacts, and ensure any plugin or
dependencyManagement entries referencing junit.jupiter.version pick up the new
value.
| <dependency> | ||
| <groupId>org.testng</groupId> | ||
| <artifactId>testng</artifactId> | ||
| <version>6.14.3</version> | ||
| </dependency> |
There was a problem hiding this comment.
TestNG dependency is missing <scope>test</scope> and is outdated.
TestNG 6.14.3 is from 2018 and will be shaded into the uber-jar since it lacks <scope>test</scope>. If it's only used for tests, scope it accordingly. Also consider whether you need both JUnit Jupiter and TestNG — typically one test framework suffices.
Proposed fix
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
- <version>6.14.3</version>
+ <version>6.14.3</version>
+ <scope>test</scope>
</dependency>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <dependency> | |
| <groupId>org.testng</groupId> | |
| <artifactId>testng</artifactId> | |
| <version>6.14.3</version> | |
| </dependency> | |
| <dependency> | |
| <groupId>org.testng</groupId> | |
| <artifactId>testng</artifactId> | |
| <version>6.14.3</version> | |
| <scope>test</scope> | |
| </dependency> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@if_condition_evaluator/pom.xml` around lines 42 - 46, The TestNG dependency
(groupId org.testng, artifactId testng) in the pom is declared without
<scope>test</scope> and uses an outdated version (6.14.3) which will be included
in the production artifact; change the dependency to include <scope>test</scope>
and update the version to a maintained release (e.g., TestNG 7.x) or remove the
TestNG dependency entirely if you are using JUnit Jupiter instead (ensure only
one test framework remains); update the <dependency> entry for testng
accordingly in the pom.xml.
| import com.testsigma.sdk.AndroidAction; | ||
| import com.testsigma.sdk.ApplicationType; | ||
| import com.testsigma.sdk.StepActionType; | ||
| import com.testsigma.sdk.WebAction; |
There was a problem hiding this comment.
Unused import: WebAction is not referenced.
This class extends AndroidAction. Remove the unused WebAction import.
Proposed fix
-import com.testsigma.sdk.WebAction;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import com.testsigma.sdk.WebAction; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@if_condition_evaluator/src/main/java/com/testsigma/addons/android/IfConditionEvaluatorAction.java`
at line 6, Remove the unused import of WebAction from
IfConditionEvaluatorAction: the class extends AndroidAction and never references
WebAction, so delete the line importing com.testsigma.sdk.WebAction to clean up
unused imports in the file.
| import com.testsigma.sdk.ApplicationType; | ||
| import com.testsigma.sdk.IOSAction; | ||
| import com.testsigma.sdk.StepActionType; | ||
| import com.testsigma.sdk.WebAction; |
There was a problem hiding this comment.
Unused import: WebAction is not referenced.
This class extends IOSAction. Remove the unused WebAction import.
Proposed fix
-import com.testsigma.sdk.WebAction;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import com.testsigma.sdk.WebAction; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@if_condition_evaluator/src/main/java/com/testsigma/addons/ios/IfConditionEvaluatorAction.java`
at line 6, Remove the unused import com.testsigma.sdk.WebAction from
IfConditionEvaluatorAction.java; this class extends IOSAction and does not
reference WebAction anywhere (so delete the import line to eliminate the
unused-import warning).
| import com.testsigma.sdk.ApplicationType; | ||
| import com.testsigma.sdk.RestApiAction; | ||
| import com.testsigma.sdk.StepActionType; | ||
| import com.testsigma.sdk.WebAction; |
There was a problem hiding this comment.
Unused import: WebAction is not referenced.
This class extends RestApiAction. Remove the unused WebAction import.
Proposed fix
-import com.testsigma.sdk.WebAction;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import com.testsigma.sdk.WebAction; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@if_condition_evaluator/src/main/java/com/testsigma/addons/restapi/IfConditionEvaluatorAction.java`
at line 6, Remove the unused import of com.testsigma.sdk.WebAction from
IfConditionEvaluatorAction.java; since the class extends RestApiAction and never
references WebAction, delete the import line for WebAction to clean up unused
imports and avoid warnings.
|
|
||
| import com.testsigma.sdk.ApplicationType; | ||
| import com.testsigma.sdk.StepActionType; | ||
| import com.testsigma.sdk.WebAction; |
There was a problem hiding this comment.
Unused import: WebAction is not referenced.
This class extends WindowsAction, not WebAction. Remove the unused import.
Proposed fix
-import com.testsigma.sdk.WebAction;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import com.testsigma.sdk.WebAction; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@if_condition_evaluator/src/main/java/com/testsigma/addons/windows/IfConditionEvaluatorAction.java`
at line 5, Remove the unused import of WebAction from
IfConditionEvaluatorAction.java: the class IfConditionEvaluatorAction extends
WindowsAction and does not reference WebAction, so delete the line importing
com.testsigma.sdk.WebAction to eliminate the unused import and clean up imports.
| private boolean evaluateCondition(String condition) throws Exception { | ||
|
|
||
| // Convert logical operators | ||
| condition = condition.replaceAll("(?i)\\bAND\\b", "&&"); | ||
| condition = condition.replaceAll("(?i)\\bOR\\b", "||"); | ||
|
|
||
| String operandPattern = "([a-zA-Z0-9_\\.]+|\"[^\"]*\"|'[^']*')"; | ||
|
|
||
| // Convert NOT CONTAINS | ||
| condition = condition.replaceAll( | ||
| "(?i)" + operandPattern + "\\s+NOT\\s+CONTAINS\\s+" + operandPattern, | ||
| "String($1).indexOf(String($2)) === -1" | ||
| ); | ||
|
|
||
| // Convert CONTAINS | ||
| condition = condition.replaceAll( | ||
| "(?i)" + operandPattern + "\\s+CONTAINS\\s+" + operandPattern, | ||
| "String($1).indexOf(String($2)) !== -1" | ||
| ); | ||
|
|
||
| logger.info("Converted Condition (JS format): " + condition); | ||
|
|
||
| ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); | ||
|
|
||
| if (engine == null) { | ||
| throw new Exception("JavaScript Engine not available. Check Java version."); | ||
| } | ||
|
|
||
| Object evalResult = engine.eval(condition); | ||
|
|
||
| if (evalResult instanceof Boolean) { | ||
| return (Boolean) evalResult; | ||
| } | ||
|
|
||
| if (evalResult instanceof Number) { | ||
| return ((Number) evalResult).doubleValue() != 0; | ||
| } | ||
|
|
||
| return false; | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Extract evaluateCondition into a shared utility class.
This method is duplicated verbatim across all 6 platform action files (Android, iOS, MobileWeb, REST API, Web, Windows). Any bug fix or enhancement would need to be applied 6 times.
Extract it into a shared utility, e.g. com.testsigma.addons.common.ConditionEvaluator, and call it from each platform action.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@if_condition_evaluator/src/main/java/com/testsigma/addons/windows/IfConditionEvaluatorAction.java`
around lines 63 - 102, The evaluateCondition method is duplicated across
platform action classes; extract its logic into a single shared utility class
com.testsigma.addons.common.ConditionEvaluator with a public static boolean
evaluateCondition(String condition) throws Exception (preserve behavior:
operator conversions, CONTAINS/NOT CONTAINS regexes, JS engine eval and result
handling), replace the local private boolean evaluateCondition(...)
implementations in each platform action (e.g., IfConditionEvaluatorAction) with
calls to ConditionEvaluator.evaluateCondition(condition), and update imports
accordingly so all six platform action classes reuse the single implementation.
| private boolean evaluateCondition(String condition) throws Exception { | ||
|
|
||
| // Convert logical operators | ||
| condition = condition.replaceAll("(?i)\\bAND\\b", "&&"); | ||
| condition = condition.replaceAll("(?i)\\bOR\\b", "||"); | ||
|
|
||
| String operandPattern = "([a-zA-Z0-9_\\.]+|\"[^\"]*\"|'[^']*')"; | ||
|
|
||
| // Convert NOT CONTAINS | ||
| condition = condition.replaceAll( | ||
| "(?i)" + operandPattern + "\\s+NOT\\s+CONTAINS\\s+" + operandPattern, | ||
| "String($1).indexOf(String($2)) === -1" | ||
| ); | ||
|
|
||
| // Convert CONTAINS | ||
| condition = condition.replaceAll( | ||
| "(?i)" + operandPattern + "\\s+CONTAINS\\s+" + operandPattern, | ||
| "String($1).indexOf(String($2)) !== -1" | ||
| ); |
There was a problem hiding this comment.
Bug: Unquoted string operands in CONTAINS produce invalid JavaScript.
The operandPattern regex captures bare words like Testsigma and sigma as-is, producing String(Testsigma).indexOf(String(sigma)) !== -1. In JavaScript, Testsigma and sigma are treated as undefined variable references, causing a ReferenceError at runtime.
The example in actionText — Testsigma CONTAINS sigma — would itself fail.
Fix: wrap unquoted (non-numeric) operands in quotes during the replacement, or document that string operands must be quoted.
Proposed fix: auto-quote non-numeric bare-word operands
// Convert NOT CONTAINS
condition = condition.replaceAll(
"(?i)" + operandPattern + "\\s+NOT\\s+CONTAINS\\s+" + operandPattern,
- "String($1).indexOf(String($2)) === -1"
+ "String(\"$1\").indexOf(String(\"$2\")) === -1"
);
// Convert CONTAINS
condition = condition.replaceAll(
"(?i)" + operandPattern + "\\s+CONTAINS\\s+" + operandPattern,
- "String($1).indexOf(String($2)) !== -1"
+ "String(\"$1\").indexOf(String(\"$2\")) === -1"
);Note: this naive fix would double-quote already-quoted operands. A more robust approach would conditionally wrap only bare-word captures. Alternatively, switch to a proper expression parser.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@if_condition_evaluator/src/main/java/com/testsigma/addons/windows/IfConditionEvaluatorAction.java`
around lines 63 - 81, The CONTAINS/NOT CONTAINS replacements in
evaluateCondition produce invalid JS for unquoted bare-word operands because
operandPattern allows bare words (e.g., Testsigma) and the replacement emits
String(Testsigma)...; fix by performing the replacement programmatically instead
of a blind replaceAll: compile the regexes used for
"(?i)"+operandPattern+"\\s+CONTAINS\\s+"+operandPattern and for NOT CONTAINS,
iterate matches with a Matcher, and for each captured operand ($1/$2) check if
it's already quoted or purely numeric—if not, wrap it in quotes before building
the replacement string ("String(\"operand\")..."). Update the code in
evaluateCondition to use these Matcher-based replacements for both CONTAINS and
NOT CONTAINS so only bare-word non-numeric operands are auto-quoted.
| ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); | ||
|
|
||
| if (engine == null) { | ||
| throw new Exception("JavaScript Engine not available. Check Java version."); | ||
| } | ||
|
|
||
| Object evalResult = engine.eval(condition); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "pom.xml" -type f | head -5Repository: testsigmahq/testsigma-addons
Length of output: 1735
🏁 Script executed:
fd IfConditionEvaluatorAction.javaRepository: testsigmahq/testsigma-addons
Length of output: 1735
🌐 Web query:
Nashorn JavaScript engine Java 11 deprecation removal Java 15
💡 Result:
- Java 11 (JEP 335): The Nashorn JavaScript engine, its public APIs, and the
jjstool were deprecated for removal (i.e., marked@Deprecated(forRemoval=true)), signaling they would be taken out in a future JDK. [1], [4], [5] - Java 15 (JEP 372): Nashorn (engine + APIs) and the
jjstool were removed from the JDK. [2], [3], [6] - What breaks / what’s gone: The Nashorn modules (notably
jdk.scripting.nashornandjdk.scripting.nashorn.shell) are no longer available starting in JDK 15. [2], [3] - Replacement direction: Oracle’s guidance commonly points to GraalVM JavaScript as a migration target for Nashorn-based code. [4]
Sources
[1] JEP 335 (JDK 11) – Deprecate Nashorn for Removal: https://jeps.dev/docs/jdk11/335/
[2] Oracle JDK 15 Release Notes – Removal of Nashorn: https://www.oracle.com/java/technologies/javase/15all-relnotes.html
[3] Oracle “Removed Tools and Components” (JDK 15) – Nashorn removed, cites JEP 372: https://docs.oracle.com/en/java/javase/21/migrate/removed-tools-and-components.html
[4] Oracle GraalVM Docs – Nashorn migration guide (notes deprecation in 11, removal in 15): https://docs.oracle.com/en/graalvm/jdk/21/docs/reference-manual/js/NashornMigrationGuide/
[5] Oracle Java 11 API Deprecated List (includes jdk.scripting.nashorn): https://docs.oracle.com/en/java/javase/11/docs/api/deprecated-list.html
[6] Oracle Java Blog – Java 15 (mentions JEP 372): https://blogs.oracle.com/java/the-arrival-of-java-15
🌐 Web query:
Nashorn Java interop security vulnerability arbitrary code execution
💡 Result:
Nashorn’s “Java interop” (e.g., Java.type(...), Packages, etc.) means that any application that evaluates untrusted JavaScript with Nashorn can often be turned into arbitrary Java/OS command execution, because the script can reach powerful JDK classes like java.lang.Runtime unless interop is explicitly disabled or sandboxed correctly. Real-world RCEs frequently come from applications embedding Nashorn unsafely, not from a single “Nashorn CVE” in isolation. [6][4]
Common RCE pattern
If a product exposes a Nashorn-evaluated expression/script to attackers (directly or via workflow rules, templating, UDFs, etc.), an attacker can do things like:
- Load Java classes via interop and execute OS commands (e.g.,
Runtime.getRuntime().exec(...)) [6][4] - Escape partial “sandboxing” by obtaining the underlying engine and instantiating a new engine without the intended restrictions (“engine property” / re-create engine) [2][6]
Why “sandboxing” often fails
Multiple analyses show that ClassFilter-only or incomplete restrictions are bypassable, especially via access to the engine (this.engine) and creating a new ScriptEngine/engine instance that isn’t constrained the way you expect. The engine exposure is explicitly called out as leading to arbitrary code execution in sandbox wrappers. [2][6]
Discussion in the security community also emphasizes that “don’t run untrusted code” is often the only robust guidance unless you combine multiple controls (and even then it’s tricky). [1]
Concrete examples seen in the wild
- Apache Cassandra UDF RCE (CVE-2021-44521): exploitation uses Nashorn Java interop patterns to reach dangerous Java functionality and achieve server-side command execution. [6]
- Conductor OSS / Orkes Conductor RCE (CVE-2025-26074): reported as stemming from initializing Nashorn without restrictions, enabling
Java.type()access and command execution in workflows. [4][1]
Practical mitigations (if you must embed Nashorn)
- Disable Java interop with the Nashorn option
--no-java(many product fixes do exactly this). [1][4] - Do not expose the engine object / block
this.engineaccess; exposure of theengineproperty is a known escape vector. [2][1] - Historically, SecurityManager was used as part of a defense-in-depth story, but it’s also complicated operationally and is deprecated in modern Java; relying on it is increasingly impractical. [1]
- Prefer not using Nashorn for untrusted code at all; OpenJDK has long since deprecated Nashorn for removal. [5]
Sources: oss-security discussion on Nashorn sandbox bypass and “engine” property [1]; Snyk advisory on delight-nashorn-sandbox arbitrary code execution via exposed engine [2]; JFrog writeup demonstrating Nashorn escape leading to command execution in Cassandra UDFs [6]; Conductor CVE-2025-26074 reports of RCE via unrestricted Nashorn Java access [4]; OpenJDK JEP 335 deprecating Nashorn for removal [5].
🌐 Web query:
Java ScriptEngine eval() security best practices expression evaluator
💡 Result:
Key rule
- Do not pass untrusted input to
ScriptEngine.eval(). Treat it as code execution (RCE) risk; prefer not evaluating user-controlled expressions at all. OWASP’s guidance for expression interpreters is essentially: avoid evaluating user input; otherwise strictly constrain what can be interpreted/executed. [4]
If you only need “expressions”, don’t use JavaScript
Use a purpose-built expression evaluator (smaller language surface area) and explicitly sandbox/allowlist what can be accessed:
- Apache Commons JEXL supports a sandbox model with allowlists/blocklists for properties/methods/constructors (
JexlSandbox). [5] - General best practice: allowlist operators/functions/identifiers; disallow reflection, class loading, and any I/O primitives.
If you must run JavaScript, prefer GraalJS + strong sandboxing (not ad‑hoc eval)
Modern JDKs no longer ship Nashorn (removed in JDK 15), so “JavaScript via ScriptEngine” typically means bringing your own engine (often GraalJS). [2]
With GraalVM Polyglot Context, apply a “deny-by-default” sandbox:
- Use sandbox policies (e.g.,
SandboxPolicy.UNTRUSTED) and restrict host access (e.g.,HostAccess.UNTRUSTED/ explicit exports only). [1] - Disable/limit Java interoperability: do not enable broad host access or permissive host class lookup; only expose specific safe APIs. (If host class lookup is allowed, Java classes become reachable from JS.) [7]
- Set hard resource limits to reduce DoS risk: max CPU time, statements, heap, stack frames, threads, output size, AST depth, etc. [1]
- Don’t accidentally bypass the sandbox by exposing a “convenience” host method that performs privileged actions (file/network/process); that can nullify
allowIO=false-style restrictions. [6]
If you’re still on Nashorn
- Historically, Nashorn relied on the Java Security Manager model for “untrusted” eval’d scripts (string/reader treated as sandboxed), but this approach is increasingly impractical because the Security Manager is deprecated; plan migration. [3]
Practical checklist
- Best: replace with a constrained expression language (allowlist) rather than JS.
- If JS is required: GraalVM Context + UNTRUSTED sandbox + minimal host access + resource limits.
- Run evaluation out-of-process (separate OS user/container) for defense-in-depth when stakes are high.
- Log/monitor evaluations and keep the engine updated. [1]
Security: Critical—arbitrary code execution via engine.eval() on user-supplied input.
engine.eval(condition) executes untrusted user input as JavaScript code. Due to Nashorn's Java interop, attackers can reach Java classes like java.lang.Runtime to execute arbitrary system commands (e.g., Java.type('java.lang.Runtime').getRuntime().exec(...)). This is confirmed in real-world CVEs:
- CVE-2021-44521 (Apache Cassandra UDF RCE)
- CVE-2025-26074 (Conductor workflow RCE)
Additionally, Nashorn is deprecated since Java 11 (JEP 335) and removed in Java 15+ (JEP 372). This code will break on modern JVMs unless a standalone Nashorn dependency is added.
Recommended fixes (in order of preference):
- Avoid evaluating untrusted input entirely. If you need simple conditional logic, parse and validate input against a whitelist of operators/values instead of evaluating arbitrary code.
- Replace with a sandboxed expression evaluator (e.g., Apache Commons JEXL with
JexlSandbox, Spring Expression Language, or EvalEx) that restricts available operations. - If JavaScript is required, use GraalVM Polyglot Context with UNTRUSTED sandbox policies and minimal host access, not ad-hoc eval.
Note: Disabling Java interop via --no-java or using ClassFilter alone is insufficient—these restrictions are often bypassable.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@if_condition_evaluator/src/main/java/com/testsigma/addons/windows/IfConditionEvaluatorAction.java`
around lines 85 - 91, The current use of ScriptEngineManager and
engine.eval(condition) in IfConditionEvaluatorAction executes untrusted
JavaScript and allows Java interop RCE and will break on modern JVMs; replace
this by removing engine.eval usage and implementing a safe, restricted
evaluator: either parse and validate the condition against a whitelist of
allowed operators/identifiers (no eval) or integrate a sandboxed expression
library such as Apache Commons JEXL with JexlSandbox or EvalEx (or use GraalVM
polyglot with strict host-access policies) in place of ScriptEngineManager,
ensuring the new code restricts available functions/classes and rejects any
input that isn't matched by the whitelist/parser (update the method that
currently calls engine.eval to use the new evaluator).
| @@ -0,0 +1 @@ | |||
| testsigma-sdk.api.key=eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIyMjMyMmM2Ni04NWYzLWIyN2UtN2FiOS0zM2U2M2Q4OWM1MGIiLCJ1bmlxdWVJZCI6IjU5OTYiLCJpZGVudGl0eUFjY291bnRVVUlkIjoiNDMifQ.GoblsmuHFdMOKiEL9HBx7J2Q74MnkMYjdKzyDFXA4YamryBO_5Nr_ajHygSf6Cc4G2X4Y36jtgcJVHhiYOBf7g No newline at end of file | |||
There was a problem hiding this comment.
Critical: API key / secret token committed to source control.
This JWT token is being committed to a public repository. It contains authentication credentials (sub, uniqueId, identityAccountUUId claims) that should never be checked into version control. This token must be rotated immediately and removed from git history.
Use environment variables or a secrets manager instead, and add this file to .gitignore.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@if_condition_evaluator/src/main/resources/testsigma-sdk.properties` at line
1, The committed JWT under the property key testsigma-sdk.api.key must be
removed and rotated: replace the literal value with a reference to an
environment variable or a secret lookup (e.g., read from process.env or your
secret manager) in the code that loads testsigma-sdk.api.key, add this
properties file to .gitignore so it won't be re-committed, rotate/invalidate the
exposed token immediately, and purge it from git history using a tool like git
filter-repo or BFG to ensure the secret is removed from the repository history.
Publish this addon as PUBLIC
Addon Name: If Condition Evaluator
Jarvis Link: https://jarvis.testsigma.com/ui/tenants/3072/addons
Jira : https://testsigma.atlassian.net/browse/CUS-10876
Added If Condition Evaluator action for dynamic IF expressions
Summary by CodeRabbit
Release Notes