@@ -124,6 +124,62 @@ public class SCMRetrieverTest {
124
124
r .assertLogContains ("Library '" + libraryName + "' has been modified in an untrusted revision" , run );
125
125
}
126
126
127
+ @ Test public void libraryCanBeRetrievedStaticallyEvenWhenPipelineScmUntrusted () throws Exception {
128
+ sampleRepo .init ();
129
+ sampleRepo .write ("vars/greet.groovy" , "def call(recipient) {echo(/hello from $recipient/)}" );
130
+ sampleRepo .write ("src/pkg/Clazz.groovy" , "package pkg; class Clazz {static String whereAmI() {'master'}}" );
131
+ sampleRepo .write ("Jenkinsfile" , "greet(pkg.Clazz.whereAmI())" ); // Library loaded implicitly.
132
+ sampleRepo .git ("add" , "vars" , "src" , "Jenkinsfile" );
133
+ sampleRepo .git ("commit" , "--message=init" );
134
+
135
+ sampleRepo .git ("checkout" , "-b" , "fork" );
136
+ sampleRepo .write ("src/pkg/Clazz.groovy" , "package pkg; class Clazz {static String whereAmI() {'fork'}}" );
137
+ sampleRepo .git ("commit" , "--all" , "--message=branching" );
138
+
139
+ WorkflowMultiBranchProject mp = r .jenkins .createProject (WorkflowMultiBranchProject .class , "mp" );
140
+ String libraryName = "stuff" ;
141
+ LibraryConfiguration config = new LibraryConfiguration (libraryName , new SCMSourceRetriever (new GitSCMSource (null , sampleRepo .toString (), "" , "*" , "" , true )));
142
+ config .setDefaultVersion ("master" );
143
+ config .setImplicit (true );
144
+ GlobalLibraries .get ().setLibraries (Collections .singletonList (config ));
145
+
146
+ SCMSource warySource = new WarySource (sampleRepo .toString ());
147
+ mp .getSourcesList ().add (new BranchSource (warySource ));
148
+ WorkflowJob job = WorkflowMultiBranchProjectTest .scheduleAndFindBranchProject (mp , "fork" );
149
+ r .waitUntilNoActivity ();
150
+ WorkflowRun run = job .getLastBuild ();
151
+ // The fork is untrusted, but that doesn't matter because we are using stuff@master, which the untrusted user can't modify.
152
+ r .assertBuildStatus (Result .SUCCESS , run );
153
+ r .assertLogContains ("hello from master" , run );
154
+ }
155
+
156
+ @ Issue ("SECURITY-1951" )
157
+ @ Test public void libraryCantBeRetrievedWithoutVersionUsingScmSourceRetriever () throws Exception {
158
+ sampleRepo .init ();
159
+ sampleRepo .write ("vars/greet.groovy" , "def call(recipient) {echo(/hello to $recipient/)}" );
160
+ sampleRepo .write ("src/pkg/Clazz.groovy" , "package pkg; class Clazz {static String whereAmI() {'master'}}" );
161
+ sampleRepo .write ("Jenkinsfile" , "def lib = library(identifier: 'stuff@master', retriever: modernSCM(fromScm(name: 'master', scm: scm))); greet(lib.pkg.Clazz.whereAmI())" );
162
+ sampleRepo .git ("add" , "vars" , "src" , "Jenkinsfile" );
163
+ sampleRepo .git ("commit" , "--message=init" );
164
+
165
+ sampleRepo .git ("checkout" , "-b" , "fork" );
166
+ sampleRepo .write ("src/pkg/Clazz.groovy" , "package pkg; class Clazz {static String whereAmI() {'fork'}}" );
167
+ sampleRepo .git ("commit" , "--all" , "--message=branching" );
168
+
169
+ WorkflowMultiBranchProject mp = r .jenkins .createProject (WorkflowMultiBranchProject .class , "mp" );
170
+ String libraryName = "stuff" ;
171
+ mp .getProperties ().add (new FolderLibraries (Collections .singletonList (new LibraryConfiguration (libraryName , new SCMSourceRetriever (new GitSCMSource (null , sampleRepo .toString (), "" , "*" , "" , true ))))));
172
+
173
+ SCMSource warySource = new WarySource (sampleRepo .toString ());
174
+ mp .getSourcesList ().add (new BranchSource (warySource ));
175
+ WorkflowJob job = WorkflowMultiBranchProjectTest .scheduleAndFindBranchProject (mp , "fork" );
176
+ r .waitUntilNoActivity ();
177
+ WorkflowRun run = job .getLastBuild ();
178
+
179
+ r .assertBuildStatus (Result .FAILURE , run );
180
+ r .assertLogContains ("Library '" + libraryName + "' has been modified in an untrusted revision" , run );
181
+ }
182
+
127
183
public static class WarySource extends GitSCMSource {
128
184
129
185
public WarySource (String remote ) {
0 commit comments