Skip to content

Commit bb2b446

Browse files
SECURITY-3505
1 parent 0af836f commit bb2b446

File tree

6 files changed

+85
-8
lines changed

6 files changed

+85
-8
lines changed

.github/ISSUE_TEMPLATE/bug-report.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ body:
1919
attributes:
2020
label: JTE Version
2121
description: What version of JTE is installed?
22-
options: [ 2.5.3, 2.5.2, 2.5.1, 2.5, 2.4 , 2.3, 2.2.2, 2.2.1, 2.1, 2.0.4, 2.0.3, 2.0.2, 2.0.1, 2.0, 1.7.1, 1.7, 1.6, 1.5.2, 1.5.1, 1.5, 1.4.2, 1.4.1, 1.4, 1.3, 1.2, 1.1.1, 1.1, 1.0 ]
22+
options: [ 2.5.4, 2.5.3, 2.5.2, 2.5.1, 2.5, 2.4 , 2.3, 2.2.2, 2.2.1, 2.1, 2.0.4, 2.0.3, 2.0.2, 2.0.1, 2.0, 1.7.1, 1.7, 1.6, 1.5.2, 1.5.1, 1.5, 1.4.2, 1.4.1, 1.4, 1.3, 1.2, 1.1.1, 1.1, 1.0 ]
2323
validations:
2424
required: true
2525
- type: textarea

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ repositories {
1414
}
1515

1616
group = 'org.jenkins-ci.plugins'
17-
version = '2.5.3'
17+
version = '2.5.4'
1818
description = 'Allows users to create tool-agnostic, templated pipelines to be shared by multiple teams'
1919

