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

Server Audit does not escape newline/tab in user, host, database or table identifiers, allowing forged log lines

    XMLWordPrintable

Details

    • Bug
    • Status: Confirmed (View Workflow)
    • Major
    • Resolution: Unresolved
    • 10.11, 11.4, 11.8, 12.3, 13.1
    • 10.11, 11.4, 11.8, 12.3, 13.1
    • Plugin - Audit
    • None
    • Linux x86_64; official image
      `mariadb@sha256:dd9b303aed4f4890ed09f766d8ca9ddfd176c0c6f6267feff53b3192ec65a979`

    Description

      The audit plugin escapes the query text before writing a QUERY record (the fix from MDEV-8032),
      but it writes `user`, `host`, database and table identifiers using plain `%.*s`. MariaDB
      identifiers may legally contain newline and tab characters (`sql/table.cc:5527-5549` only rejects
      NUL and a trailing space), so an object name containing `\n` is written verbatim into the audit
      log. The file logger appends the record and `'\n'` without post-processing, so one audit record
      becomes several lines and an attacker with CREATE privileges can inject plausible-looking
      records (CWE-117 log forging) or corrupt CSV/SIEM parsing.

      Steps to reproduce

      ```bash
      IMG='mariadb@sha256:dd9b303aed4f4890ed09f766d8ca9ddfd176c0c6f6267feff53b3192ec65a979'
      docker run -d --name mdev-audit-id --env MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=yes "$IMG" \
      --skip-name-resolve --log-error=/var/lib/mysql/error.log

      1. wait for readiness, then:
        docker exec mdev-audit-id mariadb --socket=/run/mysqld/mysqld.sock -uroot -e "
        INSTALL SONAME 'server_audit';
        SET GLOBAL server_audit_logging=ON;
        SET GLOBAL server_audit_events='CONNECT,QUERY,QUERY_DCL,TABLE';
        SET GLOBAL server_audit_file_path='/var/lib/mysql/audit.log';
        CREATE DATABASE dsh37;
        CREATE TABLE dsh37.normal_t (i INT);
        INSERT INTO dsh37.normal_t VALUES (1);"
      2. table name with a real newline (use a file to keep shell quoting simple):
        printf 'CREATE TABLE `dsh37`.`evil\ntbl` (i INT); INSERT INTO `dsh37`.`evil\ntbl` VALUES (2);\n' > /tmp/nl.sql
        docker exec -i mdev-audit-id mariadb --socket=/run/mysqld/mysqld.sock -uroot < /tmp/nl.sql
        docker exec mdev-audit-id tail -20 /var/lib/mysql/audit.log

         

      Actual result

      The normal table produces well-formed single-line records. The newline-bearing table produces a
      TABLE/QUERY record whose identifier breaks the record across lines; the continuation line starts
      with the table-name fragment (here `tbl,`), i.e. an injected line that is not a valid audit
      record but is written to the same log:

      ```text
      20261025 18:17:26,...,root,localhost,7,11,CREATE,dsh37,normal_t,
      20261025 18:17:26,...,root,localhost,7,12,WRITE,dsh37,normal_t,
      ...
      20261025 18:17:26,...,root,localhost,8,14,CREATE,dsh37,evil
      tbl,
      ```

      Expected result

      Control characters in identifiers should be escaped like they are in query text (for example to
      `\n`/`\t` sequences or percent-encoded), so each audit event occupies exactly one line and the
      fields remain parseable.

      Attachments

        Issue Links

          Activity

            People

              rucha174 Rucha Deodhar
              csfuzz csfuzz
              Votes:
              0 Vote for this issue
              Watchers:
              2 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.