# HG changeset patch # User Waqas Hussain # Date 1545989751 18000 # Node ID b35dc87ebff0d819bad2c13481cbbc83bbc3d80f # Parent 807dc9c0f140e0c37b99bdcb087c32d66eae0ebd Make --serve and --serve-port take an origin argument, in order to disallow random websites from accessing the local port diff -r 807dc9c0f140 -r b35dc87ebff0 main.lua --- a/main.lua Mon Sep 17 22:07:19 2018 +0100 +++ b/main.lua Fri Dec 28 04:35:51 2018 -0500 @@ -17,6 +17,7 @@ local quiet = false; local force_summary = false; local serve_mode = false; +local serve_origin = nil; local only_tags, skip_tags; local property_rules = {}; @@ -115,8 +116,10 @@ force_summary = true; elseif opt == "--serve" then serve_mode = 8007; + serve_origin = assert(get_value(), "origin expected for '--serve'"); elseif opt == "--serve-port" then serve_mode = assert(tonumber(get_value()), "expected port number"); + serve_origin = assert(get_value(), "origin expected for '--serve-port'"); else error("Unhandled command-line option: "..opt); end @@ -349,7 +352,7 @@ -- This function handles scansion errors, -- but they shouldn't reach here anyway end); - serve.run({ port = serve_mode }, run_test_script); + serve.run({ port = serve_mode, origin = serve_origin }, run_test_script); os.exit(0); end diff -r 807dc9c0f140 -r b35dc87ebff0 scansion/serve.lua --- a/scansion/serve.lua Mon Sep 17 22:07:19 2018 +0100 +++ b/scansion/serve.lua Fri Dec 28 04:35:51 2018 -0500 @@ -19,7 +19,17 @@ local chunk = json.encode(entry) .. "\r\n"; response.conn:write(("%x\r\n%s\r\n"):format(#chunk, chunk)); end - + + -- SECURITY NOTE: We MUST validate Origin before running the Scansion script, + -- since we don't want arbitrary websites to have local RCEs (CORS does not + -- protect us here, it at best keeps the script from seeing the response) + if request.headers.origin ~= config.origin and config.origin ~= "*" then + verse.log("warn", "Rejecting origin: %s", request.headers.origin); + response.status_code = 403; -- spec suggested response when we don't like the origin + response.headers.connection = "close"; + return ""; + end + response.status_code = 201; response.headers.connection = "close"; response.headers.transfer_encoding = "chunked";