Vulnerability: Limited Authentication Bypass for Media Files Prior to Opencast 10.14 and 11.7, users could pass along URLs for files belonging to organizations other than the user's own, which Opencast would then import into the current organization, bypassing organizational barriers.

### Impact

The vulnerability allows attackers to bypass organizational barriers. Attackers must have full access to Opencast's ingest REST interface, and also know internal links to resources in another organization of the same Opencast cluster.

If you do not run a multi-tenant cluster, you are not affected by this issue.

### Patches

This issue is fixed in Opencast 10.14 and 11.7.

### References

- [Patch fixing the issue](https://github.com/opencast/opencast/commit/8d5ec1614eed109b812bc27b0c6d3214e456d4e7)

### For more information

If you have any questions or comments about this advisory:
* Open an issue in [our issue tracker](https://github.com/opencast/opencast/issues)
* Email us at [security@opencast.org](mailto:security@opencast.org)
Vulnerability ID: GHSA-qm6v-cg9v-53j3
CWE: CWE-287
Severity score: 5.4
Project: https://github.com/opencast/opencast
Published: 2022-05-25
File: modules/ingest-service-impl/src/main/java/org/opencastproject/ingest/impl/IngestServiceImpl.java
Commit message: Merge pull request from GHSA-qm6v-cg9v-53j3

This patch fixes the issue that users can pass URLs from other tenants
to the ingest service which will check only against the other
organization but not against the one currently active. This allows users
to easily ingest media from other tenants.
Commit author: Lars Kiesow

Vulnerable version (before fix):
 import java.util.Dictionary; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors;  import javax.management.ObjectInstance;  protected URI addContentToRepo(MediaPackage mp, String elementId, URI uri) throw     try {       if (uri.toString().startsWith("http")) {         HttpGet get = new HttpGet(uri);         List<String> clusterUrls = new LinkedList<>();         try {           // Note that we are not checking ports here.           clusterUrls = organizationDirectoryService.getOrganization(uri.toURL()).getServers()                           .keySet()                           .stream()                           .collect(Collectors.toUnmodifiableList());         } catch (NotFoundException e) {           logger.warn("Unable to determine cluster members, will not be able to authenticate any downloads from them", e);         }          if (uri.toString().matches(downloadSource)) {           //NB: We're creating a new client here with *different* auth than the system auth creds

Fixed version (after fix):
 import java.util.Dictionary; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.concurrent.TimeUnit;  import javax.management.ObjectInstance;  protected URI addContentToRepo(MediaPackage mp, String elementId, URI uri) throw     try {       if (uri.toString().startsWith("http")) {         HttpGet get = new HttpGet(uri);         var clusterUrls = securityService.getOrganization().getServers().keySet();          if (uri.toString().matches(downloadSource)) {           //NB: We're creating a new client here with *different* auth than the system auth creds

Patch:
patch: @@ -129,15 +129,13 @@
 import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
 import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
 
 import javax.management.ObjectInstance;
 
@@ -1568,16 +1566,7 @@ protected URI addContentToRepo(MediaPackage mp, String elementId, URI uri) throw
     try {
       if (uri.toString().startsWith("http")) {
         HttpGet get = new HttpGet(uri);
-        List<String> clusterUrls = new LinkedList<>();
-        try {
-          // Note that we are not checking ports here.
-          clusterUrls = organizationDirectoryService.getOrganization(uri.toURL()).getServers()
-                          .keySet()
-                          .stream()
-                          .collect(Collectors.toUnmodifiableList());
-        } catch (NotFoundException e) {
-          logger.warn("Unable to determine cluster members, will not be able to authenticate any downloads from them", e);
-        }
+        var clusterUrls = securityService.getOrganization().getServers().keySet();
 
         if (uri.toString().matches(downloadSource)) {
           //NB: We're creating a new client here with *different* auth than the system auth creds
path: modules/ingest-service-impl/src/main/java/org/opencastproject/ingest/impl/IngestServiceImpl.java