TL;DR: Four operational and architectural failures from the LastPass breach, each fixable with patterns that existed in 2022.

  1. Engineers with privileged access were permitted to run non-current macOS versions, which Apple has been shown to delay patches for, if they release them at all. This is a problem for organizations that stay 1 macOS version behind and follow the “patch within 30 days of availability” policy.
  2. Source code contained cleartext secrets instead of references to secrets fetched at runtime from a secrets manager.
  3. The decryption key for customer vault backups was stored in a LastPass vault instead of an HSM, and the rotation cost of that arrangement distorted the incident response in a dangerous direction.
  4. AWS credentials in the compromised vault had no IP, MFA, or VPC restrictions, so they worked from anywhere the moment the attacker had them.

The detailed arguments and fixes are below.

Intro

The 2022 LastPass breach is the security industry’s reference case for what happens when a sophisticated attacker breaches a company that handles other people’s secrets. Three years of post-breach root cause analysis has focused on the customer impact and on the obvious Incident 2 entry point of the DevOps engineer’s personal Plex server. What has not been covered is how Apple’s structural patching gap could leave organizations compliant with patching policy yet dangerously exposed, the impact of storing secrets in source code, how encrypting data with SSE-C was actually the worst design choice possible, and the framing LastPass used to deflect the Plex criticism.

The attacker exfiltrated encrypted customer vault backups that have been slowly cracked offline for the last three years, producing a long tail of follow-on attacks against LastPass customers. The on-chain analysis firm TRM Labs has traced hundreds of millions of dollars in cryptocurrency theft to the breach, much of it flowing through Russian-associated infrastructure, including a single $150 million XRP theft from Ripple co-founder Chris Larsen in 20241. LastPass itself has faced a £1.2 million penalty from the UK Information Commissioner’s Office2, an $8.2 million class action settlement3, and the kind of reputational damage that’s hard to quantify but easy to see in the company’s diminished market position.

1) Apple’s Structural Patch Gap

LastPass’s Incident 1 post-mortem indicates that a developer’s laptop was compromised starting August 8, 2022. Logs relevant to the investigation were destroyed during an OS upgrade that occurred around the same time, meaning that a definitive entry point cannot be identified. Working backwards, an upgrade in August 2022 would have been from Big Sur to Monterey, which was released 11 months earlier.

The problem is that Apple has a systematic pattern of delaying or even not releasing security patches on non-current operating systems even when they are still officially supported. Joshua Long has documented how Apple often delays or neglects to backport patches to previous macOS versions entirely. One example is CVE-2022-22675, an AppleAVD vulnerability that allowed kernel-privileged code execution and was actively exploited in the wild. Apple patched it in macOS Monterey 12.3.1 in late March 2022 but did not patch Big Sur until the May 2022 round of security updates. Long estimates that 35–40% of CVEs fixed on the current OS never receive patches for older supported versions at all, leaving users on N-1 exposed indefinitely to a separate category of vulnerabilities4.

Organizations that follow a patch-within-30-days policy may believe they are protected, but this approach fails on N-1 systems where patches arrive weeks or months late if at all. Sophisticated attackers systematically exploit this gap by reading Apple’s security bulletins and targeting CVEs that remain unpatched on previous macOS versions. The defensible posture is to require engineers with production access to stay on the current major version of macOS and treat one-version-behind as a temporary testing state, not a production operating environment.

2) Secrets in Source Code

LastPass’s March 2023 incident report acknowledged that the 14 exfiltrated repositories included cleartext embedded credentials, stored digital certificates, and encrypted credentials used for production. Most coverage mentions this in passing before moving on to the downstream effects. It deserves more attention because it is the failure that made everything else consequential. If the source code had contained references to secrets rather than secrets themselves, Incident 1 ends with the attacker holding architectural documentation and nothing else useful. The DevOps engineer in Incident 2 still gets compromised via Plex, but when the attacker pulls the contents of his vault, there is no decryption key for the backup infrastructure to find, because there is no decryption key in a vault to begin with.

The correct pattern is that source code never contains secrets, only references to them. At runtime, the application fetches the actual secret from a dedicated secrets manager using its workload identity, and the secret never touches disk on the developer’s machine, the build artifact, or the repository. AWS Secrets Manager, HashiCorp Vault, Google Secret Manager, and Azure Key Vault all implement this pattern. The mechanics differ slightly but the shape is the same: the application asks “give me the secret named X,” the secrets manager checks whether the caller’s identity is authorized to read X, and if so returns it.

Here is what this looks like in practice for a Python service running on ECS or Lambda:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import boto3
import json

def get_database_credentials():
    client = boto3.client('secretsmanager')
    response = client.get_secret_value(SecretId='prod/db/primary')
    return json.loads(response['SecretString'])

