From 857c69d5a610ade5ddfec83891491ae50d862df7 Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Tue, 8 Oct 2013 17:06:42 +0200 Subject: [PATCH] added `--server.allow-method-override` startup option --- CHANGELOG | 15 ++++++++ Documentation/Manual/NewFeatures14.md | 10 ++++++ Documentation/UserManual/CommandLine.md | 4 +++ arangod/RestHandler/RestBatchHandler.cpp | 2 +- lib/HttpServer/ApplicationEndpointServer.cpp | 3 ++ lib/HttpServer/ApplicationEndpointServer.h | 27 ++++++++++++++ lib/HttpServer/HttpHandlerFactory.cpp | 13 ++++--- lib/HttpServer/HttpHandlerFactory.h | 7 ++++ lib/Rest/HttpRequest.cpp | 38 ++++++++++++++++---- lib/Rest/HttpRequest.h | 10 +++++- 10 files changed, 117 insertions(+), 12 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b65b310d20..4472344491 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,21 @@ v1.4 ---- +* added startup option `--server.allow-method-override` + + This option can be set to allow overriding the HTTP request method in a request using + one of the following custom headers: + + - x-http-method-override + - x-http-method + - x-method-override + + This allows bypassing proxies and tools that would otherwise just let certain types of + requests pass. Enabling this option may impose a security risk, so it should only be + used in very controlled environments. + + The default value for this option is `false` (no method overriding allowed). + * added "details" URL parameter for bulk import API Setting the `details` URL parameter to `true` in a call to POST `/_api/import` will make diff --git a/Documentation/Manual/NewFeatures14.md b/Documentation/Manual/NewFeatures14.md index a1304508dd..e70c305437 100644 --- a/Documentation/Manual/NewFeatures14.md +++ b/Documentation/Manual/NewFeatures14.md @@ -425,6 +425,16 @@ Command-Line Options added {#NewFeatures14Options} The following command-line options have been added for _arangod_ in ArangoDB 1.4: + * `--server.allow-method-override`: this option can be set to allow overriding the + HTTP request method in a request using one of the following custom headers: + - x-http-method-override + - x-http-method + - x-method-override + Using this option allows bypassing proxies and tools that would otherwise just + let certain types of requests pass. Enabling this option may impose a security + risk, so it should only be used in very controlled environments. + The default value for this option is `false` (no method overriding allowed). + * `--scheduler.maximal-queue-size`: limits the size of the asynchronous request execution queue. Please have a look at @ref NewFeatures14Async for more details. diff --git a/Documentation/UserManual/CommandLine.md b/Documentation/UserManual/CommandLine.md index 2b3034c03f..1989c53508 100644 --- a/Documentation/UserManual/CommandLine.md +++ b/Documentation/UserManual/CommandLine.md @@ -116,6 +116,10 @@ Command-Line Options for arangod {#CommandLineArangod} @anchor CommandLineArangoKeepAliveTimeout @copydetails triagens::rest::ApplicationEndpointServer::_keepAliveTimeout +@CLEARPAGE +@anchor CommandLineArangoAllowMethodOverride +@copydetails triagens::rest::ApplicationEndpointServer::_allowMethodOverride + @CLEARPAGE @anchor CommandLineArangoKeyFile @copydetails triagens::rest::ApplicationEndpointServer::_httpsKeyfile diff --git a/arangod/RestHandler/RestBatchHandler.cpp b/arangod/RestHandler/RestBatchHandler.cpp index 1496b75b64..a296e3ff25 100644 --- a/arangod/RestHandler/RestBatchHandler.cpp +++ b/arangod/RestHandler/RestBatchHandler.cpp @@ -157,7 +157,7 @@ Handler::status_e RestBatchHandler::execute() { // set up request object for the part LOGGER_TRACE("part header is " << string(headerStart, headerLength)); - HttpRequest* request = new HttpRequest(_request->connectionInfo(), headerStart, headerLength); + HttpRequest* request = new HttpRequest(_request->connectionInfo(), headerStart, headerLength, false); if (request == 0) { generateError(HttpResponse::SERVER_ERROR, TRI_ERROR_OUT_OF_MEMORY); diff --git a/lib/HttpServer/ApplicationEndpointServer.cpp b/lib/HttpServer/ApplicationEndpointServer.cpp index e19c5a8e17..0a516dc1bd 100644 --- a/lib/HttpServer/ApplicationEndpointServer.cpp +++ b/lib/HttpServer/ApplicationEndpointServer.cpp @@ -101,6 +101,7 @@ ApplicationEndpointServer::ApplicationEndpointServer (ApplicationServer* applica _httpPort(), _endpoints(), _keepAliveTimeout(300.0), + _allowMethodOverride(false), _backlogSize(10), _httpsKeyfile(), _cafile(), @@ -216,6 +217,7 @@ void ApplicationEndpointServer::setupOptions (map= 13 && + *key == 'x' && *(key + 1) == '-') { + // handle x-... headers + + // override HTTP method? + if ((keyLength == 13 && memcmp(key, "x-http-method", keyLength) == 0) || + (keyLength == 17 && memcmp(key, "x-method-override", keyLength) == 0) || + (keyLength == 22 && memcmp(key, "x-http-method-override", keyLength) == 0)) { + string overridenType(value); + StringUtils::tolowerInPlace(&overridenType); + + _type = getRequestType(overridenType.c_str(), overridenType.size()); + } + } + _headers.insert(key, keyLength, value); } } @@ -623,7 +648,8 @@ void HttpRequest::setUser (string const& user) { /// @brief determine the header type //////////////////////////////////////////////////////////////////////////////// -HttpRequest::HttpRequestType HttpRequest::getRequestType (const char* ptr, const size_t length) { +HttpRequest::HttpRequestType HttpRequest::getRequestType (const char* ptr, + const size_t length) { switch (length) { case 3: if (ptr[0] == 'g' && ptr[1] == 'e' && ptr[2] == 't') { diff --git a/lib/Rest/HttpRequest.h b/lib/Rest/HttpRequest.h index bcaef6b7f5..177ee6ab1c 100644 --- a/lib/Rest/HttpRequest.h +++ b/lib/Rest/HttpRequest.h @@ -119,7 +119,8 @@ namespace triagens { HttpRequest (ConnectionInfo const&, char const*, - size_t); + size_t, + bool); //////////////////////////////////////////////////////////////////////////////// /// @brief destructor @@ -687,6 +688,13 @@ namespace triagens { //////////////////////////////////////////////////////////////////////////////// bool _isRequestContextOwner; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief whether or not overriding the HTTP method via custom headers +/// (x-http-method, x-method-override or x-http-method-override) is allowed +//////////////////////////////////////////////////////////////////////////////// + + bool _allowMethodOverride; }; } }