Blog

Is JavaScript Safe for SharePoint?

12 min read
12 min read

The typical consultant answer is correct “It depends.” I am also expecting that there are multiple views on this and there are many I am sure who might say “Yes” and “No” and even “Maybe.

What do you think?
Do you think it is safe?
Is it always safe?
Can you guarantee what it is doing?
What impact can it have on SharePoint?

This post is not supposed to be a definitive answer but more of a conversation starter to highlight why this question should even come up. Firstly, let’s understand the real problem.

JavaScript: Simple yet powerful programming

Client-side code is all back in fashion now, remember all those years ago using early JavaScript implementations, with functions such as XMLHttpRequest for everything as well as those infamous iFrames everyone had. Those were the days when everything was more accessible and limited in functionality. Also, browsers were nowhere near as sophisticated as now, and the average workstation was less powerful than my iPhone in my pocket. Wasn’t it so much easier back then?

Yes and no really. Back then client-side was a last resort, with server-side being the option of choice for most coding. I remember back in the day converting a VAX VMS (for those that don’t know what that was:
https://en.wikipedia.org/wiki/VAX) system to Classic ASP, SQL and COM+ components, still have nightmares about it, but you know it worked perfectly.

Then things changed, and the direction changed, due to security problems and client-side performance. Using client-side code was almost frowned up for a while, and iFrames were of the devil. Fast forward to today, and now the server-side is still there but converted to RESTful API, and all the old backend coding is now lightweight JavaScript code, moving chunks of XMLand JSON around. Client-side code is now the preferred approach and iFrames are cool again. Isn’t technology so fickle?

The change this time is because JavaScript has moved on what seems like light years, browsers are different, with a better understanding of code, security, and controls. The average workstation is now more powerful than all the computing power most companies owned in their server rooms, so now we can write everything to the client now. In reality, there is not much that can’t be done with JavaScript in some format, especially when you combine that with systems such as Node.js.

Microsoft over the past few years has been a great advocate for using JavaScript within its platforms. Now it makes sense as it limits the ability for code to impact performance or security within a shared environment to simple client sandboxed browser-based solutions and not deep managed C# code that would have full server access.

I get what you’re saying, but what is the problem then?

Well, I suppose we need to understand what JavaScript is doing and if there is a real problem. JavaScript is protected within the browser by sandbox capabilities that limit its ability to access underlying component that historically had been. For example, if you read the documentation on the way Google Chrome’s Sandbox works, you get an excellent understanding of why JavaScript makes sense.

Google Chrome’s multi-process architecture allows for much flexibility in the way we do security. The entire HTML rendering and JavaScript execution run within isolated processes and renderers. These are the ones that live in the sandbox., read more here: https://chromium.googlesource.com/chromium/src/+/master/docs/design/sandbox.md

Sandboxing is a vital security technique that isolates programs, preventing malicious or malfunctioning programs from damaging or snooping on the rest of your computer. Sandboxes restrict what a piece of code can do, giving it just as many permissions as it needs without adding additional permissions that can get abused. The web browser essentially runs web pages you visit in a sandbox. The Sandbox restricts your browser to a limited set of resources. Visiting websites not using a sandbox could mean that the executing code is not isolated from the rest of your system. If the site is malicious, potentially damaging changes can be made directly to the operating system itself.

Now the problem is not the Sandboxing technology that is in most web browsers, but more what the code is doing in the context of the site you are accessing or the consent you give it. JavaScript only has access to what is defined by the Sandbox, browser policies and permission you assign. However, JavaScript code is often written to reuse components, across sessions, sites or even storing objects locally for reuse, as well calling into other systems external to the running code. If this is the case, then this is when you start to see problems.

JavaScript: Tool of Manipulation

If we bring this back to the SharePoint platform, which is our focus, then why JavaScript? Historically SharePoint development is completed using fully managed C# code, deployed directly onto the server farm, with full access to the server API’s, via the core server DLLs provided by Microsoft. This code works; however, it can impact performance and stability of the server farm purely based on the level in the stack it runs. SharePoint code written in .NET languages such as C# or VB.NET is classed as Managed Code.

Managed code is code written in one of over twenty high-level programming languages that are available for use with the Microsoft .NET Framework, including C#, J#, Microsoft Visual Basic .NET, Microsoft JScript .NET, and C++. All of these languages share a unified set of class libraries and can be encoded into an Intermediate Language (IL). A runtime-aware compiler compiles the IL into native executable code within a managed execution environment that ensures type safety, array bound and index checking, exception handling, and garbage collection.

The advantage to managed code and compiling this code within a managed execution environment is that you can avoid typical programming mistakes that can lead to security holes and unstable applications. Many unproductive programming tasks are also automatically taken care of, such as type safety checking, memory management, and destruction of unneeded objects. You are then able to focus on the business logic of developing applications and write fewer lines of code. C# compiles to .NET IL and is executed with various optimizations, JavaScript is not compiled, but rather interpreted, directly within the JavaScript engine to the browser being used.

So, our first problem is the browser interpretation of the JavaScript. Some methods, functions and even properties can behave differently depending on whether you are using Internet Explorer (IE), Edge, Firefox, Chrome, Safari or any other random browser.

The second problem is what the JavaScript code has access too. The browsers core components available to the executing JavaScript are:

Browser User interface
Browser engine
Rendering engine
Networking
UI backend
JavaScript engine
Data persistence

Now even though the executing code has access, it is controlled and sandboxed as explained before. The code can manipulate the user experience by interacting directly with the browser controls and components, causing potential problems within the browser.

The third problem is the code itself, and what it is directly trying to manipulate within the Document Object Model (DOM). Most browsers use multiple rendering engines:

Gecko – Mozilla
Servo – Mozilla
Goanna – M.C. Straver
WebKit – Apple
Blink – Google
EdgeHTML – Microsoft

Previous engines now discontinued are KHTML, Presto, Tasman, and Trident. More details on these can be found here: https://en.wikipedia.org/wiki/Comparison_of_browser_engines

Each browser contains versions of the rendering engines. The rendering engine within all browsers performs five core tasks:

Parse the HTML, and construct the DOM tree
Construct the Cascading Style Sheet Object Model (CSSOM)
Construct the render tree (combining the DOM and CSSOM)
Layout the render tree
Paint the render tree

The sequence of the entire process can, however, can break by introducing “<script>” tags. Scripts tags are parsed and executed immediately, as the parser reaches them. The parsing process stops until the script is fully executed. If the script is externally referenced, then it first has to be fetched from the network (synchronously), at that point all parsing stops until the fetch completes. HTML5 however, does provide a way to fetch externally referenced script asynchronously, mitigating this issue.

As you can see with just these three simple things, JavaScript could potentially be a problem. Of course, the real issue comes down to how JavaScript is written and what it does. Take this function for example:

The code itself is not doing anything terrible, however, due to the nature of JavaScript coding I can inject items into the “DOM.” The code is injecting a new “Image” directly into the “DOM” at load time. The “IMG” tag is pre-populated with arbitrary JavaScript commands. The newly added “IMG” tag is then retrieved and using a common JavaScript “Eval()” function, ensures the hidden code is executed. The example code is taken from a SharePoint Framework Web Part sample I created. There are many more things that can be done within JavaScript that may or may not be malicious or at least could be dangerous if not checked. Of course, a bigger issue if obfuscation is applied to the JavaScript code making it almost impossible to read and understand. The same function is shown below, albeit obfuscated.

 

JavaScript: Hidden in the Shadows

Now that you know the fundamentals of how JavaScript executes, what could be written and, where the problem lies, now let’s make it even more complicated. Browsers support the display of the “Shadow DOM.” Shadow DOM sounds like some “Dark Web” type function of our page. Shadow DOM provides us a way to overlay the normal “DOM” subtree with a document fragment that contains another subtree of nodes, which are impregnable to scripts and styles. Various browsers have already been using this methodology to implement native widgets like date, sliders, audio, video players, etc.

Using Chrome Developer Tools, you can view the “Shadow DOM” giving you the ability to see deeper into the HTML structure, especially inside of predefined components. As an example, the following code outputs the standard browser media control.

The assumption is that when you view the control source in the site after load, that this would be the code would see. As expected it is rendered that way.

However, if you look next to the beginning “<audio>” tag in the code, you can expand within the control to reveal the hidden from view “Shadow DOM.

You can see that the internal elements render prefixed with “-webkit” and “-internal” denoting these are inside the “Shadow DOM.” You then can interact and modify them as needed. However, a problem that often occurs is that code written does not follow the required rules for utilizing the “Shadow DOM.” The user experience can be inadvertently affected, or cause unknown side-effects resulting in potential performance, layout or even security problems.

Learn more about Shadow DOM and which browsers fully support it, use any of the following links:

https://developers.google.com/web/fundamentals/web-components/shadowdom

https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM

https://www.w3.org/TR/shadow-dom/

Is JavaScript Safe for SharePoint?

Back at the start, I asked the question “Is JavaScript Safe for SharePoint?” As stated before, the answer is “It depends.

It depends on what the code is doing.
It depends on what it is trying to access.
It depends on what it is trying to manipulate.
It depends on which browser you are using.
It depends on whether the code is performing malicious actions.
It depends on what you as an organization want to use.

It is true, JavaScript and of course TypeScript are both great coding approaches to building solutions within SharePoint. As I outlined in a previous post though, ensuring that the code is doing what it should be doing, controlling and managing it, as well as the security for it, is all down to you as an organization.

Is it a problem to customize SharePoint?

For me, I like JavaScript, and I love the flexibility it gives me as a Developer, as well as the restricted framework where it executes. So, for me, the answer is yes, within reason based on you employing a proactive approach to management.

Resources and Guidance

https://developers.google.com/web/fundamentals/performance/critical-rendering-path/constructing-the-object-model

https://developers.google.com/web/fundamentals/performance/rendering/reduce-the-scope-and-complexity-of-style-calculations

https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/#The_parsing_algorithm

https://chromium.googlesource.com/chromium/src/+/master/docs/design/sandbox.md

https://www.bleepingcomputer.com/news/google/heres-how-to-enable-chrome-strict-site-isolation-experimental-security-mode/

https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf

https://gist.github.com/praveenpuglia/0832da687ed5a5d7a0907046c9ef1813

This blog was originally posted on Liam’s blog

Liam is currently a Microsoft MVP and Product Owner – Security at Rencore. Please click the button below to see how the experience of our 5 MVPs is used in the offerings of our products!

Learn more

Subscribe to our newsletter