Security

A remote-access portal without MFA, and nine days before the ransomware

Testimony from 2024 describes a short path from one stolen credential to a ransomware attack. An inventory of access paths is the first defence.

Published 6 min read

Jump to the access map
An ambulance parked outside a hospital emergency entrance

Photo: Ambulance outside Emergency Entrance, Caloundra Hospital, 2025, Chris Olszewski, CC BY-SA 4.0, via Wikimedia Commons.

In February 2024, Change Healthcare, a subsidiary of UnitedHealth Group, was hit by ransomware. On 1 May 2024, UnitedHealth's CEO, Andrew Witty, testified to a US House committee. In a prepared statement, reported by TechTarget, he said that on 12 February criminals used compromised credentials to remotely access a Change Healthcare Citrix portal, an application used to enable remote access to desktops.

The statement said the portal did not have multi-factor authentication, and that ransomware was deployed nine days later. UnitedHealth attributed the attack to the BlackCat group, also known as ALPHV. Witty said the decision to pay a ransom was his, calling it one of the hardest decisions he had ever had to make. He told lawmakers he was disappointed that this particular server did not have MFA, according to Healthcare Innovation.

The gap between a policy and a setting

Reporting noted that multi-factor authentication was a company-wide requirement at UnitedHealth, and Witty told lawmakers that the company now enforced it on all external systems. The lesson is not about one vendor. A policy that says "every external system needs MFA" only protects the systems someone knows about and has checked.

Old portals, test environments, vendor connections and acquired companies' systems tend to fall outside any list. They are also the places attackers look first, because they are less likely to be monitored and more likely to rely on a single password.

Build a map of how data is reached

Start with a table. For every system that holds data, list every way in: who can connect, from where and how they authenticate. A spreadsheet works. A small SQLite table works better, because you can ask it questions. This sketch was run and returns the risky rows.

SQL
CREATE TABLE access_path (
  id INTEGER PRIMARY KEY,
  system TEXT NOT NULL,
  path TEXT NOT NULL,
  internet_facing INTEGER NOT NULL CHECK (internet_facing IN (0, 1)),
  mfa_enforced INTEGER NOT NULL CHECK (mfa_enforced IN (0, 1)),
  owner TEXT,
  last_reviewed TEXT
);

INSERT INTO access_path (system, path, internet_facing, mfa_enforced, owner, last_reviewed) VALUES
  ('claims-db', 'VPN + SSO', 0, 1, 'dba-team', '2026-09-01'),
  ('remote-desktop', 'remote portal', 1, 0, NULL, NULL);

-- Exposed to the internet with no MFA
SELECT system, path, owner
FROM access_path
WHERE internet_facing = 1 AND mfa_enforced = 0;
-- remote-desktop | remote portal | NULL

Each row the last query returns is a task for this week. A row with no owner is a finding in its own right: nobody is responsible for a way into your data.

SQL
-- Paths nobody owns, or that were never reviewed
SELECT system, path
FROM access_path
WHERE owner IS NULL OR last_reviewed IS NULL;

Check the database's own front door

In PostgreSQL, the view pg_hba_file_rules shows the rules in pg_hba.conf that decide who may connect and how. This query was run on a throwaway server and shows how easy it is to spot a login method that asks for no password at all:

SQL
SELECT line_number, type, database, user_name, address, auth_method
FROM pg_hba_file_rules;

-- line | type  | database | user_name | address   | auth_method
--  117 | local | {all}    | {all}     |           | trust
--  119 | host  | {all}    | {all}     | 127.0.0.1 | trust

The method trust lets matching connections in without a password. That is the default for a local test cluster and is fine on a laptop. On a server reachable from the network it is a hole. Look for trust, for wide address ranges such as 0.0.0.0/0 and for rules that allow every user. Replace them with scram-sha-256 and specific addresses.

