CVE-2022-39208 (XML, published 2022-09-13T19:15Z)
Description: value: 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.
Severity: nan (CVSS v3 base score: 7.5)
Weakness: CWE-552 \u2014 Files or Directories Accessible to External Parties
The product makes files or directories accessible to unauthorized actors, even though they should not be.
Repository: https://github.com/theonedev/onedev
Files changed:
pom.xml
server-core/pom.xml
server-core/src/main/java/io/onedev/server/maintenance/Upgrade.java
server-core/src/main/java/io/onedev/server/web/avatar/DefaultAvatarManager.java
server-core/src/main/java/io/onedev/server/web/component/brandlogo/BrandLogoPanel.java
server-core/src/main/java/io/onedev/server/web/page/admin/brandingsetting/BrandingSettingPage.java
server-plugin/pom.xml
server-plugin/server-plugin-archetype/pom.xml
server-plugin/server-plugin-authenticator-ldap/pom.xml
server-plugin/server-plugin-buildspec-gradle/pom.xml
server-plugin/server-plugin-buildspec-maven/pom.xml
server-plugin/server-plugin-buildspec-node/pom.xml
server-plugin/server-plugin-executor-kubernetes/pom.xml
server-plugin/server-plugin-executor-remotedocker/pom.xml
server-plugin/server-plugin-executor-remoteshell/pom.xml
server-plugin/server-plugin-executor-serverdocker/pom.xml
server-plugin/server-plugin-executor-servershell/pom.xml
server-plugin/server-plugin-import-bitbucketcloud/pom.xml
server-plugin/server-plugin-import-gitea/pom.xml
server-plugin/server-plugin-import-github/pom.xml
server-plugin/server-plugin-import-gitlab/pom.xml
server-plugin/server-plugin-import-jiracloud/pom.xml
server-plugin/server-plugin-import-youtrack/pom.xml
server-plugin/server-plugin-report-checkstyle/pom.xml
server-plugin/server-plugin-report-clover/pom.xml
server-plugin/server-plugin-report-coverage/pom.xml
server-plugin/server-plugin-report-cpd/pom.xml
server-plugin/server-plugin-report-jacoco/pom.xml
server-plugin/server-plugin-report-jest/pom.xml
server-plugin/server-plugin-report-junit/pom.xml
server-plugin/server-plugin-report-markdown/pom.xml
server-plugin/server-plugin-report-pmd/pom.xml
server-plugin/server-plugin-report-problem/pom.xml
server-plugin/server-plugin-report-spotbugs/pom.xml
server-plugin/server-plugin-report-unittest/pom.xml
server-plugin/server-plugin-sso-discord/pom.xml
server-plugin/server-plugin-sso-openid/pom.xml
server-product/pom.xml
server-product/src/main/java/io/onedev/server/product/ProductServletConfigurator.java
Commit message: Fix security vulnerability issue regarding site/* access


Vulnerable code:
	<version>7.2.9</version>
		<version>7.2.9</version>
		
		for (File file: new File(Bootstrap.getSiteDir(), "avatars").listFiles()) {
					FileUtils.copyFileToDirectory(file, new File(upgradeDir, "site/avatars"));
		File uploadedDir = new File(upgradeDir, "site/avatars/uploaded");
		File avatarFile = new File(Bootstrap.getSiteDir(), "avatars/generated/" + encoded + ".png");
		return new File(Bootstrap.getSiteDir(), "avatars/uploaded/users/" + user.getId() + ".jpg");
		return new File(Bootstrap.getSiteDir(), "avatars/uploaded/projects/" + projectId + ".jpg");
		return new File(Bootstrap.getSiteDir(), "logo.png");
		return new File(Bootstrap.getSiteDir(), "logo.png");
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		<version>7.2.9</version>
		ServletHolder fileServletHolder = new ServletHolder(new FileAssetServlet(Bootstrap.getSiteDir()));

Fixed code:
	<version>7.3.0</version>
		<version>7.3.0</version>

		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()) {
					FileUtils.copyFileToDirectory(file, new File(upgradeDir, "site/assets/avatars"));
		File uploadedDir = new File(upgradeDir, "site/assets/avatars/uploaded");
		File avatarFile = new File(Bootstrap.getSiteDir(), "assets/avatars/generated/" + encoded + ".png");
		return new File(Bootstrap.getSiteDir(), "assets/avatars/uploaded/users/" + user.getId() + ".jpg");
		return new File(Bootstrap.getSiteDir(), "assets/avatars/uploaded/projects/" + projectId + ".jpg");
		return new File(Bootstrap.getSiteDir(), "assets/logo.png");
		return new File(Bootstrap.getSiteDir(), "assets/logo.png");
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
		<version>7.3.0</version>
import java.io.File;
		File assetsDir = new File(Bootstrap.getSiteDir(), "assets");
		ServletHolder fileServletHolder = new ServletHolder(new FileAssetServlet(assetsDir));