For years, I’ve been working in various Security Operations Center (SOC) environments, and one thing has remained constant across them: large screens prominently displaying information. The actual usefullness of these screen can be debated, but they are a great way to show off to visitors.
Setting up these screens is not that hard, but it can be a bit of a hassle. How to be able to organize the different screens and be able to easily switch between different layouts? For instance, when I’m tired of work and just wanted to watch some F1.
So a few month ago I started to experiment with some ideas, leading to the creation of TheWall. A web-based dashboard designed for big screens, and can be controlled from any device on the network. It’s build using Nuxt and Vue, and only requires Firefox with the TheWall extension to be installed on the display computer.
First PoC
One of the ideas was being able todo all the displaying from within the browser. Nowadays every application uses a web interface, so there is no need to be able to display native applications. Also, by using a web interface, I can use CSS transformations and animations to create a much more appealing interface. Although in the current version, it just animates resizing and moving of the displayed sites.
There was only one issue: how to circumvent the security restrictions of the browser for displaying iframes? The solution was to develop an extension that intervenes with the request to disable all those annoying security restrictions. And due the restrictions Chromium browsers started to implement for extensions, the only supported browser is Firefox.
The extension will remove the X-Frame-Options
header and change the Content-Security-Policy
header to allow websites to be displayed.
To minimize the security risk, the extension requires the user to explicitly configure the url of the TheWall server and only changes the headers for the sub frames and not the sub frames of the sub frames.
Thinking that would be enough, was a bit naive.
I overlooked the SameSite
cookie attribute, which is a security feature that prevents the browser from sending this cookie along with cross-site requests.
Ultimately, this prevents the user from being able to login in the websites shown on TheWall.
So the extension also changes the SameSite
attribute to None
for subframes.
Hopefully, this is the last security feature that needs to be circumvented or maybe I can find a sligthly more secure way to do this.
But a good reason to only open trusted websites on TheWall.
First release
After building the first PoC, the rest of the development went quite fast. A backend and frontent was easily build using Nuxt and Vue. The frontend provides a simple drag-and-drop interface to rearrange the different sites.
When launching the TheWall viewer on a big screen, a server-side event stream is requested from the backend. An initialization request is sent to the extension to begin intercepting requests for displayed iframes. The controller then communicates any layout changes to the backend through a straightforward REST API.
To enhance customization, the controller allows users to set custom CSS and JavaScript for the displayed sites. This can hide unnecessary elements or modify layouts. The injected JavaScript can also interact with the displayed site, enabling actions like closing banners or starting videos. Importantly, this capability is restricted to TheWall’s server to ensure security, so it’s crucial to limit access to trusted devices for the server.
Currently, TheWall offers basic authentication and lacks encryption, so I highly recommend using a reverse proxy if exposing the server to the internet.
Future
TheWall is primarily a fun side project at this stage. I have several ideas for improvements, including more dynamic animations and additional customization options. I’m also considering the ability to stream video and audio to the big screen using WebRTC, along with enhanced security features to ensure safer usage.
Please feel free to try out TheWall and provide feedback or suggestions for improvements. All documentation and source code are available on GitHub and is licensed under the AGPLv3.