creds = get_database_credentials()
conn = psycopg2.connect(
    host=creds['host'],
    user=creds['username'],
    password=creds['password'],
    dbname=creds['dbname'],
)

The application code contains the name of the secret (prod/db/primary), not the secret itself. The boto3 client uses the task’s IAM role to authenticate to Secrets Manager. The IAM policy on that role is what controls access:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": "secretsmanager:GetSecretValue",
    "Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/db/primary-*",
    "Condition": {
      "StringEquals": {
        "aws:SourceVpce": "vpce-0abc123def456"
      }
    }
  }]
}

Three things are happening in this policy that matter. The Resource is scoped to one specific secret, not *, so a compromised task can only read what it needs. The aws:SourceVpce condition restricts the call to a specific VPC endpoint, so the secret cannot be retrieved from outside the VPC even with valid credentials. And there are no long-lived access keys anywhere in this picture; the ECS task assumes a role and gets short-lived credentials that rotate automatically.

The repository now contains a config file like this:

1
2
3
database:
  secret_id: prod/db/primary
  region: us-east-1

If an attacker exfiltrates this repository, they get the name of a secret they have no way to retrieve. They learn that the application uses a PostgreSQL database in us-east-1, which is architectural information of roughly the same value as the README. They do not get credentials.

Detection is the other half of the pattern. Pre-commit hooks like gitleaks or trufflehog scan staged changes for things that look like secrets and refuse the commit if they find one. CI pipelines run the same scanners on every push as a backstop. GitHub’s secret scanning runs continuously on public repositories and will notify a list of partner providers (AWS, Stripe, Slack, etc.) when it finds a credential issued by them, who will then automatically revoke it. None of this is exotic, none of it is expensive, and all of it existed in 2022.

3) Encryption Keys Belong in an HSM

LastPass encrypted their S3 backups with SSE-C, which means the customer generates the key, sends it to S3 on every API call, and AWS discards it after each operation5. The decryption key for the SSE-C key was stored in the personal LastPass vaults of four senior engineers. If the threat model says LastPass could not trust AWS KMS with their key material, the correct answer was CloudHSM or an on-premises HSM with client-side encryption, not a 256-bit value stashed in a password vault. LastPass was already running physical datacenters for production, so the infrastructure was in place. An HSM keeps the key material inside a hardware boundary, logs every cryptographic operation with the calling identity, and lets you revoke access with a policy change that takes effect in seconds.

An HSM would not have prevented the initial compromises. Someone authorized to decrypt backups for disaster recovery can still be impersonated by an attacker who compromises their workstation. What an HSM would have changed is the shape of LastPass’s response to Incident 1. After Incident 1, LastPass knew the attacker had obtained the encrypted SSE-C key from the compromised repository. They rotated the AWS access keys between August 16 and 18. They did not rotate the SSE-C key, because rotation meant re-encrypting terabytes of backup data and they assessed that the decryption key was still safely held. Two days later, one of those vaults was compromised. With an HSM, the equivalent precautionary response is revoking the compromised principal’s access, which is cheap enough that there is no cost-benefit calculation to get wrong. The SSE-C rotation cost distorted the response in a dangerous direction, and the attacker’s window between Incident 1 and Incident 2 was exactly the kind of window that a cheaper response would have closed.

4) Allowing Personal Devices

The LastPass public disclosures about device controls use a rhetorical pattern I see constantly in vendor risk assessments. The company is careful to specify what employees could not do: access the “network” without a company-provided laptop, MFA, and Cisco AnyConnect. 6 Read quickly, this sounds like a strong statement about device trust. Read carefully, it is a statement about one specific network, with everything else left unsaid. Everything in it is technically true, and the gaps it leaves open are where the breach happened.

What the statement does not say is what “network” actually covers. It does not cover the LastPass web application itself, which was reachable from any browser. It does not cover corporate vaults, which were accessed from whatever machine the engineer happened to be using. It does not cover the backup infrastructure, which was a separate cloud environment that ran on AWS. The scope of systems an engineer needed to compromise to reach customer vault backups does not overlap with the scope of systems LastPass’s device policy actually governed.

The ICO found that a keylogger captured the DevOps engineer’s master password, and a stolen trusted device cookie allowed the attacker to bypass MFA on the LastPass web application entirely. The web application was not on the “network,” so device policy never mattered. The second incident followed the same pattern at a different layer. The entry point was not a company laptop failing a control; it was an exploitable Plex server running on an engineer’s personal computer, which was not a LastPass device at all. The engineer was using that personal computer to access his corporate LastPass vault, which held the decryption keys the attacker eventually used to unlock the exfiltrated customer backups. The personal computer was outside the scope of any LastPass device policy, because LastPass’s device policy was scoped to their internal network, and a personal computer on an engineer’s home LAN is not on their internal network by definition.

