Security Scanning a SharePoint Framework Solution
The SharePoint Framework has been around for a while now and is being adopted by many of you, whether using on-premises SharePoint 2016 or SharePoint Online. The tooling is made up of common web development platforms and components.
Gulp task runner
These components combine to provide all the components needed to compile, execute, run and scaffold SharePoint Framework projects. To learn more about this, head over to the Microsoft site for more details:
The toolchain itself is made up of the following components and common build tool packages:
A Yeoman plug-in for use with the SharePoint Framework. Using this generator, developers can quickly set up a new client-side web part project with sensible defaults and best practices.
Defines the core libraries for client-side applications built using the SharePoint Framework.
The SharePoint Workbench is a standalone environment for testing and debugging client-side web parts.
Module loader for managing versioning, loading of client-side components, web parts, and other assets. It also provides basic diagnostic services. It is built on familiar standards such as SystemJS and web pack and is the first part of the SharePoint Framework to load on a page.
Defines several module interfaces that are shared by the SharePoint Framework module loader and also the build system.
Custom bundle of lodash for use with the SharePoint Framework’s module loader. To improve runtime performance, it only includes a subset of the essential lodash functions.
Custom tslint rules for usage with SharePoint client-side projects.
Custom bundle of office-UI-fabric-react for use with the SharePoint Framework’s module loader.
A collection of tasks for the SharePoint Framework build system, based on gulp. The sp-build-core-tasks package implements operations specific to SharePoint, such as packaging solutions and writing manifests.
Imports and configures a set of build tasks that are appropriate for a build target that runs in a web browser (as opposed to a Node.js environment). This package is intended to be imported directly by a gulp file that uses the SharePoint Framework build system.
The core gulp build tasks for building TypeScript, HTML, less, and other build formats. This package depends on several other npm packages that contain the following tasks:
A wrapper for web pack file-loader that can be used to modify the casing of the resulting file name. Useful in some scenarios, such as when using a content delivery network (CDN) that only allows lowercase file names.
A loader that wraps the loading of CSS in script equivalent to require(‘load-themed-styles’).loadStyles( /* css text */ ). It is designed to be a replacement for style-loader.
A loader that loads a script file’s contents directly in a web pack bundle by using an eval(…).
A loader that sets the webpack_public_path variable to a value specified in the arguments optionally appended to the SystemJS base URL property.
It is important to understand the components that the SharePoint Framework uses, just as it is to know what is within the generated project.
Secure Coding Lifecycle and SharePoint Framework
If you look at the list of components used within the SharePoint Framework, you will see two specific components. The first is “tslint” listed as a core package; the second is “jshint” inside each project.
It is common practice for Developers and organizations to follow a “Security Development Lifecycle (SDL)” process to helps build more secure software and address security compliance requirements while reducing development cost. For the SharePoint Framework, Microsoft combined “TypeScript,” “TSLint,” and “tslint-microsoft-contrib” to automate rules and recommendations for “Security Development Lifecycle (SDL).”
The SharePoint Framework components can validate basic security rules by iterating a series of rules that look for some of the common risks. The following table lists the iterated common rules.
|no-eval||tslint||Do not use the ‘eval’ function or its functional equivalents.|
|use-strict||tslint||Always enable strict mode when possible.|
|no-octal-literal||tslint-microsoft-contrib||Do not use octal literals or escaped octal sequences in strict-mode compatible code.|
|no-duplicate-parameter-names||tslint-microsoft-contrib||Do not duplicate parameter names.|
|no-delete-expression||tslint-microsoft-contrib||Do not delete expressions.|
|no-disable-auto-sanitization||tslint-microsoft-contrib||Do not disable auto-sanitization in frameworks or application helper code.|
|no-exec-script||tslint-microsoft-contrib||Banned term – execScript.|
|no-string-based-set-timeout||tslint-microsoft-contrib||Do not use the version of setTimeout that accepts code as a string argument. However, it is acceptable to use the version of setTimeout where a direct reference to a function is provided as the callback argument.|
|no-string-based-set-interval||tslint-microsoft-contrib||Do not use the version of setInterval that accepts
code as a string argument. However, it is acceptable to use the version of setInterval where a direct reference to a function is provided as the callback argument.
|no-string-based-set-immediate||tslint-microsoft-contrib||Do not use the version of setImmediate that accepts code as a string argument. However, it is acceptable to use the version of setImmediate where a direct reference to a function is provided as the callback argument.|
|no-function-constructor-with-string-args||tslint-microsoft-contrib||Do not use the version of the Function constructor that accepts a string argument to define the body of the function.|
|no-banned-terms||tslint-microsoft-contrib||Do not access terms or variables that create ambiguity or are banned in strict mode.|
|no-reserved-keywords||tslint-microsoft-contrib||Do not use reserved and future reserved keywords as identifiers.|
|no-document-domain||tslint-microsoft-contrib||Do not write to document.domain. Scripts setting document.domain to any value should be validated to ensure that the value is on a list of allowed sites.|
These rules are added to each project and validated as the code is defined and built. To see the current rules, navigate to the “tslint.json” file, you will see them listed in a “JSON” structure.
Though this is great, the current rules only cover specific coding standards or security risks. The ability to scan a project fully and identify specifics is no small task; however, at least for now, you can include other packages that perform a deeper scan.
How does this work?
“TSLint” uses a “TypeScript Compiler API” to read each file and compile it into an abstract syntax tree (AST). “TSLint” then exposes an easy to use “visitor pattern API” to each rule so that it can read and verify attributes of the tree. To make a new rule about any element such as a “Try-Catch,” you write a Typescript class that overrides the “visitCatchClause” method, performing specific checks. If you want to analyze return statements, override the “visitReturnStatement” method. There are approximately seventy visitor methods to overwrite as needed. The following describes how to write these rules.
Writing custom rules for each type of code block you want to check will help in defining not only better code but better security practices. The downside of this is the time it will take to create the rules along with testing.
Do we trust the rules or can we use anything else for checking?
Right now there is no magic way of validating the code written, outside of the core “tslint” mechanism along with custom rules. There are though, a few custom packages that work to extend the validation process. For example, you can use “tslint-config-security” or “eslint-plugin-security“, both of which are similar to the “tslint-microsoft-contrib” project.
Details on how to use and modify the Microsoft rules are here:
Another approach is to use an extension that is available for “Visual Studio Code” called “SonarLint.” To add it, navigate to the extension pane and type “Sonarlint.”
Click the “Install” link and wait for it to complete. To use it, you need to make you have the Java JDK installed. Once installed, modify the “Visual Studio Code” settings filed to update the location of the “Java Runtime version 8“.
After updating, you will need to restart “Visual Studio Code” for the new property to take effect. You will then be able to hover over your code and see that “SonarLint” is working.
When the code inspection runs, you can look at the reasons why something is flagged, such as in this example using the “Eval()” function.
Clicking the link explains in further detail the impact of the code.
This tool is very powerful, albeit needing to be configured and installed to work, but it goes further than the standard “tslint” rules to ensure code is secure.
To learn more about the tool, use the following link: https://www.sonarlint.org/vscode/index.html
The real message here is that no matter what customizations you are creating, a management lifecycle is required, validating code against best practices, and security practices. The application you choose to help you with this needs to provide the following features:
Known Vulnerability Checks
Memory Leak Detection
Code Analysis and Validation
Quality Gate and Best Practices