SQL
-- Rules that let anyone in without a password
SELECT line_number, database, user_name, address
FROM pg_hba_file_rules
WHERE auth_method = 'trust' AND type <> 'local';

The nine days

According to the statement, ransomware was launched nine days after the credentials were first used. That is a window in which an intrusion could have been noticed. Defenders usually catch attackers by watching for behaviour that does not fit: a login from a new country, a service account used interactively, a large amount of data leaving at night.

  • Log every remote login, successful or not, to a place the account holder cannot edit.
  • Alert on a first-time login from a new location, and on logins outside working hours.
  • Alert on large transfers out of databases and file stores.
  • Make it fast to cut one account or one network path without taking everything down.
  • Practise the response before you need it: who decides, who calls whom, how you restore.

A database can help with that last point by recording who connected. PostgreSQL has log_connections and log_disconnections settings that write each connection to the server log. Turn them on and ship the log elsewhere.

What kind of MFA

MethodStrengthNote
Hardware security key or passkeyStrongResists phishing by tying sign-in to the real site.
Authenticator app codeGoodBetter than a text message, but a code can still be phished.
Text message codeWeakerBetter than nothing, and vulnerable to SIM swapping.
Password onlyWeakOne stolen password is all it takes.

A plan for this week

  1. 01List every way inRemote desktops, VPNs, admin consoles, vendor logins, database ports, file-transfer tools.
  2. 02Mark the ones facing the internetThese come first.
  3. 03Check MFA on eachDo not trust the policy. Look at the setting, or try to log in.
  4. 04Name an owner for every rowNo owner, no access.
  5. 05Shut down what nobody needsAn unused portal is risk with no benefit.

Notice the login that does not fit

You cannot watch every login by eye, but a query can ask whether a login is new. This SQLite sketch keeps a table of connection events and returns logins from an address a user has never used before, for users who have logged in earlier. It was run on sample data.

SQL
CREATE TABLE login_event (
  id INTEGER PRIMARY KEY,
  user TEXT NOT NULL,
  ip TEXT NOT NULL,
  client_app TEXT NOT NULL,
  at TEXT NOT NULL
);

-- First time this user has connected from this address
SELECT e.user, e.ip, e.client_app, e.at
FROM login_event e
WHERE NOT EXISTS (
        SELECT 1 FROM login_event p
        WHERE p.user = e.user AND p.ip = e.ip AND p.at < e.at)
  AND EXISTS (
        SELECT 1 FROM login_event p
        WHERE p.user = e.user AND p.at < e.at);
-- ann | 198.51.100.9 | DBeaver | 2026-10-20 03:12

The result is not an accusation. A person may be travelling or working from a new place. It is a prompt to check, and a pattern worth alerting on if it happens at 3 a.m. from an unfamiliar client. Add a second condition for the time of day, or for a client application the user has never used.

Backups that ransomware cannot reach

The CISA and FBI advisory on the MOVEit campaign recommends maintaining offline backups, with encrypted and immutable copies, and segmenting networks to prevent the spread of ransomware. Those apply here as well. A backup that sits on a share the attacker can reach is another file to encrypt.

  1. 01Keep a copy offline or immutableUse storage the production credentials cannot write to or delete.
  2. 02Test a restore on a scheduleTime it. Recovery time is what you will actually have to live with.
  3. 03Separate the keysThe keys that decrypt backups should not live on the systems being backed up.
  4. 04Write the runbookWho declares an incident, who restores, in which order, and who tells whom.

Questions that come up

Would MFA have stopped this?
UnitedHealth's account is that the missing MFA on that portal was how stolen credentials were enough. MFA is not a complete defence, but it removes that route.
Who should own the access map?
A named person for each system. An owner turns a list into action.
Is paying a ransom recommended?
This article takes no position on that. It is a decision for the organisation, its lawyers and the authorities, and the testimony describes it as a very hard one.
How often should I review access paths?
At least every quarter, and whenever you add a vendor, a system or a company.

Sources