CVE-2022-39208 (published 2022-09-13T19:15Z)

Onedev is an open source, self-hosted Git Server with CI/CD and Kanban. All files in the /opt/onedev/sites/ directory are exposed and can be read by unauthenticated users. This directory contains all projects, including their bare git repos and build artifacts. This file disclosure vulnerability can be used by unauthenticated attackers to leak all project files of any project. Since project IDs are incremental, an attacker could iterate through them and leak all project data. This issue has been resolved in version 7.3.0 and users are advised to upgrade. There are no known workarounds for this issue.

CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)

Weakness information:
cwe_id: CWE-552
cwe_name: Files or Directories Accessible to External Parties
description: The product makes files or directories accessible to unauthorized actors, even though they should not be.
extended_description: 
	   Web servers, FTP servers, and similar servers may store a set of files underneath a "root" directory that is accessible to the server's users.  Applications may store sensitive files underneath this root without also using access control to limit which users may request those files, if any.  Alternately, an application might package multiple files or directories into an archive file (e.g., ZIP or tar), but the application might not exclude sensitive files that are underneath those directories.
	   In cloud technologies and containers, this weakness might present itself in the form of misconfigured storage accounts that can be read or written by a public or anonymous user.
	 
         

Fix information:
repo_url: https://github.com/theonedev/onedev
commit_details: repo_url: https://github.com/theonedev/onedev
author: Robin Shen
author_date: 2022-05-30 20:58:18+08:00
msg: Fix security vulnerability issue regarding site/* access
repository: repo_url: https://github.com/theonedev/onedev
repo_name: theonedev/onedev
description: Git Server with CI/CD, Kanban, and Packages. Seamless integration. Unparalleled experience.
repo_language: Java
owner: theonedev
file_changes: filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -9,7 +9,7 @@
 		<version>1.0.5</version>
 	</parent>
 	<artifactId>server</artifactId>
-	<version>7.2.9</version>
+	<version>7.3.0</version>
 	<packaging>pom</packaging>
 	<build>
 		<finalName>${project.groupId}.${project.artifactId}-${project.version}</finalName>

programming_language: HTML
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -7,7 +7,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<build>
 		<plugins>

programming_language: HTML
filename: Upgrade.java
change_type: ModificationType.MODIFY
diff: @@ -487,17 +487,48 @@ public class Upgrade extends DefaultPersistManager {
 			FileUtils.deleteFile(new File(upgradeDir, "boot/system.classpath"));
 		
 		cleanAndCopy(Bootstrap.getLibDir(), new File(upgradeDir, "lib"));
-		
-		for (File file: new File(Bootstrap.getSiteDir(), "avatars").listFiles()) {
+
+		FileUtils.createDir(new File(upgradeDir, "site/assets"));
+		if (new File(upgradeDir, "site/robots.txt").exists()) {
+			try {
+				FileUtils.copyFile(
+						new File(upgradeDir, "site/robots.txt"), 
+						new File(upgradeDir, "site/assets/robots.txt"));
+				FileUtils.deleteFile(new File(upgradeDir, "site/robots.txt"));
+			} catch (IOException e) {
+				throw new RuntimeException(e);
+			}
+		}
+		if (new File(upgradeDir, "site/logo.png").exists()) {
+			try {
+				FileUtils.copyFile(
+						new File(upgradeDir, "site/logo.png"), 
+						new File(upgradeDir, "site/assets/logo.png"));
+				FileUtils.deleteFile(new File(upgradeDir, "site/logo.png"));
+			} catch (IOException e) {
+				throw new RuntimeException(e);
+			}
+		}
+		if (new File(upgradeDir, "site/avatars").exists()) {
+			try {
+				FileUtils.copyDirectory(
+						new File(upgradeDir, "site/avatars"), 
+						new File(upgradeDir, "site/assets/avatars"));
+				FileUtils.deleteDir(new File(upgradeDir, "site/avatars"));
+			} catch (IOException e) {
+				throw new RuntimeException(e);
+			}
+		}
+		for (File file: new File(Bootstrap.getSiteDir(), "assets/avatars").listFiles()) {
 			if (file.isFile()) {
 				try {
-					FileUtils.copyFileToDirectory(file, new File(upgradeDir, "site/avatars"));
+					FileUtils.copyFileToDirectory(file, new File(upgradeDir, "site/assets/avatars"));
 				} catch (IOException e) {
 					throw new RuntimeException(e);
 				}
 			}
 		}
-		File uploadedDir = new File(upgradeDir, "site/avatars/uploaded");
+		File uploadedDir = new File(upgradeDir, "site/assets/avatars/uploaded");
 		File userUploadsDir = new File(uploadedDir, "users"); 
 		if (uploadedDir.exists() && !userUploadsDir.exists()) {
 			FileUtils.createDir(userUploadsDir);

programming_language: Java
filename: DefaultAvatarManager.java
change_type: ModificationType.MODIFY
diff: @@ -93,7 +93,7 @@ public class DefaultAvatarManager implements AvatarManager {
 		if (StringUtils.isBlank(secondaryName))
 			secondaryName = primaryName;
 		
-		File avatarFile = new File(Bootstrap.getSiteDir(), "avatars/generated/" + encoded + ".png");
+		File avatarFile = new File(Bootstrap.getSiteDir(), "assets/avatars/generated/" + encoded + ".png");
 		if (!avatarFile.exists()) {
 			Lock avatarLock = LockUtils.getLock("generated-avatar:" + encoded);
 			avatarLock.lock();
@@ -129,7 +129,7 @@ public class DefaultAvatarManager implements AvatarManager {
 	
 	@Override
 	public File getUploaded(User user) {
-		return new File(Bootstrap.getSiteDir(), "avatars/uploaded/users/" + user.getId() + ".jpg");
+		return new File(Bootstrap.getSiteDir(), "assets/avatars/uploaded/users/" + user.getId() + ".jpg");
 	}
 
 	@Sessional
@@ -170,7 +170,7 @@ public class DefaultAvatarManager implements AvatarManager {
 
 	@Override
 	public File getUploaded(Long projectId) {
-		return new File(Bootstrap.getSiteDir(), "avatars/uploaded/projects/" + projectId + ".jpg");
+		return new File(Bootstrap.getSiteDir(), "assets/avatars/uploaded/projects/" + projectId + ".jpg");
 	}
 
 	@Override

programming_language: Java
filename: BrandLogoPanel.java
change_type: ModificationType.MODIFY
diff: @@ -18,7 +18,7 @@ public class BrandLogoPanel extends Panel {
 	}
 
 	private File getCustomLogoFile() {
-		return new File(Bootstrap.getSiteDir(), "logo.png");
+		return new File(Bootstrap.getSiteDir(), "assets/logo.png");
 	}
 	
 	@Override

programming_language: Java
filename: BrandingSettingPage.java
change_type: ModificationType.MODIFY
diff: @@ -33,7 +33,7 @@ public class BrandingSettingPage extends AdministrationPage {
 	}
 	
 	private File getLogoFile() {
-		return new File(Bootstrap.getSiteDir(), "logo.png");
+		return new File(Bootstrap.getSiteDir(), "assets/logo.png");
 	}
 
 	@Override

programming_language: Java
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -6,7 +6,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<dependencies>
 		<dependency>

programming_language: TypeScript
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -6,7 +6,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<build>
 		<resources>

programming_language: HTML
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.authenticator.ldap.LdapModule</moduleClass>

programming_language: Markdown
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.buildspec.gradle.GradleModule</moduleClass>

programming_language: SQL
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.buildspec.maven.MavenModule</moduleClass>

programming_language: SQL
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.buildspec.node.NodePluginModule</moduleClass>

programming_language: CoffeeScript
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -6,7 +6,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.executor.kubernetes.KubernetesModule</moduleClass>

programming_language: CoffeeScript
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<dependencies>
 		<dependency>

programming_language: HTML
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<dependencies>
 		<dependency>

programming_language: SQL
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.executor.serverdocker.ServerDockerModule</moduleClass>

programming_language: Markdown
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.executor.servershell.ServerShellModule</moduleClass>

programming_language: SQL
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.imports.bitbucketcloud.BitbucketPluginModule</moduleClass>

programming_language: CoffeeScript
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.imports.gitea.GiteaPluginModule</moduleClass>

programming_language: CoffeeScript
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.imports.github.GitHubPluginModule</moduleClass>

programming_language: CoffeeScript
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.imports.gitlab.GitLabPluginModule</moduleClass>

programming_language: SQL
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.imports.jiracloud.JiraPluginModule</moduleClass>

programming_language: CoffeeScript
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.imports.youtrack.YouTrackPluginModule</moduleClass>

programming_language: CoffeeScript
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<dependencies>
 		<dependency>

programming_language: SQL
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<dependencies>
 		<dependency>

programming_language: HTML
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.report.coverage.CoverageReportModule</moduleClass>

programming_language: SQL
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<dependencies>
 		<dependency>

programming_language: SQL
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<dependencies>
 		<dependency>

programming_language: HTML
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<dependencies>
 		<dependency>

programming_language: HTML
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<dependencies>
 		<dependency>

programming_language: HTML
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.report.markdown.MarkdownReportModule</moduleClass>

programming_language: Markdown
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<dependencies>
 		<dependency>

programming_language: HTML
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.report.problem.ProblemReportModule</moduleClass>

programming_language: SQL
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<dependencies>
 		<dependency>

programming_language: HTML
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.report.unittest.UnitTestReportModule</moduleClass>

programming_language: SQL
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<properties>
 		<moduleClass>io.onedev.server.plugin.sso.discord.DiscordModule</moduleClass>

programming_language: SQL
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -6,7 +6,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server-plugin</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<dependencies>
 		<dependency>

programming_language: HTML
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -7,7 +7,7 @@
 	<parent>
 		<groupId>io.onedev</groupId>
 		<artifactId>server</artifactId>
-		<version>7.2.9</version>
+		<version>7.3.0</version>
 	</parent>
 	<dependencies>
 		<dependency>

programming_language: HTML
filename: ProductServletConfigurator.java
change_type: ModificationType.MODIFY
diff: @@ -1,5 +1,6 @@
 package io.onedev.server.product;
 
+import java.io.File;
 import java.util.EnumSet;
 
 import javax.inject.Inject;
@@ -119,8 +120,10 @@ public class ProductServletConfigurator implements ServletConfigurator {
 		 * Configure a servlet to serve contents under site folder. Site folder can be used 
 		 * to hold site specific web assets.   
 		 */
-		ServletHolder fileServletHolder = new ServletHolder(new FileAssetServlet(Bootstrap.getSiteDir()));
+		File assetsDir = new File(Bootstrap.getSiteDir(), "assets");
+		ServletHolder fileServletHolder = new ServletHolder(new FileAssetServlet(assetsDir));
 		context.addServlet(fileServletHolder, "/site/*");
+		
 		context.addServlet(fileServletHolder, "/robots.txt");
 		
 		context.addServlet(new ServletHolder(jerseyServlet), "/api/*");	

programming_language: Java