I'm writing a service which receives FHIR data and it stores it. FHIR is an HL7 healthcare information standard format which contains HTML by definition, embedded into a JSON or XML, (to ensure human-readability of the document)

How should I perform input validation in this case, to still be able to avoid XSS and other similar attacks?


By definition, the FHIR is asking you to preserve the XSS vulnerability of the data (store as code, display as code). XSS requires that the data be displayed back to users, which could be prevented with output validation, instead. Accept the input, store as JSON, filter when displaying the HTML data as HTML code. Depending on the "output" systems, this could be much easier (it depends on the need of the system).

Filtering out specifically bad code (malicious javascript, links, etc.) is going to be very difficult. There are lots of ways to hide bad code through obfuscation.

What you could do, depending on the details of the FHIR specification, is to whitelist good/acceptable code. If the FHIR spec is tightly defined, whitelisting should be easy to perform. If the spec is not tightly defined, it might be impossible to block all attempts at stored XSS.


I'm of the opinion that you should filter (block) xss input AND escape user-supplied input on output. Why? Because databases are long-lived and often shared, so should not contain xss. And web applications often use more than one data source.

If you're using Java, you can use Hibernate Validator with JSoup to parse and validate HTML input.

It has a WhiteListType, which lets you select which tags to allow. WhiteListType.NONE accepts no HTML tags, WhiteListType.SIMPLE_TEXT accepts b, em, i, strong, u.

You can always make your own white list too.


Your best bet is to probably not perform input validation, but perform some output sanitisation.

A sanitiser such as Google Caja can be used to strip script before it is output to the HTML page.

As there are often bugs found in sanitisers, often when there is a new addition or change to the HTML spec or implementation in a browser, it is recommended to combine this with a Content Security Policy. This is an HTML5 feature and it can prevent XSS attacks in supported browsers, because you effectively whitelist which scripts are allowed to run. Any injected by a user will fail with an error in the browser console.

The reason I recommend sanitising on output rather than input is because if there were any earlier input already in your database that bypasses the version of the sanitiser used at the time, this can often be fixed easily later by upgrading the sanitiser used to the latest version. If you sanitise on input this makes it more difficult as you then have to run all exisitng user inputs through the sanitiser each time you upgrade it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.