We at SAP use Static Application Security Testing (SAST) as one part of our secure Software Development Lifecycle (secure SDL). SAP has implemented this process framework to address security in all phases of the development lifecycle of its products. Automatic static source code scanning helps us detect software vulnerabilities during and after development.
As a consequence, we had to create our own SAST checks and enhance existing SAST checks to be run on top of a standard code analysis tool – in our case Checkmarx.
Checkmarx enables users to easily and intuitively customize SAST checks or define their own additional checks. This is typically necessary to support proprietary frameworks such as SAPUI5 that are not part of the standard checks provided by Checkmarx. This ensures that all real vulnerabilities are identified and helps in eliminating false positives. A simple programming language is available as well as a supporting tool that enables users to create new checks, experiment changes to existing checks, and save these changes to the server.
Example: XSS in custom SAPUI5 control
a) Example.js – Control Definition (properties + behavior)
b) ExampleRenderer.js – Control Implementation (actual HTML output)
Careful readers of the SAPUI5 API documentation might have already recognized the culprit in line 15 of ExampleRenderer.js. The developer wanted to spare some effort by putting three components of <span> tag (opening, text content, closing) together in one write() call, resulting in the generation of HTML with free text, without output encoding. This is a typical pattern of XSS, especially when we consider that UI controls are usually contained in reusable libraries which have no idea about their input validity if data type is string. This allows the presence of arbitrary texts therein, including malicious scripts.
How a SAST tool can reliably identify this vulnerability?
Reliability can be understood like this: code scanning results shall be complete and sound. In other words, always detect the issue and do not bug developers with false alarms. In our example it means:
- A code scan tool has to recognize that a custom SAPUI5 UI control is being scanned. In our showcase, Example.js is (possibly indirectly!) inherited from ui.core.Control (line 8 of Example.js).
- Then find the properties of that control (metadata needs to be analyzed).
- Check the properties in case they have dangerous, untrusted data types, like a string, e.g. “text” in our case (line 12 of Example.js).
- Find renderer implementation of the same control, i.e. ExampleRenderer.render(oRm, oControl) for this showcase (line 9 of ExampleRenderer.js).
- Look for references of untrusted properties. That would be oControl.getText() – where oControl is named after second parameter name of render(oRm, oControl) function, getText() is named after property name (line 15 of ExampleRenderer.js).
- Search for dangerous contexts where this untrusted data can end up as data flow sink, e.g. oRm.write(… + oControl.getText() + …) where oRm is named after the first parameter name of render(oRm, oControl) function).
This is a very complex challenge because:
- Some of the above points contain “educated guess” for a SAST tool. Semantics and contracts behind SAPUI5 APIs shall be well understood (like naming conventions) and artifact relationships which are generated only during runtime need to be modeled. “Duck typing” is heavily used in SAPUI5!
- There are multiple data types that are not validated by framework
- There are multiple methods providing direct HTML output without encoding
- There are diverse approaches for custom control implementation (“notepad” controls vs. libraries, current vs. legacy coding, etc.)
- There are various sanitizations available (like validation, encoding) that are provided by SAPUI5 itself
- And all of these shall be handled properly to achieve our goal to obtain reliable code scan results.
We jointly developed a custom check for detecting potential XSS in SAPUI5 controls that is exactly performing the steps described above with Checkmarx.