CVE-2023-28630 (Java, published 2023-03-27T21:15Z)
Description: value: GoCD is an open source continuous delivery server. In GoCD versions from 20.5.0 and below 23.1.0, if the server environment is not correctly configured by administrators to provide access to the relevant PostgreSQL or MySQL backup tools, the credentials for database access may be unintentionally leaked to admin alerts on the GoCD user interface. The vulnerability is triggered only if the GoCD server host is misconfigured to have backups enabled, but does not have access to the `pg_dump` or `mysqldump` utility tools to backup the configured database type (PostgreSQL or MySQL respectively). In such cases, failure to launch the expected backup utility reports the shell environment used to attempt to launch in the server admin alert, which includes the plaintext database password supplied to the configured tool. This vulnerability does not affect backups of the default on-disk H2 database that GoCD is configured to use. This issue has been addressed and fixed in GoCD 23.1.0. Users are advised to upgrade. Users unable to upgrade may disable backups, or administrators should ensure that the required `pg_dump` (PostgreSQL) or `mysqldump` (MySQL) binaries are available on the GoCD server when backups are triggered.
Severity: nan (CVSS v3 base score: 4.4)
Weakness: CWE-532 \u2014 Insertion of Sensitive Information into Log File
Information written to log files can be of a sensitive nature and give valuable guidance to an attacker or expose sensitive user information.
Repository: https://github.com/gocd/gocd
Files changed:
db-support/db-support-base/src/main/java/com/thoughtworks/go/server/database/BackupProcessor.java
db-support/db-support-mysql/src/main/java/com/thoughtworks/go/server/database/mysql/MySQLBackupProcessor.java
db-support/db-support-postgresql/src/main/java/com/thoughtworks/go/server/database/pg/PostgresqlBackupProcessor.java
Commit message: Improve error messages on failure to launch backup process

ztexec can include env vars in the error message which we don't want in this case.


Vulnerable code:
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
        ProcessResult processResult = createProcessExecutor(targetDir, dbProperties).execute();

        if (processResult.getExitValue() == 0) {
            log.info("MySQL backup finished successfully.");
        } else {
            log.warn("There was an error backing up the database using `mysqldump`. The `mysqldump` process exited with status code {}.", processResult.getExitValue());
            throw new RuntimeException("There was an error backing up the database using `mysqldump`. The `mysqldump` process exited with status code " + processResult.getExitValue() +
                    ". Please see the server logs for more errors");
        LinkedHashMap<String, String> env = new LinkedHashMap<>();
        ArrayList<String> argv = new ArrayList<>();
        argv.add("mysqldump");

        argv.add("--result-file=" + new File(targetDir, "db." + dbName).toString());
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Properties;
        ProcessResult processResult = createProcessExecutor(targetDir, dbProperties).execute();

        if (processResult.getExitValue() == 0) {
            log.info("PostgreSQL backup finished successfully.");
        } else {
            log.warn("There was an error backing up the database using `pg_dump`. The `pg_dump` process exited with status code {}.", processResult.getExitValue());
            throw new RuntimeException("There was an error backing up the database using `pg_dump`. The `pg_dump` process exited with status code " + processResult.getExitValue() +
                    ". Please see the server logs for more errors.");
        ArrayList<String> argv = new ArrayList<>();
        LinkedHashMap<String, String> env = new LinkedHashMap<>();
        argv.add("pg_dump");

Fixed code:

    default void throwBackupError(String command, int errorCode) {
        throwBackupError(command, errorCode, null);
    }

    default void throwBackupError(String command, int errorCode, Throwable cause) {
        throw new RuntimeException(String.format("There was an error backing up the database using `%s`. The `%s` process failed with code %s. Please see the server logs for more detail.", command, command, errorCode), cause);
    }
import org.zeroturnaround.exec.ProcessInitException;
import java.util.*;
    private static final String COMMAND = "mysqldump";

        try {
            ProcessResult processResult = createProcessExecutor(targetDir, dbProperties).execute();

            if (processResult.getExitValue() == 0) {
                log.info("MySQL backup finished successfully.");
            } else {
                throwBackupError(COMMAND, processResult.getExitValue());
            }
        } catch (ProcessInitException e) {
            throwBackupError(COMMAND, e.getErrorCode(), e.getCause());
        Map<String, String> env = new LinkedHashMap<>();
        List<String> argv = new ArrayList<>();
        argv.add(COMMAND);
        argv.add("--result-file=" + new File(targetDir, "db." + dbName));
import org.zeroturnaround.exec.ProcessInitException;
import java.util.*;
    private static final String COMMAND = "pg_dump";

        try {
            ProcessResult processResult = createProcessExecutor(targetDir, dbProperties).execute();
            if (processResult.getExitValue() == 0) {
                log.info("PostgreSQL backup finished successfully.");
            } else {
                throwBackupError(COMMAND, processResult.getExitValue());
            }
        } catch (ProcessInitException e) {
            throwBackupError(COMMAND, e.getErrorCode(), e.getCause());
        Map<String, String> env = new LinkedHashMap<>();
        List<String> argv = new ArrayList<>();
        argv.add(COMMAND);