{"id":"CVE-2026-116312","kind":"vulnerability","aliases":["CVE-2026-116312"],"related":[],"title":"PostgreSQL: MERGE on partitioned tables lets an AFTER trigger read the wrong row","description":"Inconsistent transition-capture state in PostgreSQL MERGE allows a table data modifier to make an AFTER trigger process the wrong new row, via a partitioned table MERGE that performs an INSERT before an UPDATE.  Within major versions 15-18, minor versions before PostgreSQL 18.7, 17.12, 16.16, and 15.20 are affected.  Versions before PostgreSQL 15 are unaffected.","summary":"A bug in how PostgreSQL's MERGE command tracks transition capture on partitioned tables can make an AFTER trigger process the wrong new row. A user who can modify table data can use a MERGE that runs an INSERT before an UPDATE to make the trigger act on unintended data.","severity":"medium","cvss":5.4,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["database","postgresql","runtime","self-hosted"],"not_affected_if":["no-after-triggers","no-partitioned-merge","postgresql-before-15"],"how_to_check":"- Run `SELECT version();` in psql and compare the server version with the fixed releases.\n- Check whether any AFTER triggers use transition tables and whether MERGE runs against partitioned tables.","fix":"- PostgreSQL `18.7`\n- PostgreSQL `17.12`\n- PostgreSQL `16.16`\n- PostgreSQL `15.20`","status":"open","published_at":"2026-11-12T15:17:39+00:00","first_seen_at":"2026-11-12T15:41:54+00:00","triaged_at":"2026-11-12T15:43:54+00:00","updated_at":"2026-11-12T15:43:54+00:00","category":"runtime","confidence":0.7,"triage":{"at":"2026-11-12T15:43:54Z","model":"claude-haiku-5-5","output":{"fix":"- PostgreSQL `18.7`\n- PostgreSQL `17.12`\n- PostgreSQL `16.16`\n- PostgreSQL `15.20`","reach":"network","title":"PostgreSQL: MERGE on partitioned tables lets an AFTER trigger read the wrong row","impact":"medium","summary":"A bug in how PostgreSQL's MERGE command tracks transition capture on partitioned tables can make an AFTER trigger process the wrong new row. A user who can modify table data can use a MERGE that runs an INSERT before an UPDATE to make the trigger act on unintended data.","audience":"businesses","category":"runtime","nicknames":[],"who_cares":["postgresql","self-hosted","database"],"confidence":0.7,"fix_status":"available","needs_auth":"yes","worst_case":"trigger processes wrong row, corrupting or misreading table data","analyst_note":"","how_to_check":"- Run `SELECT version();` in psql and compare the server version with the fixed releases.\n- Check whether any AFTER triggers use transition tables and whether MERGE runs against partitioned tables.","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["postgresql-before-15","no-partitioned-merge","no-after-triggers"],"who_is_affected":"Servers running PostgreSQL 15 through 18 before the fixed minor releases are exposed. The problem needs a MERGE on a partitioned table that has AFTER triggers, so instances without such triggers or without partitioned MERGE use carry much less risk. PostgreSQL before 15 is not affected.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"medium"},"cost_usd":0.000758,"input_tokens":4605,"output_tokens":595,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-116312':16A,19A '-18':115C '-2026':15A,18A '15':114C,130C '15.20':124C '16.16':122C '17.12':121C '18.7':120C 'act':72B 'affect':126C 'allow':84C 'bug':27B 'captur':36B,79C 'command':33B 'cve':14A,17A 'data':56B,75B,87C 'databas':20B 'host':25B 'inconsist':76C 'insert':64B,107C 'let':6A 'major':112C 'make':41B,69B,90C 'merg':2A,32B,60B,83C,103C 'minor':116C 'modifi':54B,88C 'new':48B,97C 'partit':4A,38B,101C 'perform':105C 'postgresql':1A,21B,30B,82C,119C,129C 'process':45B,94C 'read':10A 'row':13A,49B,98C 'run':62B 'runtim':22B 'self':24B 'self-host':23B 'state':80C 'tabl':5A,39B,55B,86C,102C 'track':34B 'transit':35B,78C 'transition-captur':77C 'trigger':9A,44B,71B,93C 'unaffect':132C 'unintend':74B 'updat':67B,110C 'use':58B 'user':51B 'version':113C,117C,127C 'via':99C 'within':111C 'wrong':12A,47B,96C","nicknames":[],"mitigations":[],"who_affected":"Servers running PostgreSQL 15 through 18 before the fixed minor releases are exposed. The problem needs a MERGE on a partitioned table that has AFTER triggers, so instances without such triggers or without partitioned MERGE use carry much less risk. PostgreSQL before 15 is not affected.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"businesses","plain_action":null,"pkeys":[],"ptokens":[],"labels":["database","medium","postgresql","runtime","selfhosted"],"campaign_type":null,"search_a":"'-116312':16A,19A '-2026':15A,18A 'cve':14A,17A 'let':6A 'merg':2A 'partit':4A 'postgresql':1A 'read':10A 'row':13A 'tabl':5A 'trigger':9A 'wrong':12A","search_b":"'act':72B 'bug':27B 'captur':36B 'command':33B 'data':56B,75B 'databas':20B 'host':25B 'insert':64B 'make':41B,69B 'merg':32B,60B 'modifi':54B 'new':48B 'partit':38B 'postgresql':21B,30B 'process':45B 'row':49B 'run':62B 'runtim':22B 'self':24B 'self-host':23B 'tabl':39B,55B 'track':34B 'transit':35B 'trigger':44B,71B 'unintend':74B 'updat':67B 'use':58B 'user':51B 'wrong':47B","search_c":"'-18':115C '15':114C,130C '15.20':124C '16.16':122C '17.12':121C '18.7':120C 'affect':126C 'allow':84C 'captur':79C 'data':87C 'inconsist':76C 'insert':107C 'major':112C 'make':90C 'merg':83C,103C 'minor':116C 'modifi':88C 'new':97C 'partit':101C 'perform':105C 'postgresql':82C,119C,129C 'process':94C 'row':98C 'state':80C 'tabl':86C,102C 'transit':78C 'transition-captur':77C 'trigger':93C 'unaffect':132C 'updat':110C 'version':113C,117C,127C 'via':99C 'within':111C 'wrong':96C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-12T15:17:39+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N","cvss_by":"f86ef6dc-4d3a-42ad-8f28-e6d5547a5007","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-116312","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-116312","severity":null,"published_at":"2026-11-12T15:17:39+00:00","modified_at":"2026-11-12T15:17:39+00:00","first_seen_at":"2026-11-12T15:41:54+00:00","fetched_at":"2026-11-12T15:41:54+00:00","note":null}],"documents":[],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}