Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-41090

mariadb-backup silently bypasses requested certificate fingerprint and TLS-version restrictions

    XMLWordPrintable

Details

    • Bug
    • Status: Confirmed (View Workflow)
    • Major
    • Resolution: Unresolved
    • 11.4, 11.8, 12.3, 13.0, 12.3.3
    • 11.4, 11.8, 12.3, 13.0
    • mariabackup

    Description

      `mariadb-backup` accepts `-ssl-fp` and `-tls-version`, but the requested
      constraints are not applied to its server connection. Against a server limited
      to TLS 1.2, the ordinary `mariadb` client rejects both a deliberately wrong
      certificate fingerprint and a TLS-1.3-only request. `mariadb-backup` receives
      the same options but completes a real backup in both cases.

      This can make an operator believe that a backup connection enforces certificate
      pinning or an approved TLS version when it does not.

      Steps to reproduce

      Run only on a disposable Docker host. The script creates a synthetic CA,
      server certificate, password, and empty test server.

      set -eu
      IMAGE='mariadb@sha256:dd9b303aed4f4890ed09f766d8ca9ddfd176c0c6f6267feff53b3192ec65a979'
      C='mdev-mariabackup-tls-policy-repro'
      OWNER="edbf-report-$C-$$"
      D=$(mktemp -d)
      PW='MDEV_SYNTHETIC_BACKUP_TLS_PASSWORD'
      cleanup() {
        if docker inspect --format '{{ index .Config.Labels "io.encryptiondbfuzz.owner" }}' \
             "$C" 2>/dev/null | grep -Fqx "$OWNER"; then
          docker rm -f "$C" >/dev/null 2>&1 || true
        fi
        rm -r "$D" >/dev/null 2>&1 || true
      }
      trap cleanup EXIT
       
      openssl req -x509 -newkey rsa:2048 -nodes -days 1 \
        -keyout "$D/ca-key.pem" -out "$D/ca.pem" \
        -subj '/CN=MDEV synthetic test CA'
      openssl req -newkey rsa:2048 -nodes \
        -keyout "$D/server-key.pem" -out "$D/server.csr" \
        -subj '/CN=localhost' \
        -addext 'subjectAltName=IP:127.0.0.1,DNS:localhost'
      openssl x509 -req -days 1 -sha256 -copy_extensions copy \
        -in "$D/server.csr" -CA "$D/ca.pem" -CAkey "$D/ca-key.pem" \
        -CAcreateserial -out "$D/server-cert.pem"
      chmod 0755 "$D"
      chmod 0644 "$D"/*.pem
       
      FP=$(openssl x509 -in "$D/server-cert.pem" -noout -fingerprint -sha1 | cut -d= -f2)
      case "$FP" in
        00:*) BAD_FP="01:${FP#*:}" ;;
        *)    BAD_FP="00:${FP#*:}" ;;
      esac
       
      docker run --detach --name "$C" \
        --label "io.encryptiondbfuzz.owner=$OWNER" \
        --mount type=bind,src="$D",dst=/edbf,readonly \
        --env MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1 \
        "$IMAGE" \
        --ssl-ca=/edbf/ca.pem \
        --ssl-cert=/edbf/server-cert.pem \
        --ssl-key=/edbf/server-key.pem \
        --tls-version=TLSv1.2
       
      READY=0
      for i in $(seq 1 90); do
        if docker exec "$C" mariadb --protocol=socket -uroot -NBe \
             "SELECT @@port" 2>/dev/null | grep -qx 3306; then
          READY=1
          break
        fi
        sleep 1
      done
      test "$READY" -eq 1
       
      docker exec "$C" mariadb --protocol=socket -uroot -e \
        "CREATE USER 'edbf_backup'@'127.0.0.1' IDENTIFIED BY '$PW';
         GRANT ALL PRIVILEGES ON *.* TO 'edbf_backup'@'127.0.0.1';"
       
      COMMON="--host=127.0.0.1 --port=3306 --protocol=TCP --user=edbf_backup --password=$PW --ssl --ssl-ca=/edbf/ca.pem"
       
      # Positive control: ordinary client accepts the real fingerprint.
      docker exec "$C" sh -c \
        "mariadb $COMMON --ssl-fp='$FP' -NBe \"SHOW STATUS LIKE 'Ssl_cipher'\""
       
      # Negative controls: ordinary client rejects both constraints.
      set +e
      docker exec "$C" sh -c \
        "mariadb $COMMON --ssl-fp='$BAD_FP' -NBe 'SELECT 1'"
      echo "client_wrong_fingerprint_rc=$?"
      docker exec "$C" sh -c \
        "mariadb $COMMON --tls-version=TLSv1.3 -NBe 'SELECT 1'"
      echo "client_tls13_rc=$?"
      set -e
       
      # Triggers: mariadb-backup receives the same constraints but succeeds.
      docker exec "$C" sh -c \
        "mariadb-backup --backup $COMMON --ssl-fp='$BAD_FP' --target-dir=/tmp/backup-wrong-fp"
      echo "backup_wrong_fingerprint_rc=$?"
      docker exec "$C" sh -c \
        "mariadb-backup --backup $COMMON --tls-version=TLSv1.3 --target-dir=/tmp/backup-tls13"
      echo "backup_tls13_rc=$?"
      

      Actual result

      The ordinary client negotiated TLS with the correct fingerprint:

      Ssl_cipher    ECDHE-RSA-AES256-GCM-SHA384
      

      It rejected the wrong fingerprint and disallowed TLS version:

      ERROR 2026 (HY000): TLS/SSL error: Fingerprint validation of peer certificate failed
      client_wrong_fingerprint_rc=1
      ERROR 2026 (HY000): TLS/SSL error: tlsv1 alert protocol version
      client_tls13_rc=1
      

      Both `mariadb-backup` trigger commands nevertheless exited 0 and ended with:

      [00] completed OK!
      backup_wrong_fingerprint_rc=0
      [00] completed OK!
      backup_tls13_rc=0
      

      Expected result

      `mariadb-backup` should apply the same Connector/C fingerprint and TLS-version
      options as the ordinary client. A wrong fingerprint or a TLS version that the
      server does not support must abort before any backup is accepted as successful.

      Attachments

        Activity

          People

            thiru Thirunarayanan Balathandayuthapani
            csfuzz csfuzz
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:

              Git Integration

                Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.