From 87639540e4ea43c57eb3d31b78e0b5acaf68f97a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 4 Oct 2018 12:22:12 +0200 Subject: mod_http: Solve CORS problems once and for all This blindly allows any cross-site requests. Future work should add an API to allow each HTTP app some influence over this for each HTTP path --- plugins/mod_http.lua | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'plugins/mod_http.lua') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index a1d409bd..07d1094b 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -22,6 +22,11 @@ server.set_default_host(module:get_option_string("http_default_host")); server.set_option("body_size_limit", module:get_option_number("http_max_content_size")); server.set_option("buffer_size_limit", module:get_option_number("http_max_buffer_size")); +-- CORS settigs +local opt_methods = module:get_option_set("access_control_allow_methods", { "GET", "POST", "PUT", "OPTIONS" }); +local opt_headers = module:get_option_set("access_control_allow_headers", { "Content-Type" }); +local opt_max_age = module:get_option_number("access_control_max_age", 2 * 60 * 60); + local function get_http_event(host, app_path, key) local method, path = key:match("^(%S+)%s+(.+)$"); if not method then -- No path specified, default to "" (base path) @@ -83,6 +88,13 @@ function moduleapi.http_url(module, app_name, default_path) return "http://disabled.invalid/"; end +local function apply_cors_headers(response, methods, headers, max_age, origin) + response.headers.access_control_allow_methods = tostring(methods); + response.headers.access_control_allow_headers = tostring(headers); + response.headers.access_control_max_age = tostring(max_age) + response.headers.access_control_allow_origin = origin or "*"; +end + function module.add_host(module) local host = module.host; if host ~= "*" then @@ -101,6 +113,12 @@ function module.add_host(module) end apps[app_name] = apps[app_name] or {}; local app_handlers = apps[app_name]; + + local function cors_handler(event_data) + local request, response = event_data.request, event_data.response; + apply_cors_headers(response, opt_methods, opt_headers, opt_max_age, request.headers.origin); + end + for key, handler in pairs(event.item.route or {}) do local event_name = get_http_event(host, app_path, key); if event_name then @@ -121,6 +139,7 @@ function module.add_host(module) if not app_handlers[event_name] then app_handlers[event_name] = handler; module:hook_object_event(server, event_name, handler); + module:hook_object_event(server, event_name, cors_handler, 1); else module:log("warn", "App %s added handler twice for '%s', ignoring", app_name, event_name); end -- cgit v1.2.3 From 19d344e092421bd84cd52de74bcd6b7b1e9a0a13 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 18 Jan 2019 02:03:40 +0100 Subject: mod_http: Set up to handle OPTIONS Lower priority to allow http modules to handle it themselves, should they wish to --- plugins/mod_http.lua | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'plugins/mod_http.lua') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 07d1094b..01f20f76 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -119,9 +119,15 @@ function module.add_host(module) apply_cors_headers(response, opt_methods, opt_headers, opt_max_age, request.headers.origin); end + local function options_handler(event_data) + cors_handler(event_data); + return ""; + end + for key, handler in pairs(event.item.route or {}) do local event_name = get_http_event(host, app_path, key); if event_name then + local options_event_name = event_name:gsub("^%S+", "OPTIONS"); if type(handler) ~= "function" then local data = handler; handler = function () return data; end @@ -140,6 +146,7 @@ function module.add_host(module) app_handlers[event_name] = handler; module:hook_object_event(server, event_name, handler); module:hook_object_event(server, event_name, cors_handler, 1); + module:hook_object_event(server, options_event_name, options_handler, -1); else module:log("warn", "App %s added handler twice for '%s', ignoring", app_name, event_name); end -- cgit v1.2.3 From 3434e4560f79c834411e0c1d117a96e8b94ff4db Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 17 Jan 2019 20:42:38 +0100 Subject: mod_http: Determine CORS methods to whitelist from actual methods used --- plugins/mod_http.lua | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'plugins/mod_http.lua') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 01f20f76..829c2d02 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -14,6 +14,7 @@ local moduleapi = require "core.moduleapi"; local url_parse = require "socket.url".parse; local url_build = require "socket.url".build; local normalize_path = require "util.http".normalize_path; +local set = require "util.set"; local server = require "net.http.server"; @@ -23,7 +24,7 @@ server.set_option("body_size_limit", module:get_option_number("http_max_content_ server.set_option("buffer_size_limit", module:get_option_number("http_max_buffer_size")); -- CORS settigs -local opt_methods = module:get_option_set("access_control_allow_methods", { "GET", "POST", "PUT", "OPTIONS" }); +local opt_methods = module:get_option_set("access_control_allow_methods", { "GET", "OPTIONS" }); local opt_headers = module:get_option_set("access_control_allow_headers", { "Content-Type" }); local opt_max_age = module:get_option_number("access_control_max_age", 2 * 60 * 60); @@ -114,9 +115,11 @@ function module.add_host(module) apps[app_name] = apps[app_name] or {}; local app_handlers = apps[app_name]; + local app_methods = opt_methods; + local function cors_handler(event_data) local request, response = event_data.request, event_data.response; - apply_cors_headers(response, opt_methods, opt_headers, opt_max_age, request.headers.origin); + apply_cors_headers(response, app_methods, opt_headers, opt_max_age, request.headers.origin); end local function options_handler(event_data) @@ -127,6 +130,10 @@ function module.add_host(module) for key, handler in pairs(event.item.route or {}) do local event_name = get_http_event(host, app_path, key); if event_name then + local method = event_name:match("^%S+"); + if not app_methods:contains(method) then + app_methods = app_methods + set.new{ method }; + end local options_event_name = event_name:gsub("^%S+", "OPTIONS"); if type(handler) ~= "function" then local data = handler; -- cgit v1.2.3 From 9f65ce71893ef10485442ee209472a38865da081 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 10 Mar 2019 19:58:28 +0100 Subject: core.certmanager: Do not ask for client certificates by default Since it's mostly only mod_s2s that needs to request client certificates it makes some sense to have mod_s2s ask for this, instead of having eg mod_http ask to disable it. --- plugins/mod_http.lua | 3 --- 1 file changed, 3 deletions(-) (limited to 'plugins/mod_http.lua') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 829c2d02..17ea27e1 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -228,9 +228,6 @@ module:provides("net", { listener = server.listener; default_port = 5281; encryption = "ssl"; - ssl_config = { - verify = "none"; - }; multiplex = { pattern = "^[A-Z]"; }; -- cgit v1.2.3 From d24e6c7582a6c09be435908083ed19f13fee9bde Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 11 Sep 2019 15:10:31 +0100 Subject: mod_http: Add support for configuring CORS Access-Control-Allow-Credentials --- plugins/mod_http.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'plugins/mod_http.lua') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 17ea27e1..654ec6c7 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -26,6 +26,7 @@ server.set_option("buffer_size_limit", module:get_option_number("http_max_buffer -- CORS settigs local opt_methods = module:get_option_set("access_control_allow_methods", { "GET", "OPTIONS" }); local opt_headers = module:get_option_set("access_control_allow_headers", { "Content-Type" }); +local opt_credentials = module:get_option_boolean("access_control_allow_credentials", false); local opt_max_age = module:get_option_number("access_control_max_age", 2 * 60 * 60); local function get_http_event(host, app_path, key) @@ -89,11 +90,14 @@ function moduleapi.http_url(module, app_name, default_path) return "http://disabled.invalid/"; end -local function apply_cors_headers(response, methods, headers, max_age, origin) +local function apply_cors_headers(response, methods, headers, max_age, allow_credentials, origin) response.headers.access_control_allow_methods = tostring(methods); response.headers.access_control_allow_headers = tostring(headers); response.headers.access_control_max_age = tostring(max_age) response.headers.access_control_allow_origin = origin or "*"; + if allow_credentials then + response.headers.access_control_allow_credentials = "true"; + end end function module.add_host(module) @@ -119,7 +123,7 @@ function module.add_host(module) local function cors_handler(event_data) local request, response = event_data.request, event_data.response; - apply_cors_headers(response, app_methods, opt_headers, opt_max_age, request.headers.origin); + apply_cors_headers(response, app_methods, opt_headers, opt_max_age, opt_credentials, request.headers.origin); end local function options_handler(event_data) -- cgit v1.2.3 From 8340ca2b183123ba1c1b2d78a155c727f70a9b10 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 10 Oct 2019 20:46:27 +0200 Subject: mod_http: Unhook CORS related event handlers Prevents CORS related handlers from being left over on reload. BC: `mod_http.apps[app_name][event_name]` is now a table instead of the main handler function. --- plugins/mod_http.lua | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'plugins/mod_http.lua') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 654ec6c7..8ef06dc2 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -154,7 +154,11 @@ function module.add_host(module) module:hook_object_event(server, event_name:sub(1, -2), redir_handler, -1); end if not app_handlers[event_name] then - app_handlers[event_name] = handler; + app_handlers[event_name] = { + main = handler; + cors = cors_handler; + options = options_handler; + }; module:hook_object_event(server, event_name, handler); module:hook_object_event(server, event_name, cors_handler, 1); module:hook_object_event(server, options_event_name, options_handler, -1); @@ -176,8 +180,11 @@ function module.add_host(module) local function http_app_removed(event) local app_handlers = apps[event.item.name]; apps[event.item.name] = nil; - for event_name, handler in pairs(app_handlers) do - module:unhook_object_event(server, event_name, handler); + for event_name, handlers in pairs(app_handlers) do + module:unhook_object_event(server, event_name, handlers.main); + module:unhook_object_event(server, event_name, handlers.cors); + local options_event_name = event_name:gsub("^%S+", "OPTIONS"); + module:unhook_object_event(server, options_event_name, handlers.options); end end -- cgit v1.2.3 From fd9ccf20d5b652dbad1f37cecd540661f4642ee6 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 16 Nov 2019 16:39:45 +0100 Subject: mod_http: Soften dependency on mod_http_errors This allows disabling mod_http_errors by adding it to moduless_disabled and ensures mod_http loads even if the error pages aren't as pretty. --- plugins/mod_http.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'plugins/mod_http.lua') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 8ef06dc2..081aa7e9 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -7,7 +7,9 @@ -- module:set_global(); -module:depends("http_errors"); +pcall(function () + module:depends("http_errors"); +end); local portmanager = require "core.portmanager"; local moduleapi = require "core.moduleapi"; -- cgit v1.2.3