Warning
This is an application that can execute arbitrary code without authentication. It is published for research and development purposes. Do not use this application if you do not understand its nature.
snippetd
or /ˈsnɪpədi/ is a Linux daemon serving an API that allows executing, interpreting or compiling code snippets from various programming languages using containerd and containers from the docker hub.
The API is very simple as it only provides a basic banner in the root /
, a list of all supported programming language runtimes under /runtimes
and the execution of code under /execute
.
curl -X POST \
-H "Content-Type: text/x-php" \
-d "<?php echo 'hello world';" \
http://192.168.1.3:8504/execute
When posting a source code to the endpoint, it will check if the Content-Type
(MIME Type) is supported. If the language is supported, it'll create a temporary folder on the host, a container for the language with the temporary folder that includes the default source file name and the execution shell script. The shell scripts can be found in the config/runtime.
The more complex runtimes like C, C++, C# and VB.NET will create the necessary project structure (i.e. .NET) and compile the source code before executing it.
The following programming languages are currently supported with the respective MIME types and containers.
Language | MIME Types | Container |
---|---|---|
Bash | application/x-sh application/x-bash text/x-sh text/x-shellscript |
docker.io/library/debian:latest |
PHP | application/x-httpd-php application/x-php text/x-php |
docker.io/library/php:latest |
Python | application/x-python-code application/x-python ,text/x-python |
docker.io/library/python:latest |
Ruby | application/x-ruby text/x-ruby |
docker.io/library/ruby:latest |
JavaScript | application/javascript text/javascript application/x-javascript |
docker.io/library/node:latest |
Go | application/x-go text/x-go text/x-go-source |
docker.io/library/golang:latest |
C | text/x-c text/x-c-header application/x-c application/x-c-header |
docker.io/library/gcc:latest |
C++ | text/x-c++ text/x-c++-header application/x-c++ application/x-c++-header |
docker.io/library/gcc:latest |
C# | application/x-csharp text/x-csharp text/x-csharp-source |
mcr.microsoft.com/dotnet/sdk:latest |
VB.NET | text/x-vb application/x-vb |
mcr.microsoft.com/dotnet/sdk:latest |
Java | text/x-java-source text/x-java application/x-java-source application/x-java application/java |
docker.io/library/openjdk:latest |
Rust | text/x-rust |
docker.io/library/rust:latest |
Swift | text/x-swift |
docker.io/library/swift:latest |
TypeScript | application/typescript text/typescript |
mcr.microsoft.com/devcontainers/typescript-node |
snippetd
comes with the install.sh
script for Linux that will install the systemd service with the snippetd.service
file, create the snippetd
user and the containerd
group, change group ownership and permissions of the containerd socket. Afterwards it'll start the systemd service.
Warning
Make sure you are 100% aware of what this application does and how the install script works. Check the script before executing it! Snippetd has no authentication, do not run it in public!
./install.sh
The vmbuild.sh
script builds a LinuxKit virtual machine image for darwin/arm64
(Apple Silicon Mac) and vmrun.sh
allows running the vm with the Apple Virtualization framework on macOS.
If you are receiving an error with a message like the following when executing vmrun.sh
, you need to sign LinuxKit.
FATA[0000] validation failedError Domain=VZErrorDomain Code=2 Description="Invalid virtual machine configuration. The process doesn’t have the “com.apple.security.virtualization” entitlement." UserInfo={
NSLocalizedFailure = "Invalid virtual machine configuration.";
NSLocalizedFailureReason = "The process doesn\U2019t have the \U201ccom.apple.security.virtualization\U201d entitlement.";
}
This requires Xcode and the necessary developer tools as well as accounts to be present on your macOS. If you have all of them perfectly installed, you can use the codesign-linuxkit.sh
shell script to sign your LinuxKit binary.
sudo ./codesign-linuxkit.sh
Deplying the image to the Docker hub so it can be fetched by LinuxKit. The dockerbuild.sh
allows building it before.
docker tag snippetd jankammerath/snippetd:latest
docker push jankammerath/snippetd:latest
There are security considerations for this application as it allows executing containers and arbitrary code. It is important that you understand the impact of this application, the lack of authentication and security. This aims to serve as a sandboxed sidecar for any application that wishes to execute arbitrary code on Linux.
These are some sample source codes to test if snippetd
is working correctly.
The sample application in VB.NET
(Visual Basic .NET) is a good test case, because Visual Basic does not have curly braces, .NET is complicated to setup and picky with its environment. Further it queries a weather API and thus uses networking with HTTP. It's a good example to test if the setup works. If VB.NET
works, you can be sure the other languages work as well.
Imports System
Imports System.Net.Http
Imports System.Text.Json
Imports System.Text.Json.Nodes ' Import JsonNode
Imports System.Threading.Tasks
Module WeatherFetcher
Sub Main()
GetWeatherAsync().Wait()
End Sub
Async Function GetWeatherAsync() As Task
Dim latitude As String = "47.6786"
Dim longitude As String = "-122.1310"
Dim apiUrl As String = $"https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}¤t_weather=true"
Console.WriteLine($"Fetching current temperature for Redmond, WA...")
Using client As New HttpClient()
Try
Dim response As HttpResponseMessage = Await client.GetAsync(apiUrl)
response.EnsureSuccessStatusCode()
Dim responseContent As String = Await response.Content.ReadAsStringAsync()
' Parse the JSON response
ParseWeatherJson(responseContent)
Catch ex As HttpRequestException
Console.WriteLine($"Error fetching weather data: {ex.Message}")
Catch ex As Exception
Console.WriteLine($"An unexpected error occurred: {ex.Message}")
End Try
End Using
End Function
Sub ParseWeatherJson(jsonString As String)
Try
Using jsonDocument As JsonDocument = JsonDocument.Parse(jsonString)
Dim root As JsonNode = jsonDocument.RootElement.Deserialize(Of JsonNode)() ' Deserialize to JsonNode
If root IsNot Nothing AndAlso root("current_weather") IsNot Nothing Then
Dim currentWeatherElement As JsonNode = root("current_weather")
If currentWeatherElement("temperature") IsNot Nothing Then
Dim temperatureCelsius As Double = currentWeatherElement("temperature").GetValue(Of Double)
Dim temperatureFahrenheit As Double = (temperatureCelsius * 9 / 5) + 32
Console.WriteLine($"Current Temperature in Redmond, WA:")
Console.WriteLine($" Celsius: {temperatureCelsius}°C")
Console.WriteLine($" Fahrenheit: {Math.Round(temperatureFahrenheit, 2)}°F")
Else
Console.WriteLine("Temperature data not found in the response.")
End If
Else
Console.WriteLine("Current weather data not found in the response.")
End If
End Using
Catch ex As JsonException
Console.WriteLine($"Error parsing JSON: {ex.Message}")
Console.WriteLine($"Raw JSON response: {jsonString}")
Catch ex As Exception
Console.WriteLine($"An unexpected error occurred during JSON processing: {ex.Message}")
Console.WriteLine($"Raw JSON response: {jsonString}")
End Try
End Sub
End Module
If everything works fine and as expected, the output of the Visual Basic .NET app should be the weather in Redmond, WA in the following JSON format.
{
"result": {
"uuid": "c0241b3e-c0c5-44e0-ab09-890dcd5e50bd",
"standard_output": "Fetching current temperature for Redmond, WA...\nCurrent Temperature in Redmond, WA:\n Celsius: 7.3°C\n Fahrenheit: 45.14°F\n"
}
}