Where ERP Systems Actually Get Breached, and How to Close the Gaps

The breach that gets a CISO fired rarely starts with someone cracking a password. It starts with an integration account that was set up three years ago with full API access to "make onboarding easier," never revisited, and still active long after the contractor who requested it left. ERP systems hold the data attackers actually want - vendor bank details, customer PII, payroll, margin data - and the paths in are more mundane than ransomware headlines suggest.
Integration endpoints and APIs: the most common actual entry point
A mid-market ERP deployment typically has a dozen or more integrations running: EDI with major customers, a payment gateway, a payroll provider, a CRM sync, a shipping carrier API, maybe a business intelligence tool pulling nightly extracts. Each one is a credentialed connection into the core system, and each one tends to get provisioned during an implementation project under time pressure, then left alone for years.
The pattern that shows up repeatedly in incident reports: an integration account provisioned with broad read/write access because narrowing the scope would have taken an extra afternoon during setup, still holding that access long after the specific integration it was built for has changed or been retired. A manufacturer running a 2019-era EDI connection with a trading partner discovered during an audit that the service account tied to it had write access to the full customer master and general ledger posting - permissions nobody had reviewed since the original implementation, for a connection that only needed to read open sales orders and write shipment confirmations.
API keys embedded in scripts, scheduled jobs, or third-party middleware configurations are the other recurring problem: keys that don't rotate, keys checked into a code repository by accident, keys with no IP allowlist restricting where a valid credential can even be used from.
Over-privileged service accounts and stale access
Service accounts - the non-human logins used by integrations, scheduled reports, and automation - get created with admin-equivalent access as the path of least resistance, then almost never get revisited once things are working. Combine that with human accounts that don't get deprovisioned promptly when someone changes roles or leaves, and the actual exploitable surface of an ERP system is often much larger than the org chart of "who's supposed to have access" would suggest.
A useful audit exercise: pull every account with elevated access, not just admin-labeled roles but anything with broad read/write across financial or customer modules, and require a named business owner to justify it in writing within 30 days or it gets revoked. Run that exercise on a system that's been live for four or five years and it's common to find that a quarter or more of elevated-access accounts have no current legitimate reason to hold that level of access - former employees whose accounts were disabled but not stripped of role assignments, contractors from a project that ended a year ago, service accounts for integrations that were replaced but never decommissioned.
Segregation-of-duties gaps
This is less a hacking risk and more a fraud and error risk, but it belongs in the same conversation because the control failure looks identical from the outside: someone with access they shouldn't have, doing something the system should have blocked. Classic segregation-of-duties conflicts in ERP: the same user can create a vendor and approve a payment to that vendor, or create a purchase order and receive against it, or post a journal entry and approve their own posting.
Most ERP platforms ship with conflict-detection reports for exactly this, and most implementations never turn them on or review them after go-live. A controller running one for the first time on a system that's been live three years commonly finds dozens of active conflicts, not because anyone set out to create fraud opportunity, but because roles get assigned pragmatically during a short-staffed stretch, "just give Maria approval rights too, she's covering AP this month," and the temporary grant never gets revoked.
A distributor's own audit turned up exactly this pattern with real money attached: a single accounts payable clerk with both vendor-creation and payment-approval rights had set up a vendor with a name one character off from a legitimate supplier and routed payments to it over 14 months, totaling $92,000, before a routine vendor master cleanup flagged two "different" vendors sharing the same bank routing number. Neither the vendor-creation step nor the payment-approval step was individually suspicious. The conflict was that one person could do both without a second set of eyes on either.
Patch cadence: the on-prem versus cloud responsibility split, made explicit
This is where a lot of organizations have a gap they don't know they have. On a cloud-hosted ERP, the vendor patches the underlying application and infrastructure on their own schedule - but the customer is still responsible for their own integration middleware, their own single sign-on configuration, their own endpoint security on the devices accessing the system, and their own access reviews. Assuming "it's cloud, so security is handled" leaves those pieces unmanaged.
On an on-premises deployment, the customer owns patching end to end: OS, database, application layer, and any customizations that might break with an update, which is exactly why patches get deferred. A common pattern: a known vulnerability gets disclosed, a patch ships within weeks, and the patch sits unapplied for six months or more because the last update broke a custom report and nobody wants to risk that happening again without a full regression test cycle that competes with other project priorities.
Whichever model you're on, write down explicitly who owns each layer - infrastructure, application, integrations, identity, endpoints - because "the vendor handles security" and "IT handles security" are both dangerously vague answers that different people in the same organization will answer differently when asked. Organizations weighing a move from on-prem to cloud specifically to close this gap should model the actual cost difference, including the patching and infrastructure labor that disappears, with something like a cloud vs. on-prem calculator rather than assuming the security benefit alone justifies the switch.
What the incidents actually look like
Three patterns account for most real-world ERP-adjacent breaches, and none of them are exotic:
- Business email compromise leading to a vendor bank detail change. An attacker who's compromised email access, often not even the ERP itself, sends a convincing request to change a vendor's payment bank account. If accounts payable can update vendor banking details without a second approver and a callback verification to a known phone number, the next payment run wires funds straight to the attacker.
- Credential reuse from an unrelated breach. A user's ERP password matches a password exposed in a completely unrelated breach years earlier, and there's no multi-factor authentication on the ERP login. Credential-stuffing tools find the match in seconds.
- An abandoned integration credential. The scenario from the opening of this piece - a service account for a project that ended, never decommissioned, discovered and used by an attacker who found it through a leaked config file or a compromised vendor.
What this actually costs when it goes wrong
A mid-market manufacturer whose vendor bank details were changed through a spoofed email wired $187,000 to an attacker-controlled account before a mismatch against the originally verified account number surfaced on the next reconciliation - by then the funds had moved through two more accounts and only a fraction was ever recovered, months later, through the bank's fraud department. Beyond a direct fraud loss like that one, incident response on a mid-size ERP breach - forensics, outside counsel, and customer notification where personal data was exposed - commonly runs $75,000 to $250,000, separate from whatever was actually stolen.
The detection timeline is the other overlooked cost. Ransomware announces itself immediately. A misused credential doing something that looks like ordinary system activity, an integration account pulling a larger-than-usual customer export, a service account logging in from a new IP, does not, and the average time from initial compromise to detection for this kind of quiet credential abuse commonly runs into months rather than days. That gap is exactly what the access reviews and account inventories above are meant to close.
A practical hardening checklist
- Require multi-factor authentication on every human ERP login, no exceptions for "just the read-only reporting users."
- Inventory every integration and service account, assign a named owner, and set a recurring 90-day review.
- Run the segregation-of-duties conflict report quarterly, not once at implementation, and route findings to a real owner with authority to fix role assignments.
- Require a second approver plus out-of-band verification for any vendor banking detail change.
- Restrict API keys with IP allowlists where the integration's source is a known, fixed set of servers.
- Document the patch-responsibility split in writing, whether cloud or on-prem, and set a hard SLA for applying security patches even when it means scheduling a regression test.
- Deprovision access same-day on role change or termination, not on the next scheduled access review.
None of this requires exotic tooling. It requires treating the ERP's access model with the same seriousness as its financial controls, because functionally, for an attacker, they're the same target.