Skip to main content

XPages ${} risk of code injection

While working on app optimization I experimented a bit more with 'Compute on page load' vs. 'Compute dynamically' behavior. There have been several discussions in past about possible combination of ${} and #{}, for example posts from Marky RodenSven Hasselbach and Paul Withers . What struck me today was risk of code injection.

In this app many elements are read from configuration documents that are loaded into beans and later used using ${} binding. This is recommended way as it is static information, so it's efficient. It works nicely until you insert expressions into your data. This way I realized that a lot of code is prone to code injection that can be contained either in configuration documents or any string that is stored and later read this way.

To simulate the issue I created simple page with one field, one button and one text:

All it does is saving entered value into applicationScope and then displaying it. Since the text uses ${} Compute on page load, I have to reload whole page to see the result immediately.

So now to the results. Normal user would probably enter something like 'Hi there'
But more advanced user can try 'Now is #{javascript:new Date()}'
(Also note that if you do partial refresh to the text, date gets updated as it's computed every time)

If he stops being nice to your app, he will switch to
 'You #{javascript:database.getAllDocuments().removeAll(true);'had'} data'
Once he gets bored, he can finish his job with
'You had #{javascript:sessionAsSigner.getDatabase('','names.nsf').getAllDocuments().getCount()} documents in address book, but 
now you have 0.  #{javascript:sessionAsSigner.getEffectiveUserName()} did that.'
(dev/pradny is name of the server as I signed the db with server ID as many admins do)

(one part is missing in previous example as I wasn't brave enough to run full version on my server to take a screenshot, you get the idea...).

The problem is not how you get the data, but how you use it. It can come from field, configuration or computation. With great power comes great responsibility. Just be aware that ugly things can happen, which reminds me of a question. Is your son's name really Robert';) Drop Tables?

Update (15.8.2016)
 Possible workaround in next post


  1. In talking to Jesse Gallagher... my impression is that the biggest risk here is data coming in from the URL. I mean I see you're point but I'm not sure I've ever used ${} to get user input and then done a full page load like that.
    I use pageControllers for everything.. inside is helper methods to easily get the URL parameter... not tested but IN THEORY we could sanitize any parameters and strip out the #{} binding.

    public String getParam(final String key) {
    if (!this.getQueryString().containsKey(key)) {
    return null;
    } else {
    String temp = this.getQueryString().get(key);
    String sanitize = temp.replaceAll("\\#\\{[^\\}]+\\}", "");

    return sanitize;


    public Map getQueryString() {
    final Map qs = (Map) ExtLibUtil.resolveVariable("param");
    return qs;

    1. Good idea, I'll have to check my projects how I deal with url parameters. I bet in some cases I may have a problem.

      Full page reload was used just to create easy demo. It doesn't matter how you get your data, so if your pageController reads a String form somewhere, it can have such problem. I bet I have problems in place, where I compute static texts from data using controller like page title or section labels.


Post a Comment

Popular posts from this blog

Microsoft Word black box in numbering issue

This is awkward post, primarily to save the solution for future me. I have seen many people mentioning this problem over years and as I've struggled with it several times, I needed to find final and permanent solution. All editions of Microsoft Word from time to time suffer from bug in numbering. Instead of a number, black box is displayed. Sometimes it happens right after document is opened, sometimes during editing. Probably some internal structure of document gets corrupted, so based on level of corruption, different fixes could help. Many of them are listed at I took different approach. Since docx is just standard zip package with xml files, I decided to try if I can fix it manually. And it worked. When I extracted the docx, there was file called numbering.xml in word folder. When I examined that file, I found strange se

WSL, HCL Volt and some Docker

My list of new technologies to try was growing fast in past months, but now I finally can try to catch up with all the cool improvements that can be used to enhance my/your dev experience. Microsoft has enhanced the Windows Subsystem for Linux this year and Docker completely changed the way Docker Desktop for Windows is integrated into the operating system. The most important change for me was that I can finally run Docker Desktop and VMWare Workstation on my machine in parallel. When I was looking for some good use cases to try how it works, HCL Domino was a logical choice. HCL started to even publish official Docker images for every release and some pre-releases are only available as Docker images. I have many test Domino machines running in VMs, but I had no HCL Volt. If you don't know that HCL Volt is - it's a new low-code platform that brings HCL Form Builder experience, now know as HCL Leap, to HCL Domino, which then serves as a data store and application server. Whe

HCL Domino SSO with Microsoft Teams

 Microsoft Teams is probably one of the most used tools this year, it was already quite popular before the pandemic started to spread across the world this spring, but now most of the businesses I work with use it. After using it just like a chat/conferencing tool, many start to explore further capabilities of the platform. When working with Domino data in apps that are web-enabled, it can be quite easy - just add a web tab anywhere you want. The problem is, that you need to deal with user authentication.