piston/readme.md

186 lines
4.9 KiB
Markdown
Raw Normal View History

2018-09-21 20:45:09 +02:00
## Piston
2021-01-14 07:01:22 +01:00
Piston is the underlying engine for running untrusted and possibly malicious code that originates from
[EMKC Challenges](https://emkc.org/challenges) and
[EMKC Weekly Contests](https://emkc.org/contests). It's also used in the
[Engineer Man Discord Server](https://discord.gg/engineerman) via
[I Run Code](https://github.com/engineer-man/piston-bot) bot as well as 1300+ other servers.
2020-12-31 22:22:44 +01:00
To get it in your own server, go here: https://emkc.org/run.
2018-09-21 20:45:09 +02:00
2020-07-04 07:07:21 +02:00
#### Use Public API (new)
2021-01-14 07:01:22 +01:00
Requires no installation and you can use it immediately. Reference the Versions/Execute sections
below to learn about the request and response formats.
2020-07-04 07:07:21 +02:00
- `GET` `https://emkc.org/api/v1/piston/versions`
- `POST` `https://emkc.org/api/v1/piston/execute`
2020-07-04 07:08:17 +02:00
2021-01-04 20:35:01 +01:00
Important Note: The Piston API is rate limited to 5 requests per second
2020-07-04 07:07:21 +02:00
2021-01-14 07:01:22 +01:00
#### Cloning and System Dependencies
```
# clone and enter repo
git clone https://github.com/engineer-man/piston
cd piston/lxc
# centos/rhel dependencies:
yum install -y epel-release
yum install -y lxc lxc-templates debootstrap libvirt
systemctl start libvirtd
# ubuntu server 18.04 dependencies:
apt install lxc lxc-templates debootstrap libvirt0
# arch dependencies:
sudo pacman -S lxc libvirt unzip
# everything else:
# not documented, please open pull requests with commands for debian/arch/macos/etc
```
#### Installation (simple)
Coming soon
#### Installation (advanced/manual)
See `var/install.txt` for how to create a new LXC container and install all of the required
software.
2018-09-21 20:45:09 +02:00
2019-06-17 07:06:38 +02:00
#### CLI Usage
- `lxc/execute [language] [file path] [args]`
2018-09-21 20:45:09 +02:00
2019-06-17 07:06:38 +02:00
#### API Usage
2019-06-17 07:09:35 +02:00
To use the API, it must first be started. To start the API, run the following:
```
cd api
./start
```
2020-07-04 07:07:21 +02:00
#### Base URLs
When using the public Piston API, use:
```
https://emkc.org/api/v1/piston
```
2021-01-14 07:01:22 +01:00
For your own local installation, use:
```
http://127.0.0.1:2000
```
2020-07-04 07:07:21 +02:00
#### Versions Endpoint
`GET /versions`
This endpoint takes no input and returns a JSON array of the currently installed languages.
Truncated response sample:
```json
HTTP/1.1 200 OK
Content-Type: application/json
2020-07-04 07:07:21 +02:00
[
{
"name": "awk",
"version": "1.3.3"
},
{
"name": "bash",
"version": "4.4.20"
},
{
"name": "c",
"version": "7.5.0"
}
]
```
2021-01-14 07:01:22 +01:00
#### Execute Endpoint
2020-07-04 07:07:21 +02:00
`POST /execute`
2019-06-17 07:06:38 +02:00
This endpoint takes the following JSON payload and expects at least the language and source. If
2021-01-14 07:01:22 +01:00
source is not provided, a blank file is passed as the source. If no `args` are desired, it can either
be an empty array or left out entirely.
2019-06-17 07:06:38 +02:00
```json
{
"language": "js",
"source": "console.log(process.argv)",
"args": [
"1",
"2",
"3"
]
}
```
2021-01-14 07:01:22 +01:00
A typical response upon successful execution will contain the `language`, `version`, `output` which
is a combination of both `stdout` and `stderr` but in chronological order according to program output,
as well as separate `stdout` and `stderr`.
2019-06-17 07:06:38 +02:00
```json
HTTP/1.1 200 OK
Content-Type: application/json
2019-06-17 07:06:38 +02:00
{
"ran": true,
"language": "js",
"version": "12.13.0",
2021-01-14 07:01:22 +01:00
"output": "[ '/usr/bin/node',\n '/tmp/code.code',\n '1',\n '2',\n '3' ]",
"stdout": "[ '/usr/bin/node',\n '/tmp/code.code',\n '1',\n '2',\n '3' ]",
"stderr": ""
2019-06-17 07:06:38 +02:00
}
```
If an invalid language is supplied, a typical response will look like the following:
```json
HTTP/1.1 400 Bad Request
Content-Type: application/json
2019-06-17 07:06:38 +02:00
{
"code": "unsupported_language",
"message": "whatever is not supported by Piston"
}
```
2018-09-21 20:45:09 +02:00
#### Supported Languages
2020-06-09 04:24:15 +02:00
- awk
- bash
2021-01-14 07:01:22 +01:00
- brainfuck
2020-06-09 04:24:15 +02:00
- c
- cpp
- csharp
2020-10-17 19:06:23 +02:00
- deno
- erlang
2020-06-09 04:24:15 +02:00
- elixir
- emacs
2021-01-14 07:01:22 +01:00
- elisp
2020-06-09 04:24:15 +02:00
- go
2020-10-17 05:57:45 +02:00
- haskell
2020-06-09 04:24:15 +02:00
- java
2020-10-17 19:56:02 +02:00
- jelly
2020-06-09 04:24:15 +02:00
- julia
- kotlin
2021-01-14 07:01:22 +01:00
- lua
2020-06-09 04:24:15 +02:00
- nasm
- node
2021-01-14 07:01:22 +01:00
- paradoc
2020-06-09 04:24:15 +02:00
- perl
- php
- python2
- python3
- ruby
- rust
- swift
- typescript
2018-09-21 20:45:09 +02:00
2018-09-22 06:15:24 +02:00
#### Principle of Operation
2019-05-31 20:09:47 +02:00
Piston utilizes LXC as the primary mechanism for sandboxing. There is a small API written in Go which takes
in execution requests and executes them in the container. High level, the API writes
a temporary source and args file to `/tmp` and that gets mounted read-only along with the execution scripts into the container.
2018-09-22 18:52:19 +02:00
The source file is either ran or compiled and ran (in the case of languages like c, c++, c#, go, etc.).
2018-09-22 06:15:24 +02:00
#### Security
2019-05-31 20:09:47 +02:00
LXC provides a great deal of security out of the box in that it's separate from the system.
Piston takes additional steps to make it resistant to
2018-09-22 06:15:24 +02:00
various privilege escalation, denial-of-service, and resource saturation threats. These steps include:
- Disabling outgoing network interaction
- Capping max processes at 64 (resists `:(){ :|: &}:;`, `while True: os.fork()`, etc.)
- Capping max files at 2048 (resists various file based attacks)
2018-09-22 06:15:24 +02:00
- Mounting all resources read-only (resists `sudo rm -rf --no-preserve-root /`)
- Cleaning up all temp space after each execution (resists out of drive space attacks)
- Running as a variety of unprivileged users
2018-09-22 18:52:19 +02:00
- Capping runtime execution at 3 seconds
2018-09-22 06:15:24 +02:00
- Capping stdout to 65536 characters (resists yes/no bombs and runaway output)
- SIGKILLing misbehaving code
2018-09-21 20:45:09 +02:00
#### License
Piston is licensed under the MIT license.