Schools can hardly be the only organisations with legacy applications in regular use for vital ’line-of-business’ functions. Hopefully for the most part these are visible to IT, securely contained and have an end-of-life date with a succession plan rather than being adopted through choice into a modern desktop environment. A while ago I encountered a nasty and unavoidable case of the latter and had to figure out a solution.

The application I was tasked to deploy was for processing sensitive financial data on our most heavily-secured devices and relied on Internet Explorer and Java. Naturally I called for a fresh look at the purpose of this application and a search for any available alternative, but due to external constraints in this case there was none.

But why?

I consulted with the developers and was unofficially told that they are aware of these issues but are unable to migrate to a modern platform because of their code debt. This wasn’t an expression I had heard before but it’s a readily understandable concept. Due to business pressures and a focus on operations over improvements, this high-profile financial firm has been ploughing their effort into a codebase built upon a platform that is fading from use due to security and performance concerns (Java) and declared end-of-life (Internet Explorer). Their code still works, but the world has moved on:

Technical debt incurred by the passage of time and the evolution of the surrounding environment is not the result of bad quality. Your system could have had the best possible design (or code) at the time you built it; five years later, it is deep in technical debt because of changes in your environment—not because the system has degraded. A technological gap has grown between the original state and the current environment.

What is Technical Debt by Kruchten, Nord and Ozkaya.

Java? No-va! ⛔

I refused to proceed with the rollout as planned given that it would compromise the security and performance of the infrastructure for which I am responsible. In formulating my response, I pointed to a spate of recent high-profile security issues such as Log4j as well as Microsoft’s baseline security policy but the real heft of my argument came from the ACSC Essential Eight maturity model. I discovered this glorious document during my pgcert in cybersecurity last year and it’s a marvel of inescapable clarity on the mitigations that must be adopted by all organisations in order to operate securely in the modern threat landscape. There aren’t many products mentioned by name but Java is one of them and it’s on the very first maturity level that states:

Web browsers do not process Java from the internet.

Essential Eight Security Model

As I said, inescapable.

Sandbox Solution

Unfortunately merely objecting wasn’t going to get me anywhere; I had to come up with a solution. The devs suggested running their app on a Remote Desktop Session Host; this would require several servers including an RD Gateway for off-campus access, all of which would lend its own bouquet of attack surfaces. Alternatively they suggested we give our users an extra computer (an insecure one for their secure work to go alongside the secure one for their insecure work!). I declined both of these options and set to work figuring out a way of running it in Windows Sandbox.

Sandbox is a feature included in Pro, Enterprise and Edu versions of Windows 10/11 that (provided the hardware requirements are met) allows the user to open an isolated container based on the installed version of Windows that allows for apps to be run in a separate and secure environment. It’s handy for an app that only needs to be run once or one that might make a mess of the host OS but since it’s ephemeral, the moment it’s closed all data it holds is lost; not very useful for an app that needs to stay installed.

Fortunately there are some limited customisations that can be applied, including mounting a folder and running a command at logon. I was able to extract the application and support files (including Java) into a directory, mount that directory (read-only of course) and execute a .CMD file with Powershell using the following XML saved as a .wsb file:

   <Command>C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -executionpolicy unrestricted -command "start powershell {-noexit -Command C:\\Users\\WDAGUtilityAccount\\Desktop\\InstallDir\\Runcmd.cmd}"</Command>

The CMD file contains the path to the Java executable followed by the archive and its URL path:

cd C:\Users\WDAGUtilityAccount\Desktop\InstallDir\jre1.8.0_311\bin
.\java.exe -jar <filename.jar>

The result of this is that upon the user clicking the .wsb file, Sandbox starts and mounts the folder, runs the script to open the application and then presents it to the user in exactly the same way as if it were installed but without any risk to the host OS of having a permanently-available Java attack surface. It’s a fair exchange for a delay of just 10-15 seconds on opening the app.

Of course I was fortunate that my particular use case works in this scenario; let’s face it, there aren’t many ‘portable’ apps these days (one that can be run from a single executable or self-contained folder). Most will use the registry to store configuration and may rely on other support software being installed elsewhere on the system. I was also fortunate that my app was online-only; it didn’t need to transfer files directly to and from the host OS or engage in printing or other device interactions that would have complicated the user experience.

If only…

I’ve been wondering about the future potential of this and whether these problems could be solved. Imagine a ‘managed sandbox’ feature in Windows that would allow me to distribute apps to devices in a sandbox or make pre-configured persistent sandboxes available to users; this would not only cater for legacy apps but also those edge cases such as unsigned executables, uncommon drivers or apps that require local admin permissions, all without the security concerns inherent in these scenarios.

Taking that further, why not a ‘SandboxApp’ that works in the same way as a RemoteApp running on Remote Desktop; this makes the underlying platform invisible and presents the app to the user as though it were running natively on their device. Certainly this would raise the question of balancing security against functionality since the greater the level of integration with the host OS, the more numerous the vectors for malicious sandbox escape. However if this risk could be managed then we as admins could say ‘yes’ to users more often when they ask for software to be made available. Specifically in a school context, teachers would be free to adopt software in the classroom without prior planning, vetting, approval and distribution and admins would have an easier time managing the heterogenous nature of app deployments (packaged apps, EXEs, MSIs, etc.). There are ways to solve all of these issues with existing technologies of course, just not as straightforwardly.