@@ -1835,22 +1835,17 @@ public void setup()
18351835 @ Test
18361836 public void testScriptContainerScoping () throws Exception
18371837 {
1838- // A flow script that lives in folder B .
1838+ // GitHub Issue #1892: Regression test for FLOW-1 .
18391839 FlowScript script = FlowScript .create (_admin , _folderB , "scope-test" ,
18401840 "<script xmlns=\" http://www.labkey.org/data/xml/flowScript\" />" );
18411841 int scriptId = script .getScriptId ();
18421842
1843- // DownloadAction resolves the script through EditScriptForm; dispatch it against folder A while pointing
1844- // scriptId at B's script -- the FLOW-1 attack shape (reaching a script that lives in another folder).
18451843 ActionURL foreignUrl = new ActionURL (ScriptController .DownloadAction .class , _folderA )
18461844 .addParameter (FlowParam .scriptId .toString (), scriptId );
18471845
18481846 User readerAonly = createUserInRole (_folderA , ReaderRole .class );
18491847 assertStatus (HttpServletResponse .SC_NOT_FOUND , get (foreignUrl , readerAonly ));
18501848
1851- // Redirect branch: a caller who can read both folders is redirected to B (where its own permissions are
1852- // re-enforced) instead of being served B's script from A's context. This is the core vulnerability:
1853- // without checkContainer() in EditScriptForm.reset() the action streams B's script from folder A (200).
18541849 User readerAreaderB = createUserInRole (_folderA , ReaderRole .class );
18551850 grantRole (readerAreaderB , _folderB , ReaderRole .class );
18561851 MockHttpServletResponse resp = get (foreignUrl , readerAreaderB );
@@ -1868,22 +1863,16 @@ public void testScriptContainerScoping() throws Exception
18681863 @ Test
18691864 public void testProtocolContainerScoping () throws Exception
18701865 {
1871- // Regression test for FLOW-2. A FlowProtocol is accessed by a global experimentId.
1872- // A flow protocol that lives in folder B.
1866+ // GitHub Issue #1892: Regression test for FLOW-2. A FlowProtocol is accessed by a global experimentId.
18731867 FlowProtocol protocolB = FlowProtocol .ensureForContainer (_admin , _folderB );
18741868 int experimentId = protocolB .getProtocol ().getRowId ();
18751869
1876- // EditFCSAnalysisFilter is an UpdatePermission action; dispatch it against folder A while pointing
1877- // experimentId at B's protocol -- the FLOW-2 attack shape (editor in A reaching a protocol in B).
18781870 ActionURL foreignUrl = new ActionURL (ProtocolController .EditFCSAnalysisFilterAction .class , _folderA )
18791871 .addParameter (FlowParam .experimentId .toString (), experimentId );
18801872
18811873 User editorAonly = createUserInRole (_folderA , EditorRole .class );
18821874 assertStatus (HttpServletResponse .SC_NOT_FOUND , get (foreignUrl , editorAonly ));
18831875
1884- // Redirect branch: a caller who can edit folder A and read folder B is redirected to B (where its own
1885- // permissions are re-enforced) instead of operating on B's protocol from A's context. This is the core
1886- // vulnerability: without checkContainer() in fromURL() the action proceeds in folder A (HTTP 200).
18871876 User editorAreaderB = createUserInRole (_folderA , EditorRole .class );
18881877 grantRole (editorAreaderB , _folderB , ReaderRole .class );
18891878 MockHttpServletResponse resp = get (foreignUrl , editorAreaderB );
@@ -1901,7 +1890,7 @@ public void testProtocolContainerScoping() throws Exception
19011890 @ Test
19021891 public void testExportAnalysisContainerScoping () throws Exception
19031892 {
1904- // Regression test for FLOW-3 RunController.ExportAnalysis resolves
1893+ // GitHub Issue #1892: Regression test for FLOW-3. RunController.ExportAnalysis resolves
19051894 // URL supplied runId/wellId via the global FlowRun.
19061895 ExpData data = ExperimentService .get ().createData (_folderB , FlowDataType .FCSFile , "scope-test-well" );
19071896 URI dataFileURI = new URI ("file:///attributes.flowdata.xml" );
@@ -1912,18 +1901,12 @@ public void testExportAnalysisContainerScoping() throws Exception
19121901 AttributeSetHelper .save (attrs , _admin , data );
19131902 int wellId = data .getRowId ();
19141903
1915- // Point wellId at B's well while dispatching the export against folder A -- the FLOW-3 attack shape.
19161904 ActionURL foreignUrl = new ActionURL (RunController .ExportAnalysis .class , _folderA )
19171905 .addParameter (FlowParam .wellId .toString (), wellId );
19181906
1919- // Deny branch: a caller who can read folder A but has no rights in folder B must not learn B's well exists,
1920- // nor export it -> 404.
19211907 User readerAonly = createUserInRole (_folderA , ReaderRole .class );
19221908 assertStatus (HttpServletResponse .SC_NOT_FOUND , post (foreignUrl , readerAonly ));
19231909
1924- // Redirect branch: a caller who can read both folders is redirected to B (where its own permissions are
1925- // re-enforced) instead of having B's well exported from A's context. This is the core vulnerability: without
1926- // checkContainer() in validateCommand() the action exports B's well from folder A.
19271910 User readerAreaderB = createUserInRole (_folderA , ReaderRole .class );
19281911 grantRole (readerAreaderB , _folderB , ReaderRole .class );
19291912 MockHttpServletResponse resp = post (foreignUrl , readerAreaderB );
@@ -1940,8 +1923,8 @@ public void testExportAnalysisContainerScoping() throws Exception
19401923 @ Test
19411924 public void testRunDownloadContainerScoping () throws Exception
19421925 {
1943- // Regression test for FLOW-4. RunController.DownloadAction (and
1944- // DownloadAttachmentAction) resolve a run via RunForm.getRun() -> FlowRun.fromRunId() from a global runId
1926+ // GitHub Issue #1892: Regression test for FLOW-4. RunController.DownloadAction (and
1927+ // DownloadAttachmentAction) resolve a run via RunForm.getRun() -> FlowRun.fromRunId() from a global runId.
19451928 FlowProtocol protocolB = FlowProtocol .ensureForContainer (_admin , _folderB );
19461929 ExpRun expRun = ExperimentService .get ().createExperimentRun (_folderB , "scope-test-run" );
19471930 expRun .setProtocol (protocolB .getProtocol ());
@@ -1954,9 +1937,6 @@ public void testRunDownloadContainerScoping() throws Exception
19541937 User readerAonly = createUserInRole (_folderA , ReaderRole .class );
19551938 assertStatus (HttpServletResponse .SC_NOT_FOUND , get (foreignUrl , readerAonly ));
19561939
1957- // Redirect branch: a caller who can read both folders is redirected to B (where its own permissions are
1958- // re-enforced) instead of having B's run streamed from A's context. This is the core vulnerability: without
1959- // checkContainer() in DownloadAction.validate() the action streams B's run from folder A.
19601940 User readerAreaderB = createUserInRole (_folderA , ReaderRole .class );
19611941 grantRole (readerAreaderB , _folderB , ReaderRole .class );
19621942 MockHttpServletResponse resp = get (foreignUrl , readerAreaderB );
0 commit comments