├── README.md └── main.rb /README.md: -------------------------------------------------------------------------------- 1 | # Escape API 2 | 3 | an API for escaping html, shell and path queries 4 | 5 | --- 6 | 7 | ## Documentation 8 | 9 | **parameters** 10 | - **method** escaping method 11 | - **data** string to be escaped 12 | 13 | **available methods** 14 | 15 | Method | Description | Type | Prevention| 16 | |---|---|---|---| 17 | | html | HTML escape | string | XSS 18 | | shell| UNIX bourne shell escape| string | os command injection 19 | | path | UNIX path escape | string | directory traversal 20 | 21 | #### examples 22 | 23 | ``` 24 | curl "https://s.polarspetroll.repl.co/api?method=html&data=<>/>,test'" 25 | ``` 26 | output : 27 | ```json 28 | { 29 | "ok":true, 30 | "data":"<>/>,test'" 31 | } 32 | ``` 33 | --- 34 | ``` 35 | curl "https://s.polarspetroll.repl.co/api?method=shell&data=ls -la | cat /etc/passwd" 36 | ``` 37 | 38 | output: 39 | 40 | ```json 41 | { 42 | "ok":true, 43 | "data":"ls\\ -la\\ \\|\\ cat\\ /etc/passwd" 44 | } 45 | ``` 46 | --- 47 | 48 | ``` 49 | curl "https://s.polarspetroll.repl.co/api?method=path&data=../../../../../../../etc/passwd" 50 | ``` 51 | 52 | output: 53 | 54 | ```json 55 | { 56 | "ok":true, 57 | "data":"./././././././etc/passwd" 58 | } 59 | ``` 60 | -------------------------------------------------------------------------------- /main.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | ['socket', 'cgi', 'json', 'cgi/util', 'shellwords', 'uri'].each(&method(:require)) 3 | 4 | port = ENV['PORT'] # lport 5 | meths = ["html", "shell", "path"] 6 | 7 | begin 8 | server = TCPServer.new port 9 | rescue => err 10 | abort err.to_s 11 | end 12 | 13 | ####################################################################################### 14 | def parseheader(head) 15 | req = head.split 16 | uri = URI(req[1]) 17 | if uri.path != "/api" 18 | return 404 19 | end 20 | return CGI::parse(uri.query) 21 | end 22 | 23 | def sendreq(code, client, body) 24 | begin 25 | body = JSON.generate(body) 26 | rescue 27 | body = '{"ok": false, "message": "Internal Server Error"}' 28 | end 29 | head = "HTTP/1.1 #{code}\r\n" 30 | head += "Content-Length: #{body.size}\r\n" 31 | head += "Content-Type: application/json\r\n" 32 | head += "Access-Control-Allow-Origin: *\r\n" 33 | head += "\r\n" 34 | head += "#{body}\r\n" 35 | client.print(head) 36 | end 37 | 38 | 39 | ####################################################################################### 40 | 41 | while client = server.accept 42 | Thread.start do 43 | begin 44 | request = client.readpartial(3000) 45 | params = parseheader(request) 46 | if params == 404 47 | sendreq(404, client, {"ok": false, "message": "Not Found"}) 48 | end 49 | 50 | func = params["method"][0] 51 | data = params["data"][0] 52 | 53 | if func == nil or data == nil or !meths.include?(func) 54 | sendreq(400, client, {"ok": false, "message": "Bad Request"}) 55 | end 56 | 57 | if func == "html" 58 | dataencoded = CGI.escapeHTML(data) 59 | sendreq(200, client, {"ok": true, "data": dataencoded}) 60 | elsif func == "path" 61 | dataencoded = data.gsub!(/\.+/, ".") 62 | sendreq(200, client, {"ok": true, "data": dataencoded}) 63 | elsif func == "shell" 64 | dataencoded = data.shellescape 65 | sendreq(200, client, {"ok": true, "data": dataencoded}) 66 | end 67 | 68 | rescue 69 | sendreq(500, client, {"ok":false, "message": "Internal Server Error"}) 70 | ensure 71 | client.close 72 | end 73 | 74 | end 75 | 76 | end 77 | --------------------------------------------------------------------------------