Skip to content
Output prediction quizintermediate · 2 min read · 2026-11-01

E-Maj 5.0.1: Find Usage and Upgrade Safely

Learn how PostgreSQL teams can identify E-Maj usage, understand the privilege-escalation risk at a high level, and plan an immediate upgrade to E-Maj 5.0.1.

What changed in E-Maj 5.0.1

E-Maj 5.0.1 is a security-focused release of the E-Maj PostgreSQL extension. E-Maj provides fine-grained write logging and time travel on subsets of a database.

The release fixes a vulnerability present in all previous versions. At a high level, the risk is privilege escalation: under certain circumstances, some users could gain superuser privileges. Treat this as urgent even if only a small number of databases use E-Maj.

First task: prove whether you rely on E-Maj

The safe response starts with inventory. Do not assume that because E-Maj packages are installed on a server, every database uses E-Maj. PostgreSQL extensions are installed per database, so check each database that matters.

A common mistake is checking only one application database or only the package manager. For incident response, you need a database-level list: database name, extension name, and installed extension version.

Avoid weak version checks

For this security update, the key question is not just “is the version different from 5.0.1?” A condition such as extension_version <> '5.0.1' is too blunt: it would also flag a newer version as if it were older.

A better runbook distinguishes these cases: - E-Maj below 5.0.1: upgrade now. - E-Maj exactly 5.0.1: record as fixed. - E-Maj above 5.0.1: review against your approved version policy instead of treating it as below 5.0.1. - Non-E-Maj extensions: outside this E-Maj change.

Scenario: classify databases before the change window

The runnable SQLite example below models a small extension inventory. It is not PostgreSQL; it is a deterministic training example that shows the decision logic your runbook needs before touching production.

The example parses simple major.minor.patch strings into a numeric key. Real production upgrade scripts should follow PostgreSQL and E-Maj documentation, but the habit is the same: produce a short, reviewable list first.

Safe upgrade plan

A practical plan should be boring and auditable: - Identify every database with emaj installed. - Confirm whether each one is below 5.0.1. - Test the upgrade path in staging or a restored copy first. - Schedule a maintenance window if your workload or extension usage requires it. - Upgrade to E-Maj 5.0.1 as soon as possible and re-run the inventory query.

Avoid trying to “mitigate” this only with application permissions. The release note describes a path to superuser privilege under certain circumstances, so the durable fix is to update the installed E-Maj extension.

Code

SQL (SQLite) · Training inventory classifier in SQLite✓ Executed & verified · 3.40.1 2022-12-28 14:03:47 df5c253c0b3dd24916e4ec7cf77d3db5294cc9fd45ae7b9c5e82ad8197f3alt1
CREATE TABLE installed_extensions (
  database_name TEXT,
  extension_name TEXT,
  extension_version TEXT
);

INSERT INTO installed_extensions VALUES
  ('orders', 'emaj', '4.7.0'),
  ('analytics', 'postgis', '3.4.0'),
  ('billing', 'emaj', '5.0.1'),
  ('future_lab', 'emaj', '5.0.2');

WITH version_parts AS (
  SELECT database_name,
         extension_name,
         extension_version,
         substr(extension_version, 1, instr(extension_version, '.') - 1) AS major_text,
         substr(extension_version, instr(extension_version, '.') + 1) AS rest
  FROM installed_extensions
), parsed AS (
  SELECT database_name,
         extension_name,
         extension_version,
         CAST(major_text AS INTEGER) AS major,
         CAST(substr(rest, 1, instr(rest, '.') - 1) AS INTEGER) AS minor,
         CAST(substr(rest, instr(rest, '.') + 1) AS INTEGER) AS patch
  FROM version_parts
)
SELECT database_name || ':' || extension_name || ':' ||
       CASE
         WHEN extension_name <> 'emaj'
           THEN 'NOT_E_MAJ'
         WHEN major * 10000 + minor * 100 + patch < 50001
           THEN 'UPGRADE_NOW'
         WHEN major * 10000 + minor * 100 + patch = 50001
           THEN 'OK_5_0_1'
         ELSE 'REVIEW_NEWER_THAN_5_0_1'
       END AS status
FROM parsed
ORDER BY database_name;

This SQLite script models extension inventory data and classifies which databases need action. It uses explicit version ordering instead of <> '5.0.1', so a newer synthetic training version is not mislabeled as below 5.0.1.

SQL (SQLite) · PostgreSQL: check whether the current database uses E-MajIllustrative · not executed
SELECT current_database() AS database_name,
       extname AS extension_name,
       extversion AS extension_version
FROM pg_extension
WHERE extname = 'emaj';

This is PostgreSQL-specific SQL, so it is not runnable in the SQLite sandbox. Run it in each PostgreSQL database you manage.

SQL (SQLite) · PostgreSQL: upgrade after installing the 5.0.1 extension filesIllustrative · not executed
-- Run only after testing and following your E-Maj/PostgreSQL upgrade procedure.
ALTER EXTENSION emaj UPDATE TO '5.0.1';

SELECT extname, extversion
FROM pg_extension
WHERE extname = 'emaj';

This shows the normal PostgreSQL extension-update shape. Validate it in staging and ensure the E-Maj 5.0.1 extension files are installed before running it in production.

Quick quiz

Q1. What is the exact output of snippet s1?
Q2. Your package inventory shows E-Maj files on a PostgreSQL server. What should you check next?
Q3. What is the main security risk described for E-Maj versions before 5.0.1?
Q4. Why should a runbook avoid using only `extension_version <> '5.0.1'`?

Key takeaways

  • E-Maj 5.0.1 is an urgent security update for PostgreSQL teams using E-Maj.
  • Check E-Maj usage per database, not just per server or package installation.
  • Do not use a blunt <> '5.0.1' check when you mean “below 5.0.1”.
  • Keep the upgrade auditable: inventory, test, change window, update, verify.
  • Do not treat application-level permissions as a substitute for applying the extension security fix.

References

See the full SQL learning path

Keep learning