2020
jenkinsPlugin {

src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjector.groovy

+16-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import org.boozallen.plugins.jte.init.governance.config.dsl.PipelineConfiguratio
2121
import org.boozallen.plugins.jte.init.governance.GovernanceTier
2222
import org.boozallen.plugins.jte.init.governance.libs.LibraryProvider
2323
import org.boozallen.plugins.jte.init.governance.libs.LibrarySource
24+
import org.boozallen.plugins.jte.init.governance.TemplateGlobalConfig
2425
import org.boozallen.plugins.jte.init.primitives.TemplatePrimitiveInjector
2526
import org.boozallen.plugins.jte.init.primitives.TemplatePrimitiveNamespace
2627
import org.boozallen.plugins.jte.util.AggregateException
@@ -76,7 +77,15 @@ import org.jenkinsci.plugins.workflow.job.WorkflowJob
7677
@Override
7778
TemplatePrimitiveNamespace injectPrimitives(CpsFlowExecution exec, PipelineConfigurationObject config){
7879
FlowExecutionOwner flowOwner = exec.getOwner()
79-
// fetch library providers and determine library resolution order
80+
81+
// Get global tier libraries first
82+
GovernanceTier globalTier = TemplateGlobalConfig.get().getTier()
83+
Set<LibraryProvider> globalProviders = []
84+
if(globalTier?.getLibrarySources()) {
85+
globalProviders.addAll(globalTier.getLibrarySources().collect { source -> source.getLibraryProvider() } - null)
86+
}
87+
88+
// fetch all library providers and determine library resolution order
8089
List<LibraryProvider> providers = getLibraryProviders(flowOwner)
8190
boolean reverseProviders = config.jteBlockWrapper.reverse_library_resolution
8291
if(reverseProviders) {
@@ -106,8 +115,13 @@ import org.jenkinsci.plugins.workflow.job.WorkflowJob
106115
String includes = "${libName}/${LibraryProvider.STEPS_DIR_NAME}/**/*.groovy"
107116
TemplatePrimitiveNamespace library = new TemplatePrimitiveNamespace(name: libName)
108117
library.setParent(libCollector)
118+
119+
// Find the provider for this library
120+
LibraryProvider provider = providers.find{ p -> p.hasLibrary(flowOwner, libName) }
121+
boolean isSandboxed = !globalProviders.contains(provider)
122+
109123
jteDir.list(includes).each{ stepFile ->
110-
StepWrapper step = stepFactory.createFromFilePath(stepFile, libName, libConfig)
124+
StepWrapper step = stepFactory.createFromFilePath(stepFile, libName, libConfig, isSandboxed)
111125
List<StepAlias> aliases = getStepAliases(step)
112126
if(aliases.isEmpty() || shouldKeepOriginal(aliases)) {
113127
step.setParent(library)

src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/StepWrapper.groovy

+5
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class StepWrapper extends TemplatePrimitive implements Serializable{
7979
protected boolean isLibraryStep = false
8080
protected boolean isDefaultStep = false
8181
protected boolean isTemplateStep = false
82+
protected boolean isSandboxed = true
8283

8384
@SuppressWarnings("UnusedMethodParameter")
8485
Object getValue(CpsScript script, Boolean skipOverloaded = false){
@@ -127,6 +128,10 @@ class StepWrapper extends TemplatePrimitive implements Serializable{
127128
return stepContext.library
128129
}
129130

131+
void setSandboxed(boolean sandboxed){
132+
this.isSandboxed = sandboxed
133+
}
134+
130135
/**
131136
* recompiles the StepWrapperScript if missing. This typically only happens if
132137
* Jenkins has ungracefully restarted and the pipeline is resuming

src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/StepWrapperFactory.groovy

+15-3
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,16 @@ class StepWrapperFactory{
5353
* @param config the library configuration for the step
5454
* @return a StepWrapper instance
5555
*/
56-
StepWrapper createFromFilePath(FilePath filePath, String library, Map config){
56+
StepWrapper createFromFilePath(FilePath filePath, String library, Map config, Boolean isSandboxed){
5757
String name = filePath.getBaseName()
5858
String sourceText = filePath.readToString()
5959
StepContext stepContext = new StepContext(library: library, name: name, isAlias: false)
6060
StepWrapper step = new StepWrapper(
6161
stepContext: stepContext,
6262
config: config,
6363
sourceFile: filePath.absolutize().getRemote(),
64-
isLibraryStep: true
64+
isLibraryStep: true,
65+
isSandboxed: isSandboxed
6566
)
6667
StepWrapperScript script = prepareScript(step, sourceText)
6768
step.setScript(script)
@@ -151,7 +152,12 @@ class StepWrapperFactory{
151152
152153
@groovy.transform.BaseScript ${StepWrapperScript.getName()} _
153154
"""
154-
GroovyShell shell = exec.getTrustedShell()
155+
GroovyShell shell
156+
if (step.isSandboxed){
157+
shell = exec.getShell()
158+
} else {
159+
shell = exec.getTrustedShell()
160+
}
155161
String scriptName = "JTE_${step.library ?: "Default"}_${step.name}"
156162
try {
157163
try {
@@ -212,6 +218,12 @@ class StepWrapperFactory{
212218
}
213219
}
214220

221+
@Override
222+
void customizeImports(CpsFlowExecution execution, ImportCustomizer ic) {
223+
ic.addStarImports("org.boozallen.plugins.jte.init.primitives.hooks")
224+
ic.addImport(StepAlias.getName())
225+
}
226+
215227
GroovyShellDecorator forTrusted(){
216228
return new GroovyShellDecorator() {
217229
@Override

src/test/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjectorSpec.groovy

+47-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class LibraryStepInjectorSpec extends Specification {
148148
jenkins.assertLogContains("folder step", run)
149149
}
150150

151-
def "library on higher governance tier (last in hierarchy array) gets loaded if library override set to false"() {
151+
def "library on higher governance tier last in hierarchy array gets loaded if library override set to false"() {
152152
given:
153153
// add global
154154
TestLibraryProvider lib = new TestLibraryProvider()
@@ -179,4 +179,50 @@ class LibraryStepInjectorSpec extends Specification {
179179
jenkins.assertLogContains("global step", run)
180180
}
181181

182+
def "folder library steps are sandboxed"() {
183+
given:
184+
// add folder
185+
TestLibraryProvider lib2 = new TestLibraryProvider()
186+
lib2.addStep("lib", "step", """
187+
import jenkins.model.Jenkins
188+
void call(){
189+
println Jenkins.get().getRootUrl()
190+
}
191+
""")
192+
Folder folder = jenkins.createProject(Folder)
193+
lib2.addToFolder(folder)
194+
// create job
195+
WorkflowJob job = TestUtil.createAdHocInFolder(folder,
196+
config: 'libraries{ lib }',
197+
template: 'step()'
198+
)
199+
when:
200+
def run = job.scheduleBuild2(0).get()
201+
then:
202+
jenkins.assertBuildStatus(Result.FAILURE, run)
203+
jenkins.assertLogContains("Scripts not permitted to use staticMethod jenkins.model.Jenkins get", run)
204+
}
205+
206+
def "global library steps are not sandboxed"() {
207+
given:
208+
// add folder
209+
TestLibraryProvider lib2 = new TestLibraryProvider()
210+
lib2.addStep("lib", "step", """
211+
import jenkins.model.Jenkins
212+
void call(){
213+
println Jenkins.get().getRootUrl()
214+
}
215+
""")
216+
lib2.addGlobally()
217+
// create job
218+
WorkflowJob job = TestUtil.createAdHoc(jenkins,
219+
config: 'libraries{ lib }',
220+
template: 'step()'
221+
)
222+
when:
223+
def run = job.scheduleBuild2(0).get()
224+
then:
225+
jenkins.assertBuildStatusSuccess(run)
226+
}
227+
182228
}

0 commit comments

Comments
 (0)