You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
10 test cases ran. 2 additional findings, 8 passed.
Across 10 executed test cases, 8 passed and 2 failed, confirming successful bootstrap startup/query readiness, TLS pgwire handshake behavior (including database fallback to username), authorization enforcement, adapter initialization, and key replication happy paths including restart checkpoint recovery. The major issues were both in logical replication: a High-severity SQL apply-construction flaw with unquoted identifiers and malformed predicates that can produce unsafe or broken statements, and a Critical crash path where out-of-order DML with unknown relation IDs triggers log.Fatalf and terminates the replica; several runs bypassed SCRAM authentication, so these results validate functional paths rather than credential enforcement.
✅ Passed (8)
Category
Summary
Screenshot
Adapter
First SELECT * FROM dolt.status after restart succeeded with expected adapted columns.
N/A
Bootstrap
Fresh startup created postgres and SELECT 1 succeeded via psql.
Handshake
Configured doltgres with TLS cert/key, connected with SSL-required pgwire client, and verified authenticated usable session by querying current_user successfully.
N/A
Handshake
Using a raw pgwire startup packet that omitted the database parameter, connection succeeded over TLS and subsequent query confirmed usable session with current_database() resolving to postgres.
N/A
Permissions
Unauthorized table SELECT was correctly denied for a role without SELECT privileges.
Permissions
Execute after privilege revocation was correctly denied in the prepared-statement flow.
After forced stop and restart, replay resumed cleanly with complete row range 500-520.
ℹ️ Additional Findings (2)
These findings are unrelated to the current changes but were observed during testing.
Category
Summary
Screenshot
Replication
⚠️ Replication apply builds SQL from unquoted identifiers and malformed predicates, causing unsafe/malformed statements.
Replication
🚨 Out-of-order DML for unknown relation ID calls log.Fatalf and terminates the replica process.
⚠️ Replication apply SQL builder is unsafe
What failed: The apply path interpolates relation and column identifiers directly into SQL and contains malformed predicate assembly, so malformed/adversarial metadata can produce unsafe or syntactically broken statements instead of a clean safe reject.
Impact: A crafted replication stream can trigger malformed or unintended SQL in the apply path, creating a security and data integrity risk on replicas. Replication can also enter retry/error loops instead of cleanly rejecting invalid metadata.
Steps to reproduce:
Configure logical replication between primary and replica with a controlled publication.
Send crafted relation and column identifiers through replication metadata.
Observe generated apply SQL behavior and replica error handling.
Stub / mock context: SCRAM authentication was intentionally bypassed for local connections in server/authentication_scram.go to keep replication setup deterministic, and the runtime image used the prebuilt doltgres binary path during this run.
Code analysis: I inspected the replication apply implementation in server/logrepl/replication.go and found raw identifier interpolation in INSERT/UPDATE/DELETE query builders plus predicate-construction defects (updateStr separator written in the WHERE branch and comma-joined delete predicates).
Why this is likely a bug: The production apply code composes executable SQL from unquoted replication identifiers and inconsistent predicate builders, which directly explains syntax-error behavior and unsafe statement-construction risk without relying on test-only assumptions.
Relevant code:
server/logrepl/replication.go (lines 613-637)
colName:=rel.Columns[idx].NamecolumnStr.WriteString(colName)
switchcol.DataType {
case'n': // nullvaluesStr.WriteString("NULL")
case't': // text// We have to round-trip the data through the encodings to get an accurate text rep backval, err:=decodeTextColumnData(state.typeMap, col.Data, rel.Columns[idx].DataType)
iferr!=nil {
log.Fatalln("error decoding column data:", err)
}
colData, err:=encodeColumnData(state.typeMap, val, rel.Columns[idx].DataType)
iferr!=nil {
returnfalse, err
}
valuesStr.WriteString(colData)
}
err=r.replicateQuery(state.replicaConn, fmt.Sprintf("INSERT INTO %s.%s (%s) VALUES (%s)", rel.Namespace, rel.RelationName, columnStr.String(), valuesStr.String()))
ifwhereStr.Len() >0 {
whereStr.WriteString(", ")
}
whereStr.WriteString(fmt.Sprintf("%s = %v", colName, stringVal))
err=r.replicateQuery(state.replicaConn, fmt.Sprintf("DELETE FROM %s.%s WHERE %s", rel.Namespace, rel.RelationName, whereStr.String()))
🚨 Out-of-order replication DML crashes process
What failed: Unknown relation IDs in DML paths trigger log.Fatalf, which terminates the process rather than rejecting/quarantining the bad stream segment and continuing service.
Impact: A single out-of-order replication message can crash the replica process and interrupt availability until manual restart. This makes replication fragile under protocol disorder or malicious upstream input.
Steps to reproduce:
Connect replication to a controllable stream source.
Deliver INSERT, UPDATE, or DELETE frames that reference an unseen relation ID before the relation message.
Observe process behavior and confirm whether the replica stays available and can recover.
Stub / mock context: SCRAM authentication was intentionally bypassed for local connections in server/authentication_scram.go to keep replication setup deterministic, and the runtime image used the prebuilt doltgres binary path during this run.
Code analysis: I reviewed the insert, update, and delete replication handlers in server/logrepl/replication.go; each unknown relation branch uses log.Fatalf, so the failure mode is process termination instead of resilient error handling.
Why this is likely a bug: Fatal process exits on malformed/out-of-order replication input violate the expected resilient behavior and are caused by explicit production crash paths in the handler.
Relevant code:
server/logrepl/replication.go (lines 600-603)
rel, ok:=state.relations[logicalMsg.RelationID]
if!ok {
log.Fatalf("unknown relation ID %d", logicalMsg.RelationID)
}
server/logrepl/replication.go (lines 648-651)
rel, ok:=state.relations[logicalMsg.RelationID]
if!ok {
log.Fatalf("unknown relation ID %d", logicalMsg.RelationID)
}
server/logrepl/replication.go (lines 703-705)
rel, ok:=state.relations[logicalMsg.RelationID]
if!ok {
log.Fatalf("unknown relation ID %d", logicalMsg.RelationID)
}
These are tests that we're marking as Successful, however they do not match the expected output in some way. This is due to small differences, such as different wording on the error messages, or the column names being incorrect while the data itself is correct. ↩
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
☕ An Automated Dependency Version Bump PR 👑
Initial Changes
The changes contained in this PR were produced by `go get`ing the dependency.
```bash
go get github.com/dolthub/[dependency]/go@[commit]
```