diff options
author | Joan Touzet <joant@atypical.net> | 2017-10-25 12:35:02 -0400 |
---|---|---|
committer | Joan Touzet <wohali@users.noreply.github.com> | 2017-10-25 17:48:46 -0400 |
commit | 82635ef7f1b44cbdf98a8d6989cf505b828c3f55 (patch) | |
tree | a89c9894e419a869e8dd0ceae5ed71364d4d9979 | |
parent | 629a3e00efde6c7af99358c7bd0071a9764c7c1e (diff) | |
download | couchdb-82635ef7f1b44cbdf98a8d6989cf505b828c3f55.tar.gz |
Blacklist some config sections from HTTP PUT/DELETE operations
-rw-r--r-- | Makefile | 1 | ||||
-rwxr-xr-x | dev/run | 11 | ||||
-rw-r--r-- | src/chttpd/src/chttpd_misc.erl | 2 | ||||
-rw-r--r-- | src/couch/src/couch_httpd_misc_handlers.erl | 1 | ||||
-rw-r--r-- | src/couch/src/couch_util.erl | 22 | ||||
-rw-r--r-- | test/javascript/tests/config.js | 8 | ||||
-rw-r--r-- | test/javascript/tests/erlang_views.js | 4 | ||||
-rw-r--r-- | test/javascript/tests/view_sandboxing.js | 2 |
8 files changed, 48 insertions, 3 deletions
@@ -124,6 +124,7 @@ else endif @rm -rf dev/lib @dev/run -n 1 -q --with-admin-party-please \ + --enable-erlang-views \ -c 'startup_jitter=0' \ 'test/javascript/run --suites "$(suites)" \ --ignore "$(ignore_js_suites)"' @@ -113,6 +113,9 @@ def setup_argparse(): dest='with_admin_party', default=False, action='store_true', help='Runs a dev cluster with admin party mode on') + parser.add_option('--enable-erlang-views', + action='store_true', + help='Enables the Erlang view server') parser.add_option('--no-join', dest='no_join', default=False, action='store_true', @@ -135,6 +138,7 @@ def setup_context(opts, args): return {'N': opts.nodes, 'no_join': opts.no_join, 'with_admin_party': opts.with_admin_party, + 'enable_erlang_views': opts.enable_erlang_views, 'admin': opts.admin.split(':', 1) if opts.admin else None, 'nodes': ['node%d' % (i + opts.node_number) for i in range(opts.nodes)], 'node_number': opts.node_number, @@ -274,6 +278,13 @@ def hack_default_ini(ctx, node, contents): repl = toposixpath("coffeescript = %s %s" % (couchjs, coffeejs)) contents = re.sub("(?m)^coffeescript.*$", repl, contents) + if ctx['enable_erlang_views']: + contents = re.sub( + "^\[native_query_servers\]$", + "[native_query_servers]\nerlang = {couch_native_process, start_link, []}", + contents, + flags=re.MULTILINE) + return contents diff --git a/src/chttpd/src/chttpd_misc.erl b/src/chttpd/src/chttpd_misc.erl index cfeeb3ff7..fefb85284 100644 --- a/src/chttpd/src/chttpd_misc.erl +++ b/src/chttpd/src/chttpd_misc.erl @@ -256,6 +256,7 @@ handle_node_req(#httpd{path_parts=[_, _Node, <<"_config">>, _Section]}=Req) -> % PUT /_node/$node/_config/Section/Key % "value" handle_node_req(#httpd{method='PUT', path_parts=[_, Node, <<"_config">>, Section, Key]}=Req) -> + couch_util:check_config_blacklist(Section), Value = chttpd:json_body(Req), Persist = chttpd:header_value(Req, "X-Couch-Persist") /= "false", OldValue = call_node(Node, config, get, [Section, Key, ""]), @@ -271,6 +272,7 @@ handle_node_req(#httpd{method='GET', path_parts=[_, Node, <<"_config">>, Section end; % DELETE /_node/$node/_config/Section/Key handle_node_req(#httpd{method='DELETE',path_parts=[_, Node, <<"_config">>, Section, Key]}=Req) -> + couch_util:check_config_blacklist(Section), Persist = chttpd:header_value(Req, "X-Couch-Persist") /= "false", case call_node(Node, config, get, [Section, Key, undefined]) of undefined -> diff --git a/src/couch/src/couch_httpd_misc_handlers.erl b/src/couch/src/couch_httpd_misc_handlers.erl index eb75a9461..1def94853 100644 --- a/src/couch/src/couch_httpd_misc_handlers.erl +++ b/src/couch/src/couch_httpd_misc_handlers.erl @@ -199,6 +199,7 @@ handle_config_req(#httpd{method='POST', path_parts=[_, <<"_reload">>]}=Req) -> handle_config_req(#httpd{method=Method, path_parts=[_, Section, Key]}=Req) when (Method == 'PUT') or (Method == 'DELETE') -> ok = couch_httpd:verify_is_server_admin(Req), + couch_util:check_config_blacklist(Section), Persist = couch_httpd:header_value(Req, "X-Couch-Persist") /= "false", case config:get("httpd", "config_whitelist", undefined) of undefined -> diff --git a/src/couch/src/couch_util.erl b/src/couch/src/couch_util.erl index 54a92fcc1..4d3d73d66 100644 --- a/src/couch/src/couch_util.erl +++ b/src/couch/src/couch_util.erl @@ -35,12 +35,25 @@ -export([with_proc/4]). -export([process_dict_get/2, process_dict_get/3]). -export([unique_monotonic_integer/0]). +-export([check_config_blacklist/1]). -include_lib("couch/include/couch_db.hrl"). % arbitrarily chosen amount of memory to use before flushing to disk -define(FLUSH_MAX_MEM, 10000000). +-define(BLACKLIST_CONFIG_SECTIONS, [ + <<"daemons">>, + <<"external">>, + <<"httpd_design_handlers">>, + <<"httpd_db_handlers">>, + <<"httpd_global_handlers">>, + <<"native_query_servers">>, + <<"os_daemons">>, + <<"query_servers">> +]). + + priv_dir() -> case code:priv_dir(couch) of {error, bad_name} -> @@ -640,3 +653,12 @@ unique_monotonic_integer() -> erlang:unique_integer([monotonic, positive]). -endif. + +check_config_blacklist(Section) -> + case lists:member(Section, ?BLACKLIST_CONFIG_SECTIONS) of + true -> + Msg = <<"Config section blacklisted for modification over HTTP API.">>, + throw({forbidden, Msg}); + _ -> + ok + end. diff --git a/test/javascript/tests/config.js b/test/javascript/tests/config.js index ee51ef5b9..8c7ce9917 100644 --- a/test/javascript/tests/config.js +++ b/test/javascript/tests/config.js @@ -212,4 +212,12 @@ couchTests.config = function(debug) { headers: {"X-Couch-Persist": "false"} }); TEquals(200, xhr.status, "Reset config whitelist to undefined"); + + // Confirm that the blacklist is functional + ["daemons", "external", "httpd_design_handlers", "httpd_db_handlers", "native_query_servers", "os_daemons", "query_servers"].forEach(function(section) { + xhr = CouchDB.request("PUT", "/_node/node1@127.0.0.1/_config/" + section + "/wohali",{ + body: "\"rules\"" + }); + TEquals(403, xhr.status, "Blacklisted config section " + section); + }); }; diff --git a/test/javascript/tests/erlang_views.js b/test/javascript/tests/erlang_views.js index 8ce9a7e42..ec78e6506 100644 --- a/test/javascript/tests/erlang_views.js +++ b/test/javascript/tests/erlang_views.js @@ -17,9 +17,7 @@ couchTests.erlang_views = function(debug) { if (debug) debugger; run_on_modified_server( - [{section: "native_query_servers", - key: "erlang", - value: "{couch_native_process, start_link, []}"}], + [], function() { // Note we just do some basic 'smoke tests' here - the // test/query_server_spec.rb tests have more comprehensive tests diff --git a/test/javascript/tests/view_sandboxing.js b/test/javascript/tests/view_sandboxing.js index 9e7fa8694..1f97218b7 100644 --- a/test/javascript/tests/view_sandboxing.js +++ b/test/javascript/tests/view_sandboxing.js @@ -148,6 +148,7 @@ couchTests.view_sandboxing = function(debug) { // cleanup db.deleteDb(); +/* TODO: re-enable this test once --no-eval is the default // test that runtime code evaluation can be prevented var couchjs_command_xhr = CouchDB.request( "GET", "_node/node1@127.0.0.1/_config/query_servers/javascript"); @@ -179,6 +180,7 @@ couchTests.view_sandboxing = function(debug) { TEquals(0, results.rows.length); }); +*/ // cleanup CouchDB.request("POST", "_reload_query_servers"); |