The credential failure compounds the framing failure. Once an attacker was on the engineer’s personal machine with access to his LastPass vault, the AWS credentials in that vault worked from anywhere. There was no constraint on where they could be used from, no constraint on how they could be used, and no constraint on how long they remained valid. AWS provides several IAM condition keys that constrain where and how credentials can be used, and a sufficiently restrictive combination would have made the exfiltrated credentials nearly useless outside the corporate environment. The strongest pattern is restricting the credentials to specific VPC endpoints, which keeps the traffic off the public internet entirely:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": "*",
    "Resource": "*",
    "Condition": {
      "StringEquals": {
        "aws:SourceVpce": "vpce-0abc123def456"
      },
      "Bool": {
        "aws:MultiFactorAuthPresent": "true"
      }
    }
  }]
}

Three things are happening in this policy. The aws:SourceVpce condition restricts the call to a specific VPC endpoint, which means the credentials cannot be used over the public internet at all, even with valid keys. The aws:MultiFactorAuthPresent condition requires MFA at the API call level, not just at the console login level, so exfiltrated long-lived keys without MFA tokens cannot be used. And the policy could be combined with short-lived STS credentials issued by an SSO provider rather than long-lived access keys, which means the credentials a vault contained would expire on their own within hours of exfiltration regardless of any other control.

Where VPC endpoint restrictions are not possible, IP-based conditions restricting use to the corporate VPN range are a weaker but reasonable fallback. Policies using aws:SourceIp need to be written carefully: AWS services making calls on behalf of the user appear to originate from AWS infrastructure rather than the user’s IP, so production policies often need a companion aws:ViaAWSService condition to allow legitimate service-chained calls.

The framing question I started this section with applies here too. A vendor who tells you their “internal systems” require MFA is not answering the question you asked. The question is which systems an attacker has to reach to hurt your customers, and whether the controls the vendor described cover all of them. An exfiltrated vault containing credentials that only work from inside a specific VPC, with MFA, and that expire in an hour, is an exfiltrated vault that does not unlock customer backup infrastructure two days later. LastPass’s answer to the framing question, in retrospect, was no.

Conclusion

The LastPass breach is not a story about novel attack techniques or zero-day exploits that no one could have anticipated. It is a story about four decisions that created compounding failure modes: allowing engineers with production access to run outdated operating systems, embedding secrets directly in source code, choosing an encryption pattern with prohibitive rotation costs, and scoping device policies to internal networks while leaving cloud infrastructure unprotected.

Each of these failures was preventable with controls that existed in 2022. Requiring current macOS versions for production access, using dedicated secrets managers with workload identity, storing encryption keys in HSMs with revocable access policies, and restricting cloud credentials to VPC endpoints with MFA are not exotic practices. They are the baseline for organizations that handle other people’s secrets. The gap between what LastPass described in their public disclosures and what their controls actually protected is the gap where $150 million in cryptocurrency disappeared and where customer trust evaporated.

The question for any organization in a similar position is not whether your controls sound good in a vendor questionnaire. The question is whether the systems an attacker needs to reach to hurt your customers are actually covered by the controls you claim to have in place.

Sources


  1. TRM Labs, “TRM Traces Stolen Crypto From 2022 LastPass Breach; On-Chain Indicators Suggest Russian Cybercriminal Involvement,” https://www.trmlabs.com/resources/blog/trm-traces-stolen-crypto-from-2022-lastpass-breach-on-chain-indicators-suggest-russian-cybercriminal-involvement. Ian Allison, “Ripple Co-Founder’s $150M XRP Heist Related to LastPass Hack: ZachXBT,” CoinDesk, March 8, 2025, https://www.coindesk.com/tech/2025/03/08/ripple-co-founder-s-usd150m-xrp-heist-related-to-lastpass-hack-zachxbt↩︎

  2. UK Information Commissioner’s Office, Penalty Notice – LastPass UK Ltd, November 2025. ↩︎

  3. In re LastPass Data Security Incident Litigation, settlement details at https://www.lastpasssettlement.com/↩︎

  4. Joshua Long, “Apple Neglects to Patch Two Zero-Day, Wild Vulnerabilities for macOS Big Sur, Catalina,” Intego Mac Security Blog, https://www.intego.com/mac-security-blog/apple-neglects-to-patch-zero-day-wild-vulnerabilities-for-macos-big-sur-catalina/. The 35–40% figure on Mac patch coverage gaps and Mickey Jin’s reverse-engineering of the CVE-2022-22675 Monterey patch are both sourced from this article. ↩︎

  5. LastPass, “Notice of Recent Security Incident,” December 22, 2022, and “Update on the December 2022 Security Incident,” March 1, 2023. Details on SSE-C key storage and rotation timeline from these disclosures. ↩︎

  6. LastPass, “Incident 1 – Additional details of the attack,” March 2023 incident disclosure. The direct quote about company-provided laptops and the Cisco AnyConnect VPN requirement is from this document. ↩︎