From a07e39443b9973943707d50a43cca0fd5f6b7091 Mon Sep 17 00:00:00 2001 From: Jake Huneau Date: Sat, 18 Jul 2026 10:41:14 -0400 Subject: [PATCH 1/3] Fix SQL injection via message ID in DbTrackingModule.persist The existence-check SELECT concatenated the message ID directly into the SQL, and for inbound messages that value is the partner-controlled Message-ID header. A crafted header could inject SQL (e.g. "x' OR '1'='1" made a new message match an existing row, corrupting tracking) or break the query outright, and persist() swallows the resulting exception so the tracking record was silently lost. Parameterise the existence-check SELECT and escape the message ID in the UPDATE WHERE clause using the existing formatField() helper (the same escaping the SET values already use). Adds a test proving crafted IDs are stored/matched as opaque literals rather than interpreted as SQL. --- Server/src/config/as2_certs.p12 | Bin 7668 -> 7668 bytes .../msgtracking/DbTrackingModule.java | 12 +- .../DbTrackingModulePersistInjectionTest.java | 119 ++++++++++++++++++ 3 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 Server/src/test/java/org/openas2/processor/msgtracking/DbTrackingModulePersistInjectionTest.java diff --git a/Server/src/config/as2_certs.p12 b/Server/src/config/as2_certs.p12 index 779333d8047950131bd0da99d918ba9020a9a7cd..29621116c8cb17a62aba8767996af17fc3a809b3 100644 GIT binary patch delta 7176 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 map) { String msgIdValue = map.get(msgIdField); try (Connection conn = dbHandler.getConnection()) { Statement s = conn.createStatement(); - ResultSet rs = s.executeQuery( - "SELECT * FROM " + tableName + " WHERE " + msgIdField + " = '" + msgIdValue + "'"); + // Parameterised existence check: msgIdValue is partner-controlled (the inbound + // Message-ID header) so it must not be concatenated into the SQL. + PreparedStatement selectStmt = conn.prepareStatement( + "SELECT * FROM " + tableName + " WHERE " + msgIdField + " = ?"); + selectStmt.setString(1, msgIdValue); + ResultSet rs = selectStmt.executeQuery(); ResultSetMetaData meta = rs.getMetaData(); boolean isUpdate = rs.next(); // Record already exists so update if (logger.isTraceEnabled()) { @@ -154,8 +158,8 @@ protected synchronized void persist(Message msg, Map map) { if (fieldStmt.length() > 0) { String stmt = ""; if (isUpdate) { - stmt = "UPDATE " + tableName + " SET " + fieldStmt.toString() + " WHERE " + FIELDS.MSG_ID + " = '" - + map.get(msgIdField) + "'"; + stmt = "UPDATE " + tableName + " SET " + fieldStmt.toString() + " WHERE " + FIELDS.MSG_ID + " = " + + formatField(map.get(msgIdField), Types.VARCHAR); } else { stmt = "INSERT INTO " + tableName + " (" + fieldStmt.toString() + ") VALUES (" + valuesStmt.toString() + ")"; diff --git a/Server/src/test/java/org/openas2/processor/msgtracking/DbTrackingModulePersistInjectionTest.java b/Server/src/test/java/org/openas2/processor/msgtracking/DbTrackingModulePersistInjectionTest.java new file mode 100644 index 00000000..26e94a9d --- /dev/null +++ b/Server/src/test/java/org/openas2/processor/msgtracking/DbTrackingModulePersistInjectionTest.java @@ -0,0 +1,119 @@ +package org.openas2.processor.msgtracking; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; +import org.openas2.app.BaseServerSetup; +import org.openas2.message.AS2Message; +import org.openas2.message.Message; +import org.openas2.processor.ProcessorModule; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.Statement; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Verifies that DbTrackingModule.persist is not vulnerable to SQL injection through the message ID, + * which for inbound messages is the partner-controlled Message-ID header. A crafted value must be + * stored and matched as an opaque literal, not interpreted as SQL. + */ +@TestInstance(Lifecycle.PER_CLASS) +public class DbTrackingModulePersistInjectionTest extends BaseServerSetup { + + private DbTrackingModule db; + + @BeforeAll + public void setUp() throws Exception { + super.createFileSystemResources(this.getClass().getName()); + super.setStartActiveModules(true); + super.setup(); + + List mpl = session.getProcessor().getModulesSupportingAction(TrackingModule.DO_TRACK_MSG); + db = (DbTrackingModule) mpl.get(0); + + try (Connection conn = db.dbHandler.getConnection()) { + Statement s = conn.createStatement(); + String ddl = new String(Files.readAllBytes(Paths.get("src", "config", "db_ddl.sql"))); + for (String statement : ddl.split(";")) { + if (!statement.trim().isEmpty()) { + s.execute(statement); + } + } + // A pre-existing legitimate record that an injection would try to match/mangle + s.executeUpdate("INSERT INTO msg_metadata (msg_id, sender_id, receiver_id, state) VALUES " + + "('', 'SENDER', 'RECEIVER', 'ORIGINAL_STATE')"); + } + } + + private void persist(String msgId, String state) { + Map map = new HashMap(); + map.put(DbTrackingModule.FIELDS.MSG_ID, msgId); + map.put(DbTrackingModule.FIELDS.SENDER_ID, "SENDER"); + map.put(DbTrackingModule.FIELDS.RECEIVER_ID, "RECEIVER"); + map.put(DbTrackingModule.FIELDS.STATE, state); + Message msg = new AS2Message(); + db.persist(msg, map); + } + + private String stateOf(String msgId) throws Exception { + try (Connection conn = db.dbHandler.getConnection(); + java.sql.PreparedStatement ps = conn.prepareStatement("SELECT state FROM msg_metadata WHERE msg_id = ?")) { + ps.setString(1, msgId); + try (ResultSet rs = ps.executeQuery()) { + return rs.next() ? rs.getString(1) : null; + } + } + } + + private long rowCount() throws Exception { + try (Connection conn = db.dbHandler.getConnection(); + Statement s = conn.createStatement(); + ResultSet rs = s.executeQuery("SELECT COUNT(*) FROM msg_metadata")) { + rs.next(); + return rs.getLong(1); + } + } + + @Test + public void injectionInMessageIdIsStoredAsLiteralNotInterpreted() throws Exception { + long before = rowCount(); + String malicious = ""; + persist(withQuote, "QUOTED"); + assertEquals("QUOTED", stateOf(withQuote), "a message ID containing a quote must persist and be retrievable"); + + // And an update to the same record is matched correctly (exercises the WHERE clause of the UPDATE path) + persist(withQuote, "QUOTED_UPDATED"); + assertEquals("QUOTED_UPDATED", stateOf(withQuote), "updating a quoted message ID must match the same record"); + } + + @Test + public void normalInsertAndUpdateStillWork() throws Exception { + persist("", "S1"); + assertEquals("S1", stateOf("")); + persist("", "S2"); + assertEquals("S2", stateOf(""), "second persist of the same ID should update in place"); + assertTrue(rowCount() >= 1); + } +} From 4aca40a6ef4208ce98aacd8901baa308761bdcff Mon Sep 17 00:00:00 2001 From: Jake Huneau Date: Thu, 23 Jul 2026 06:37:52 -0400 Subject: [PATCH 2/3] Restore as2_certs.p12 to the master version --- Server/src/config/as2_certs.p12 | Bin 7668 -> 7668 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Server/src/config/as2_certs.p12 b/Server/src/config/as2_certs.p12 index 29621116c8cb17a62aba8767996af17fc3a809b3..9d45fd49c0ec8dbf8dbab0120e40cdebd51b71ef 100644 GIT binary patch delta 7164 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 delta 7164 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 Date: Thu, 23 Jul 2026 06:39:43 -0400 Subject: [PATCH 3/3] Restore as2_certs.p12 to the master version --- Server/src/config/as2_certs.p12 | Bin 7668 -> 7668 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Server/src/config/as2_certs.p12 b/Server/src/config/as2_certs.p12 index 9d45fd49c0ec8dbf8dbab0120e40cdebd51b71ef..779333d8047950131bd0da99d918ba9020a9a7cd 100644 GIT binary patch delta 7176 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 KaGOv90w)m4A@`L4