feat(security): default-off kill-switch for user-generated dynamic code execution#2860
Merged
simonredfern merged 3 commits intoJul 13, 2026
Merged
Conversation
DynamicUtil.compileScalaCode, createJsFunction and createJavaFunction compile and execute user-supplied Scala/JS/Java with no sandbox on JDK 24+ (SecurityManager removal, JEP 486) and GraalVM contexts built with HostAccess.ALL, so any bank-level entitlement holder able to reach one of the dynamic-code management endpoints could achieve RCE. Adopt the existing but previously unused allow_user_generated_scala_code prop as the master switch, defaulting to off. compileScalaCode is split into a guarded public entry point and an unchecked variant used only by DynamicUtil.Validation's own props-driven config parsing, so operator config still compiles and the app boots with the switch off.
…h the kill-switch Add an early check to the create/update endpoints for connector methods, dynamic resource docs, dynamic message docs and ABAC rules so a disabled instance returns a clean 400 (OBP-50020) instead of surfacing the compile failure further down the stack. Dynamic Entities and Swagger Dynamic Endpoints are intentionally left unguarded since they never compile or execute user-supplied code. Document the prop in sample.props.template with the security rationale, and add DynamicCodeKillSwitchTest covering the predicate directly, each guarded endpoint on/off, and a regression check that Dynamic Entities stay unaffected.
|
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
DynamicUtil(Dynamic Resource Docs, Connector Methods, Dynamic Message Docs, ABAC Rules) runs with no effective sandbox and no way for an operator to disable it. Two runtime facts make this worse than it looks:SecurityManagerwas removed in JDK 24+ (JEP 486);Sandbox.runInSandboxis now a pass-through with no permission enforcement.createJsFunctionis built withallowHostAccess(HostAccess.ALL)andallowHostClassLookup(_ => true), i.e. full host access.allow_user_generated_scala_codeprop.DynamicUtil.dynamicCodeExecutionEnabledresolves it with explicit-prop-wins semantics; absent the prop it's on in test/dev and off in production.compileScalaCodeis split into a guarded public entry point and a privatecompileScalaCodeUncheckedused only byDynamicUtil.Validation's own props-driven config parsing (operator config, not user code) — otherwise the app would fail to boot with the switch off, since that parsing happens at object-init time.Http4s400.scala,Http4s600.scala) so a disabled instance returns a clean400 OBP-50020instead of surfacing a downstream compile failure.sample.props.template.Test plan
mvn install -pl .,obp-commons -am -DskipTests— BUILD SUCCESSmvn test-compile -pl obp-api -am— main + test sources compile cleanDynamicCodeKillSwitchTest: predicate on/off, each of the three guarded endpoint chokepoints on/off, and a Dynamic Entity regression check (unaffected when the switch is off)testMode:DynamicUtilTest,ConnectorMethodTest,AbacRuleTests,DynamicResourceDocTest,DynamicMessageDocTest,ResourceDocsTest— 114 succeeded, 0 failed (3 canceled are pre-existing JDK24+SecurityManager-unavailable skips, unrelated to this change)git grep -n 'allow_user_generated_scala_code' obp-api/srcconfirms the prop is now read in code and documented