VYPR
Medium severity5.8OSV Advisory· Published Jul 1, 2025· Updated Apr 15, 2026

CVE-2025-53103

CVE-2025-53103

Description

JUnit is a testing framework for Java and the JVM. From version 5.12.0 to 5.13.1, JUnit's support for writing Open Test Reporting XML files can leak Git credentials. The impact depends on the level of the access token exposed through the OpenTestReportGeneratingListener. If these test reports are published or stored anywhere public, then there is the possibility that a rouge attacker can steal the token and perform elevated actions by impersonating the user or app. This issue as been patched in version 5.13.2.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.junit.platform:junit-platform-reportingMaven
>= 5.12.0, < 5.13.25.13.2

Affected products

1

Patches

2
d4fc834c8c1c

Merge commit from fork

https://github.com/junit-team/junit-frameworkMarc PhilippJun 24, 2025via ghsa
7 files changed · +313 112
  • documentation/documentation.gradle.kts+1 0 modified
    @@ -161,6 +161,7 @@ tasks {
     		args.addAll("execute")
     		args.addAll("--scan-classpath")
     		args.addAll("--config=junit.platform.reporting.open.xml.enabled=true")
    +		args.addAll("--config=junit.platform.reporting.open.xml.git.enabled=true")
     		args.addAll("--config=junit.platform.output.capture.stdout=true")
     		args.addAll("--config=junit.platform.output.capture.stderr=true")
     		args.addAll("--config=junit.platform.discovery.issue.severity.critical=info")
    
  • documentation/src/docs/asciidoc/release-notes/release-notes-5.13.2.adoc+5 1 modified
    @@ -21,7 +21,11 @@ repository on GitHub.
     [[release-notes-5.13.2-junit-platform-deprecations-and-breaking-changes]]
     ==== Deprecations and Breaking Changes
     
    -* ❓
    +* Including information about the Git repository (such as the commit hash and branch name)
    +  in the Open Test Reporting XML format is now an opt-in feature that can be enabled via a
    +  configuration parameter. Please refer to the
    +  <<../user-guide/index.adoc#junit-platform-reporting-open-test-reporting, User Guide>>
    +  for details.
     
     [[release-notes-5.13.2-junit-platform-new-features-and-improvements]]
     ==== New Features and Improvements
    
  • documentation/src/docs/asciidoc/user-guide/advanced-topics/junit-platform-reporting.adoc+4 2 modified
    @@ -36,10 +36,12 @@ event-based format specified by {OpenTestReporting} which supports all features
     JUnit Platform such as hierarchical test structures, display names, tags, etc.
     
     The listener is auto-registered and can be configured via the following
    -<<running-tests-config-params, configuration parameter>>:
    +<<running-tests-config-params, configuration parameters>>:
     
     `junit.platform.reporting.open.xml.enabled=true|false`::
    -  Enable/disable writing the report.
    +  Enable/disable writing the report; defaults to `false`.
    +`junit.platform.reporting.open.xml.git.enabled=true|false`::
    +  Enable/disable including information about the Git repository (see https://github.com/ota4j-team/open-test-reporting#git[Git extension schema] of open-test-reporting); defaults to `false`.
     
     If enabled, the listener creates an XML report file named `open-test-report.xml` in the
     configured <<junit-platform-reporting-output-directory, output directory>>.
    
  • gradle/plugins/common/src/main/kotlin/junitbuild.testing-conventions.gradle.kts+1 0 modified
    @@ -130,6 +130,7 @@ tasks.withType<Test>().configureEach {
     	jvmArgumentProviders += CommandLineArgumentProvider {
     		listOf(
     			"-Djunit.platform.reporting.open.xml.enabled=true",
    +			"-Djunit.platform.reporting.open.xml.git.enabled=true",
     			"-Djunit.platform.reporting.output.dir=${reports.junitXml.outputLocation.get().asFile.absolutePath}/junit-{uniqueNumber}",
     		)
     	}
    
  • junit-platform-reporting/src/main/java/org/junit/platform/reporting/open/xml/GitInfoCollector.java+209 0 added
    @@ -0,0 +1,209 @@
    +/*
    + * Copyright 2015-2025 the original author or authors.
    + *
    + * All rights reserved. This program and the accompanying materials are
    + * made available under the terms of the Eclipse Public License v2.0 which
    + * accompanies this distribution and is available at
    + *
    + * https://www.eclipse.org/legal/epl-v20.html
    + */
    +
    +package org.junit.platform.reporting.open.xml;
    +
    +import java.io.BufferedReader;
    +import java.io.IOException;
    +import java.io.InputStream;
    +import java.io.InputStreamReader;
    +import java.io.Reader;
    +import java.io.UncheckedIOException;
    +import java.net.URI;
    +import java.net.URISyntaxException;
    +import java.nio.charset.Charset;
    +import java.nio.file.Path;
    +import java.util.Optional;
    +import java.util.concurrent.TimeUnit;
    +import java.util.function.BiConsumer;
    +
    +import org.junit.platform.commons.util.ExceptionUtils;
    +import org.junit.platform.commons.util.StringUtils;
    +
    +/**
    + * @since 5.13.2
    + */
    +interface GitInfoCollector {
    +
    +	static Optional<GitInfoCollector> get(Path workingDir) {
    +		ProcessExecutor executor = new ProcessExecutor(workingDir);
    +		boolean gitInstalled = executor.exec("git", "--version").isPresent();
    +		return gitInstalled ? Optional.of(new CliGitInfoCollector(executor)) : Optional.empty();
    +	}
    +
    +	Optional<String> getOriginUrl();
    +
    +	Optional<String> getBranch();
    +
    +	Optional<String> getCommitHash();
    +
    +	Optional<String> getStatus();
    +
    +	class CliGitInfoCollector implements GitInfoCollector {
    +
    +		private static final String ALLOWED_USERNAME = "git";
    +		private static final String USER_INFO_REPLACEMENT = "***";
    +		private static final String USER_INFO_SEPARATOR = "@";
    +
    +		private final ProcessExecutor executor;
    +
    +		public CliGitInfoCollector(ProcessExecutor executor) {
    +			this.executor = executor;
    +		}
    +
    +		@Override
    +		public Optional<String> getOriginUrl() {
    +			return executor.exec("git", "config", "--get", "remote.origin.url") //
    +					.filter(StringUtils::isNotBlank) //
    +					.flatMap(this::toGitUrl) //
    +					.flatMap(this::obfuscateUserInfo);
    +		}
    +
    +		@Override
    +		public Optional<String> getBranch() {
    +			return executor.exec("git", "rev-parse", "--abbrev-ref", "HEAD") //
    +					.filter(StringUtils::isNotBlank);
    +		}
    +
    +		@Override
    +		public Optional<String> getCommitHash() {
    +			return executor.exec("git", "rev-parse", "--verify", "HEAD") //
    +					.filter(StringUtils::isNotBlank);
    +		}
    +
    +		@Override
    +		public Optional<String> getStatus() {
    +			return executor.exec("git", "status", "--porcelain");
    +		}
    +
    +		private Optional<String> obfuscateUserInfo(GitUrl gitUrl) {
    +			try {
    +				if (gitUrl.uri.getUserInfo() != null) {
    +					URI newUri = new URI(gitUrl.uri.getScheme(), USER_INFO_REPLACEMENT, gitUrl.uri.getHost(),
    +						gitUrl.uri.getPort(), gitUrl.uri.getPath(), gitUrl.uri.getQuery(), gitUrl.uri.getFragment());
    +					return Optional.of(newUri.toString().substring(gitUrl.addedPrefix.length()));
    +				}
    +				if (gitUrl.uri.getAuthority() != null && gitUrl.uri.getAuthority().contains(USER_INFO_SEPARATOR)) {
    +					String oldAuthority = gitUrl.uri.getAuthority();
    +					String[] parts = oldAuthority.split(USER_INFO_SEPARATOR, 2);
    +					if (!ALLOWED_USERNAME.equals(parts[0])) {
    +						String newAuthority = USER_INFO_REPLACEMENT + USER_INFO_SEPARATOR + parts[1];
    +						URI newUri = new URI(gitUrl.uri.getScheme(), newAuthority, gitUrl.uri.getPath(),
    +							gitUrl.uri.getQuery(), gitUrl.uri.getFragment());
    +						return Optional.of(newUri.toString().substring(gitUrl.addedPrefix.length()));
    +					}
    +				}
    +				return Optional.of(gitUrl.rawValue);
    +			}
    +			catch (URISyntaxException e) {
    +				return Optional.empty();
    +			}
    +		}
    +
    +		private Optional<GitUrl> toGitUrl(String remoteUrl) {
    +			try {
    +				return Optional.of(new GitUrl(remoteUrl, new URI(remoteUrl), ""));
    +			}
    +			catch (URISyntaxException ex) {
    +				try {
    +					return Optional.of(new GitUrl(remoteUrl, new URI("ssh://" + remoteUrl), "ssh://"));
    +				}
    +				catch (URISyntaxException ignore) {
    +					return Optional.empty();
    +				}
    +			}
    +		}
    +	}
    +
    +	class ProcessExecutor {
    +
    +		private final Path workingDir;
    +
    +		ProcessExecutor(Path workingDir) {
    +			this.workingDir = workingDir;
    +		}
    +
    +		Optional<String> exec(String... args) {
    +
    +			Process process = startProcess(args);
    +
    +			try (Reader out = newBufferedReader(process.getInputStream());
    +					Reader err = newBufferedReader(process.getErrorStream())) {
    +
    +				StringBuilder output = new StringBuilder();
    +				readAllChars(out, (chars, numChars) -> output.append(chars, 0, numChars));
    +
    +				readAllChars(err, (__, ___) -> {
    +					// ignore
    +				});
    +
    +				boolean terminated = process.waitFor(10, TimeUnit.SECONDS);
    +				return terminated && process.exitValue() == 0 ? Optional.of(trimAtEnd(output)) : Optional.empty();
    +			}
    +			catch (InterruptedException e) {
    +				throw ExceptionUtils.throwAsUncheckedException(e);
    +			}
    +			catch (IOException ignore) {
    +				return Optional.empty();
    +			}
    +			finally {
    +				process.destroyForcibly();
    +			}
    +		}
    +
    +		private static BufferedReader newBufferedReader(InputStream stream) {
    +			return new BufferedReader(new InputStreamReader(stream, Charset.defaultCharset()));
    +		}
    +
    +		private Process startProcess(String[] command) {
    +			Process process;
    +			try {
    +				process = new ProcessBuilder().directory(workingDir.toFile()).command(command).start();
    +			}
    +			catch (IOException e) {
    +				throw new UncheckedIOException("Failed to start process", e);
    +			}
    +			return process;
    +		}
    +
    +		private static void readAllChars(Reader reader, BiConsumer<char[], Integer> consumer) throws IOException {
    +			char[] buffer = new char[1024];
    +			int numChars;
    +			while ((numChars = reader.read(buffer)) != -1) {
    +				consumer.accept(buffer, numChars);
    +			}
    +		}
    +
    +		private static String trimAtEnd(StringBuilder value) {
    +			int endIndex = value.length();
    +			for (int i = value.length() - 1; i >= 0; i--) {
    +				if (Character.isWhitespace(value.charAt(i))) {
    +					endIndex--;
    +					break;
    +				}
    +			}
    +			return value.substring(0, endIndex);
    +		}
    +	}
    +
    +	class GitUrl {
    +
    +		private final String rawValue;
    +		private final URI uri;
    +		private final String addedPrefix;
    +
    +		GitUrl(String rawValue, URI uri, String addedPrefix) {
    +			this.rawValue = rawValue;
    +			this.uri = uri;
    +			this.addedPrefix = addedPrefix;
    +		}
    +	}
    +
    +}
    
  • junit-platform-reporting/src/main/java/org/junit/platform/reporting/open/xml/OpenTestReportGeneratingListener.java+22 93 modified
    @@ -51,30 +51,20 @@
     import static org.opentest4j.reporting.events.root.RootFactory.reported;
     import static org.opentest4j.reporting.events.root.RootFactory.started;
     
    -import java.io.BufferedReader;
     import java.io.IOException;
    -import java.io.InputStream;
    -import java.io.InputStreamReader;
    -import java.io.Reader;
     import java.io.UncheckedIOException;
     import java.net.InetAddress;
     import java.net.UnknownHostException;
    -import java.nio.charset.Charset;
     import java.nio.file.Path;
     import java.nio.file.Paths;
     import java.time.Instant;
     import java.time.LocalDateTime;
     import java.util.Map;
    -import java.util.Optional;
     import java.util.concurrent.ConcurrentHashMap;
    -import java.util.concurrent.TimeUnit;
     import java.util.concurrent.atomic.AtomicInteger;
    -import java.util.function.BiConsumer;
     
     import org.apiguardian.api.API;
     import org.junit.platform.commons.JUnitException;
    -import org.junit.platform.commons.util.ExceptionUtils;
    -import org.junit.platform.commons.util.StringUtils;
     import org.junit.platform.engine.ConfigurationParameters;
     import org.junit.platform.engine.TestExecutionResult;
     import org.junit.platform.engine.TestSource;
    @@ -110,6 +100,7 @@
     public class OpenTestReportGeneratingListener implements TestExecutionListener {
     
     	static final String ENABLED_PROPERTY_NAME = "junit.platform.reporting.open.xml.enabled";
    +	static final String GIT_ENABLED_PROPERTY_NAME = "junit.platform.reporting.open.xml.git.enabled";
     
     	private final AtomicInteger idCounter = new AtomicInteger();
     	private final Map<UniqueId, String> inProgressIds = new ConcurrentHashMap<>();
    @@ -140,19 +131,23 @@ public void testPlanExecutionStarted(TestPlan testPlan) {
     			Path eventsXml = outputDir.resolve("open-test-report.xml");
     			try {
     				eventsFileWriter = Events.createDocumentWriter(namespaceRegistry, eventsXml);
    -				reportInfrastructure();
    +				reportInfrastructure(config);
     			}
     			catch (Exception e) {
     				throw new JUnitException("Failed to initialize XML events file: " + eventsXml, e);
     			}
     		}
     	}
     
    -	private Boolean isEnabled(ConfigurationParameters config) {
    +	private boolean isEnabled(ConfigurationParameters config) {
     		return config.getBoolean(ENABLED_PROPERTY_NAME).orElse(false);
     	}
     
    -	private void reportInfrastructure() {
    +	private boolean isGitEnabled(ConfigurationParameters config) {
    +		return config.getBoolean(GIT_ENABLED_PROPERTY_NAME).orElse(false);
    +	}
    +
    +	private void reportInfrastructure(ConfigurationParameters config) {
     		eventsFileWriter.append(infrastructure(), infrastructure -> {
     			try {
     				String hostName = InetAddress.getLocalHost().getHostName();
    @@ -168,89 +163,23 @@ private void reportInfrastructure() {
     					.append(fileEncoding(System.getProperty("file.encoding"))) //
     					.append(heapSize(), heapSize -> heapSize.withMax(Runtime.getRuntime().maxMemory()));
     
    -			addGitInfo(infrastructure);
    +			if (isGitEnabled(config)) {
    +				GitInfoCollector.get(workingDir).ifPresent(git -> addGitInfo(infrastructure, git));
    +			}
     		});
     	}
     
    -	private void addGitInfo(Infrastructure infrastructure) {
    -		boolean gitInstalled = exec("git", "--version").isPresent();
    -		if (gitInstalled) {
    -			exec("git", "config", "--get", "remote.origin.url") //
    -					.filter(StringUtils::isNotBlank) //
    -					.ifPresent(
    -						gitUrl -> infrastructure.append(repository(), repository -> repository.withOriginUrl(gitUrl)));
    -			exec("git", "rev-parse", "--abbrev-ref", "HEAD") //
    -					.filter(StringUtils::isNotBlank) //
    -					.ifPresent(branch -> infrastructure.append(branch(branch)));
    -			exec("git", "rev-parse", "--verify", "HEAD") //
    -					.filter(StringUtils::isNotBlank) //
    -					.ifPresent(gitCommitHash -> infrastructure.append(commit(gitCommitHash)));
    -			exec("git", "status", "--porcelain") //
    -					.ifPresent(statusOutput -> infrastructure.append(status(statusOutput),
    -						status -> status.withClean(statusOutput.isEmpty())));
    -		}
    -	}
    -
    -	Optional<String> exec(String... args) {
    -
    -		Process process = startProcess(args);
    -
    -		try (Reader out = newBufferedReader(process.getInputStream());
    -				Reader err = newBufferedReader(process.getErrorStream())) {
    -
    -			StringBuilder output = new StringBuilder();
    -			readAllChars(out, (chars, numChars) -> output.append(chars, 0, numChars));
    -
    -			readAllChars(err, (__, ___) -> {
    -				// ignore
    -			});
    -
    -			boolean terminated = process.waitFor(10, TimeUnit.SECONDS);
    -			return terminated && process.exitValue() == 0 ? Optional.of(trimAtEnd(output)) : Optional.empty();
    -		}
    -		catch (InterruptedException e) {
    -			throw ExceptionUtils.throwAsUncheckedException(e);
    -		}
    -		catch (IOException ignore) {
    -			return Optional.empty();
    -		}
    -		finally {
    -			process.destroyForcibly();
    -		}
    -	}
    -
    -	private static BufferedReader newBufferedReader(InputStream stream) {
    -		return new BufferedReader(new InputStreamReader(stream, Charset.defaultCharset()));
    -	}
    -
    -	private Process startProcess(String[] command) {
    -		Process process;
    -		try {
    -			process = new ProcessBuilder().directory(workingDir.toFile()).command(command).start();
    -		}
    -		catch (IOException e) {
    -			throw new UncheckedIOException("Failed to start process", e);
    -		}
    -		return process;
    -	}
    -
    -	private static void readAllChars(Reader reader, BiConsumer<char[], Integer> consumer) throws IOException {
    -		char[] buffer = new char[1024];
    -		int numChars;
    -		while ((numChars = reader.read(buffer)) != -1) {
    -			consumer.accept(buffer, numChars);
    -		}
    -	}
    -
    -	private static String trimAtEnd(StringBuilder value) {
    -		int endIndex = value.length();
    -		for (int i = value.length() - 1; i >= 0; i--) {
    -			if (Character.isWhitespace(value.charAt(i))) {
    -				endIndex--;
    -				break;
    -			}
    -		}
    -		return value.substring(0, endIndex);
    +	private void addGitInfo(Infrastructure infrastructure, GitInfoCollector git) {
    +		git.getOriginUrl() //
    +				.ifPresent(
    +					gitUrl -> infrastructure.append(repository(), repository -> repository.withOriginUrl(gitUrl)));
    +		git.getBranch() //
    +				.ifPresent(branch -> infrastructure.append(branch(branch)));
    +		git.getCommitHash() //
    +				.ifPresent(gitCommitHash -> infrastructure.append(commit(gitCommitHash)));
    +		git.getStatus() //
    +				.ifPresent(statusOutput -> infrastructure.append(status(statusOutput),
    +					status -> status.withClean(statusOutput.isEmpty())));
     	}
     
     	@Override
    
  • platform-tests/src/test/java/org/junit/platform/reporting/open/xml/OpenTestReportGeneratingListenerTests.java+71 16 modified
    @@ -23,6 +23,7 @@
     import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request;
     import static org.junit.platform.launcher.core.LauncherFactoryForTestingPurposesOnly.createLauncher;
     import static org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener.ENABLED_PROPERTY_NAME;
    +import static org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener.GIT_ENABLED_PROPERTY_NAME;
     import static org.junit.platform.reporting.testutil.FileUtils.findPath;
     
     import java.io.PrintStream;
    @@ -36,6 +37,7 @@
     import org.junit.jupiter.api.Test;
     import org.junit.jupiter.api.io.TempDir;
     import org.junit.jupiter.params.ParameterizedTest;
    +import org.junit.jupiter.params.provider.CsvSource;
     import org.junit.jupiter.params.provider.ValueSource;
     import org.junit.platform.commons.util.ExceptionUtils;
     import org.junit.platform.engine.TestEngine;
    @@ -58,6 +60,12 @@
      */
     public class OpenTestReportGeneratingListenerTests {
     
    +	private static final Map<String, String> NAMESPACE_CONTEXT = Map.of( //
    +		"core", Namespace.REPORTING_CORE.getUri(), //
    +		"e", Namespace.REPORTING_EVENTS.getUri(), //
    +		"git", Namespace.REPORTING_GIT.getUri() //
    +	);
    +
     	private PrintStream originalOut;
     	private PrintStream originalErr;
     
    @@ -172,7 +180,7 @@ void writesValidXmlReport(@TempDir Path tempDirectory) throws Exception {
     	@ParameterizedTest
     	@ValueSource(strings = { "https://github.com/junit-team/junit-framework.git",
     			"git@github.com:junit-team/junit-framework.git" })
    -	void includesGitInfo(String originUrl, @TempDir Path tempDirectory) throws Exception {
    +	void includesGitInfoWhenEnabled(String originUrl, @TempDir Path tempDirectory) throws Exception {
     
     		assumeTrue(tryExecGit(tempDirectory, "--version").exitCode() == 0, "git not installed");
     		execGit(tempDirectory, "init", "--initial-branch=my_branch");
    @@ -192,36 +200,76 @@ void includesGitInfo(String originUrl, @TempDir Path tempDirectory) throws Excep
     		var xmlFile = findPath(tempDirectory, "glob:**/open-test-report.xml");
     		assertThat(validate(xmlFile)).isEmpty();
     
    -		var namespaceContext = Map.of("core", Namespace.REPORTING_CORE.getUri(), "e",
    -			Namespace.REPORTING_EVENTS.getUri(), "git", Namespace.REPORTING_GIT.getUri());
    +		assertThatXml(xmlFile) //
    +				.doesNotHaveXPath("/e:events/core:infrastructure/git:repository");
    +		assertThatXml(xmlFile) //
    +				.doesNotHaveXPath("/e:events/core:infrastructure/git:branch");
    +		assertThatXml(xmlFile) //
    +				.doesNotHaveXPath("/e:events/core:infrastructure/git:commit");
    +		assertThatXml(xmlFile) //
    +				.doesNotHaveXPath("/e:events/core:infrastructure/git:status");
    +
    +		executeTests(tempDirectory, engine, tempDirectory.resolve("junit-reports"),
    +			Map.of(GIT_ENABLED_PROPERTY_NAME, "true"));
    +
    +		assertThat(validate(xmlFile)).isEmpty();
     
    -		XmlAssert.assertThat(xmlFile) //
    -				.withNamespaceContext(namespaceContext) //
    +		assertThatXml(xmlFile) //
     				.valueByXPath("/e:events/core:infrastructure/git:repository/@originUrl") //
     				.isEqualTo(originUrl);
     
    -		XmlAssert.assertThat(xmlFile) //
    -				.withNamespaceContext(namespaceContext) //
    +		assertThatXml(xmlFile) //
     				.valueByXPath("/e:events/core:infrastructure/git:branch") //
     				.isEqualTo("my_branch");
     
     		var commitHash = execGit(tempDirectory, "rev-parse", "--verify", "HEAD").stdOut().trim();
    -		XmlAssert.assertThat(xmlFile) //
    -				.withNamespaceContext(namespaceContext) //
    +		assertThatXml(xmlFile) //
     				.valueByXPath("/e:events/core:infrastructure/git:commit") //
     				.isEqualTo(commitHash);
     
    -		XmlAssert.assertThat(xmlFile) //
    -				.withNamespaceContext(namespaceContext) //
    +		assertThatXml(xmlFile) //
     				.valueByXPath("/e:events/core:infrastructure/git:status/@clean") //
     				.isEqualTo(false);
     
    -		XmlAssert.assertThat(xmlFile) //
    -				.withNamespaceContext(namespaceContext) //
    +		assertThatXml(xmlFile) //
     				.valueByXPath("/e:events/core:infrastructure/git:status") //
     				.startsWith("?? junit-reports");
     	}
     
    +	@ParameterizedTest
    +	@CsvSource(textBlock = """
    +				https://foo:bar@github.com/junit-team/junit5.git, https://***@github.com/junit-team/junit5.git
    +				https://token@github.com/junit-team/junit5.git,   https://***@github.com/junit-team/junit5.git
    +				foo@github.com:junit-team/junit5.git,             ***@github.com:junit-team/junit5.git
    +				ssh://foo@github.com:junit-team/junit5.git,       ssh://***@github.com:junit-team/junit5.git
    +				git@github.com:junit-team/junit5.git,             git@github.com:junit-team/junit5.git
    +				ssh://git@github.com:junit-team/junit5.git,       ssh://git@github.com:junit-team/junit5.git
    +			""")
    +	void stripsCredentialsFromOriginUrl(String configuredUrl, String reportedUrl, @TempDir Path tempDirectory)
    +			throws Exception {
    +
    +		assumeTrue(tryExecGit(tempDirectory, "--version").exitCode() == 0, "git not installed");
    +		execGit(tempDirectory, "init", "--initial-branch=my_branch");
    +		execGit(tempDirectory, "remote", "add", "origin", configuredUrl);
    +
    +		var engine = new DemoHierarchicalTestEngine("dummy");
    +
    +		executeTests(tempDirectory, engine, tempDirectory.resolve("junit-reports"),
    +			Map.of(GIT_ENABLED_PROPERTY_NAME, "true"));
    +
    +		var xmlFile = findPath(tempDirectory, "glob:**/open-test-report.xml");
    +		assertThat(validate(xmlFile)).isEmpty();
    +
    +		assertThatXml(xmlFile) //
    +				.valueByXPath("/e:events/core:infrastructure/git:repository/@originUrl") //
    +				.isEqualTo(reportedUrl);
    +	}
    +
    +	private static XmlAssert assertThatXml(Path xmlFile) {
    +		return XmlAssert.assertThat(xmlFile) //
    +				.withNamespaceContext(NAMESPACE_CONTEXT);
    +	}
    +
     	private static ProcessResult execGit(Path workingDir, String... arguments) throws InterruptedException {
     		var result = tryExecGit(workingDir, arguments);
     		assertEquals(0, result.exitCode(), "git " + String.join(" ", arguments) + " failed");
    @@ -242,15 +290,22 @@ private ValidationResult validate(Path xmlFile) throws URISyntaxException {
     		return new DefaultValidator(catalogUri).validate(xmlFile);
     	}
     
    -	private void executeTests(Path tempDirectory, TestEngine engine, Path outputDir) {
    -		var build = request() //
    +	private static void executeTests(Path tempDirectory, TestEngine engine, Path outputDir) {
    +		executeTests(tempDirectory, engine, outputDir, Map.of());
    +	}
    +
    +	private static void executeTests(Path tempDirectory, TestEngine engine, Path outputDir,
    +			Map<String, String> extraConfigurationParameters) {
    +		var request = request() //
     				.selectors(selectUniqueId(UniqueId.forEngine(engine.getId()))) //
    +				.enableImplicitConfigurationParameters(false) //
     				.configurationParameter(ENABLED_PROPERTY_NAME, String.valueOf(true)) //
     				.configurationParameter(CAPTURE_STDOUT_PROPERTY_NAME, String.valueOf(true)) //
     				.configurationParameter(CAPTURE_STDERR_PROPERTY_NAME, String.valueOf(true)) //
     				.configurationParameter(OUTPUT_DIR_PROPERTY_NAME, outputDir.toString()) //
    +				.configurationParameters(extraConfigurationParameters) //
     				.build();
    -		createLauncher(engine).execute(build, new OpenTestReportGeneratingListener(tempDirectory));
    +		createLauncher(engine).execute(request, new OpenTestReportGeneratingListener(tempDirectory));
     	}
     
     }
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.