Creating Secure ThingWorx Widgets
When you create customized widgets, ensure that you create secure widgets. You must account for cross-site scripting (XSS) and cross-site request forgery (CSRF) vulnerabilities. See the section Updating the Request Method and Content Type Filtering for CSRF Protection for more details.
The next sections provide best practices for creating secure widgets.
Use Encoding for HTML Output Value in Widgets
If you use widgets to display values in the user interface, it is recommended to use the HTML encoding. See the following sample code:
this.updateProperty = function (updatePropertyInfo) {
if (updatePropertyInfo.TargetProperty === 'Text') {
var labelText = Encoder.htmlEncode(updatePropertyInfo.SinglePropertyValue);
thisWidget.setProperty('Text', labelText);
showLabelText(thisWidget.getProperty('Text'));
}
}
In this example:
The function updatePropery() is called every time the bound value for a widget property changes.
The value from the widget is HTML-encoded using the encoder library.
After encoding, use the Get and Set methods to access this new value.
This step ensures that the Get methods perform extra sanitization on the values being returned to the user interface.
Use Decoding and jQuery for HTML Output Values in Widgets
If you use widgets to display values in the user interface, and have used the HTML encoding to encode values, use the HTML decoding to convert the encoded value to its original value. See the following sample code:
function showLabelText(labelText) {
labelText = Encoder.htmlDecode(labelText);
var spanText = thisWidget.jqElement.find('.label-text');
spanText.text(labelText);
}
In this example:
The function showLabelText is used to get the DOM element of the widget and update the value.
Decode the value using the encoder library.
Use the text() method with jQuery on the DOM element to display the value. This method has built-in escaping function that helps in securing the solution against the XSS vulnerability.
Use Encoding for HTML Output in JavaServer Pages (JSP)
If you use JSP to display values in the user interface, it is recommended to use the HTML encoding. You can use ESAPI Utilities from OWASP to handle encoding on a contextual basis. See the following sample code:
<div class="org-info">
<h1 class="orgName">
<%=ESAPIUtilities.getEncoder().encodeForHTML(orgName)%>
</h1>
<p class="orgDescription"><%=ESAPIUtilities.getEncoder().encodeForHTML(loginPrompt)%></p>
</div>
In this example:
Users can create their own login pages for ThingWorx.
The following fields require a user input for a login screen:
orgName
loginPrompt
The data in these fields is untrusted data. There is a potential threat that the user may enter malicious characters for these fields. Therefore, it is required to run this data through the ESAPI utilities for HTML encoding.
Secure Custom User Interfaces
You can build your own custom user interfaces by developing extensions, or have your own hosted Web solutions that consume the ThingWorx REST APIs. In these scenarios, you should ensure that the data is sanitized and encoded before it is displayed in the browser.
Make sure you understand the frameworks that you are implementing, and use the best practices for that environment to safeguard the solution against the XSS vulnerabilities.
In the following example, an AngularJS solution uses a template that was imported as an extension. You can use ThingWorx Utilities to build this workflow.
<div class="node-label-wrap" ng-class="{'graph-node-nonadmin': $parent.$parent.isNonAdminUser}">
<textarea type="text" ng-model="node.label" ng-change="$parent.$parent.setBPUpdatesMade()">
</textarea>
<div class="node-label">{{node.label}}</div>
</div>
In this example:
node.label is the untrusted user input. It is an arbitrary string. users provide the name of the label for the workflow node.
In the templates of AngularJS solutions, if you wrap an untrusted input in double curly brace notation {{}},for example {{node.label}}, it forces a string interpolation. The value is treated as a string and is not executed in the context of a script.
HTML Responses
PTC documents its HTML responses in a common class that filters any output through the ESAPI Utilities.
public void writeTableCell(String value, String id, String sClass, String sStyle) throws Exception {
startTableCell(id, sClass, sStyle);
writeValue(value);
endTableCell();
}

public void writeValue(String value) throws Exception {
write(ESAPIUtilities.getEncoder().encodeForHTML(value));
}
Was this helpful?