Navigating XSSFilter Impact on Bahmni - Seeking Ecosystem Best Practices for Decoding

Dear OpenMRS Community,

Following the critical OpenMRS security advisory here, the Bahmni core team has diligently upgraded affected dependencies and released a new patch. We deeply appreciate the ongoing commitment to security within the OpenMRS ecosystem, especially the introduction of the XSSFilter to prevent stored XSS attacks.

However, since this XSSFilter has been configured to process all REST API requests through a servlet filter, we’ve begun to observe several integration challenges and functional breaks in various downstream systems and community implementations after the patch upgrade. While the security intent is clear and valued, the blanket application of the owasp.encode.Encode.forHtmlContent encoding is causing unforeseen side effects.

We’ve identified a few critical areas where this encoding strategy is impacting data integrity and system functionality:

  1. Global Property Data Corruption: When saving global properties that contain special characters (e.g., &, <, >), these characters are now being HTML-encoded and persisted directly into the database. This alters the intended plain text values and can break configurations or integrations expecting the original string.
  2. External System Sync Issues (e.g., Odoo): Drug names, for instance, when entered with an ampersand (&) symbol, get encoded by the filter (e.g., to &amp;). When this data is subsequently synced to downstream systems like Odoo, the encoded text (&amp;) is what gets stored and displayed, leading to incorrect and unprofessional presentation of drug names and other critical patient data.
  3. Form Event JavaScript Code Breakage: OpenMRS forms that include JavaScript code within form events are failing to render correctly. The XSSFilter is encoding the JavaScript code itself when the form definition is saved, rendering it inert and unusable for client-side logic. This significantly impacts the dynamic behavior of forms built with this feature.

Given Bahmni’s broad integration touch points with various external systems and internal functionalities that rely on plain text data representation, we’re keenly looking to understand how the broader OpenMRS ecosystem is addressing these encoding challenges. Specifically, we’d like to explore:

  • What approaches are other implementations taking to effectively “decode” or properly handle these HTML-encoded values at various integration points (frontend display, backend processing, external system synchronization) without reintroducing XSS vulnerabilities?

  • Are there recommended patterns or best practices for selectively applying encoding, or for robustly managing data integrity across systems when such a broad XSS filter is in place?

  • How are you managing scenarios where fields are intended to contain raw text vs. fields that might genuinely contain HTML or executable code (e.g., form event JavaScript)?

Any thoughts, insights, architectural patterns, or specific code examples on how your implementations are navigating these challenges would be immensely valuable.

Thank you for your time.

@angshuonline @rahu1ramesh @arshiya_sehzad @akhilmalhotra @devsingh05298 @taseew @ibacher @grace @dkayiwa @raff @mseaton

Best regards,

The Bahmni Core Team

The general practice has been unescaping before use, as you can see from some of these commits: Commits · openmrs/openmrs-module-legacyui · GitHub

We are generally dealing with this on a case by case basis, and in some cases we have overridden the default by storing unescaped xml, where it doesn’t substantially increase the risk. Here is an example: HTML-858 - Unescape submitted xml on htmlform admin page. by mseaton · Pull Request #314 · openmrs/openmrs-module-htmlformentry · GitHub

By default, anything served via the /ws/ prefix shouldn’t be run through the filter. You can also provide a custom csrfguard.properties file with whatever exclusions make sense.