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.

Node.js
Gulp task runner
Webpack
Yeoman generators

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:

https://docs.microsoft.com/en-us/sharepoint/dev/spfx/tools-and-libraries

 

The Toolchain

The toolchain itself is made up of the following components and common build tool packages:

More details here:
https://docs.microsoft.com/en-us/sharepoint/dev/spfx/toolchain/sharepoint-framework-toolchain

@microsoft/generator-SharePoint:

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.

@microsoft/sp-client-base:

Defines the core libraries for client-side applications built using the SharePoint Framework.

@microsoft/sp-web part-workbench:

The SharePoint Workbench is a standalone environment for testing and debugging client-side web parts.

@microsoft/sp-module-loader:

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.

@microsoft/sp-module-interfaces:

Defines several module interfaces that are shared by the SharePoint Framework module loader and also the build system.

@microsoft/sp-lodash-subset:

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.

@microsoft/sp-tslint-rules:

Custom tslint rules for usage with SharePoint client-side projects.

@microsoft/office-UI-fabric-react-bundle:

Custom bundle of office-UI-fabric-react for use with the SharePoint Framework’s module loader.

@microsoft/sp-build-core-tasks:

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.

@microsoft/sp-build-web:

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.

@microsoft/gulp-core-build:

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:

@microsoft/gulp-core-build-typescript

@microsoft/gulp-core-build-sass

@microsoft/gulp-core-build-webpack

@microsoft/gulp-core-build-serve

@microsoft/gulp-core-build-karma

@microsoft/gulp-core-build-mocha

@microsoft/loader-cased-file:

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.

@microsoft/loader-load-themed-styles:

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.

@microsoft/loader-raw-script:

A loader that loads a script file’s contents directly in a web pack bundle by using an eval(…).

@microsoft/loader-set-webpack-public-path:

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.

Rule Name From Description
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.

https://palantir.github.io/tslint/develop/custom-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:

https://github.com/Microsoft/tslint-microsoft-contrib

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

 

Thoughts

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

Liam Cleary

Liam began his career as a Trainer of all things computer related. He quickly realized that programming, breaking, and hacking was a lot more fun. He spent the next few years working within core infrastructure and security services until he found SharePoint. He is the founder and owner of SharePlicity, a consulting company that focuses on all areas of Technology. His role within SharePlicity is to help organizations implement technology that will enhance internal and external collaboration, document and records management, automate business processes and of course security controls and protection. Liam also serves as the Product Owner for Security at Rencore, where he is helping to develop offerings that help organizations further understand and mitigate security and compliance risks, within SharePoint and Office 365 customizations. His core focus will is to identify, control and protect whether they are full-fledged customizations or out-of-the-box Office 365 functionality. He is also a twelve-time Microsoft MVP focusing on Architecture but also crosses the boundary into Development. His specialty over the past few years has been security in SharePoint and its surrounding platforms. He can often be found at user groups or conferences speaking, offering advice, spending time in the community, teaching his kids how to code, raspberry PI programming, hacking the planet or building Lego robots.

You may also like...