Have you ever ran into a business requirement that you thought could not be done?
I’m talking about the cases when your answer was something between these lines: “We are the customers of NOW platform and we do not have access to the source code, there are limited things we can do and modify with SNOW”.
But how limited are you actually? How much is that related to the lack of knowledge?
I want to share the findings that allowed me to make a breakthrough as a SNOW developer to support integrations that are not supported officially by ServiceNow, like corporate mobile and other restricted applications related to security requirements.
So what can you do with the information below?
- Find undocumented system properties and use them
- Modify customer hidden UI pages – modify designers, fix role issues
- Fix compatibility issues for SNOW unsupported unique corporate applications
First you will need to modify one ACL rule. Elevate your role to security_admin, go to ACL’s menu, find the cache_inspect UI page read ACL rule and select the “admin overrides” checkmark and save it.
Now go to the cache_inspect page by typing cache_inspect.do in the filter navigator. You will be presented with the cache inspector (v2) tool.
Here you can browse through the Shared and Private cache. Shared cache is what is put to cache for use by all SNOW users. Private cache is something that is unique to the user’s cache. For example, his recently viewed UI pages, user criteria evaluations. If the user just logged in, his cache would not have as much information loaded as if he browsed through SNOW for an hour. This means that you will only see cached items here only If you visited it through the UI first.
Now select cache type: Private and locate “syscache_jelly_template” property. This contains all cached jelly templates (UI Pages).
Jelly files have .xml extension, so you will see a list of xml files in your cache inspector and the name of the plugin it came with. Now, if you click on each of them you will find the source code for each of the page in the details tab.
Let’s take $sp page which is page for any service portal. It loads $sp.xml to figure out doctype compatibility, then loads the sp.xml to figure out which portal you want to go to and does the rest. Let’s do a short POC to show this actually works for this article’s sake.
In the filter navigator go to UI pages and create a new one. Name it exactly as it is named in the cache without the .xml: $sp.
Paste the source code and modify it :
First remove the first line: java.lang.String (1112):
Next we can see that when opening any portal it first checks your browsers doctype compatibility, if it is fine, then it starts loading service portal, otherwise it redirects you to /ess page.
So, let’s just try the POC and do the opposite, if the doctype is compatible, do not load the portal, but redirect to /ess page.
Now we save it and we go to /sp and there it is, you get redirected to /ess. From the transaction log this is what we see (view_content.do is the UI page for /ess):
So why does it work and what is actually happening?
Because every time you try to load any type of resource it always first try to look in the database, if the database cannot be found for the record then it looks into application node files, usually in the JAR files or other non-compressed XML files.
All we need to do is put this in the database!
By creating a UI page, naming it $sp, the same name as it is named in the JAR file – $sp.xml, it will always load the file from the database first if it exists there.
But this is not supported by SNOW and is a customization?
Exactly, that is the reason why we would want to do it – to support something we have to support in our unique corporate environment that ServiceNow does not support officially. This can be labelled as a customization as well and could become maintenance issue if not handled properly. But if you are customizing in the right way then there is no problem modifying customer hidden content.