#!/usr/bin/lua5.4 local base = "/var/nex" local function sanitize(req) req = req:gsub("[\r\n]", ""):gsub("^/*", ""):gsub("/*$", "") return req == "" and "menu" or req end local function canonicalize(path) local parts = {} for part in path:gmatch("[^/]+") do if part == ".." then table.remove(parts) elseif part ~= "." then table.insert(parts, part) end end return "/" .. table.concat(parts, "/") end local function is_dir(path) local f = io.open(path, "r") if not f then return true end f:close() return false end local function is_within_base(path, base) return path:sub(1, #base) == base end local req = io.read("*l") or "" req = sanitize(req) local path = base .. "/" .. req local canonical_path = canonicalize(path) if not is_within_base(canonical_path, base) then print("3cut it out\t.\t.\t.\r\n") os.exit(1) end if is_dir(canonical_path) then canonical_path = canonical_path .. "/menu" end local f = io.open(canonical_path, "r") if f then local content = f:read("*a") f:close() if content then io.write(content) else print("3not found\t.\t.\t.\r\n") os.exit(1) end else print("3not found\t.\t.\t.\r\n") os.exit(1) end