From 4aa0eb97e4c90490a9c84a0d8bd57cd22572c37a Mon Sep 17 00:00:00 2001 From: KLuka Date: Thu, 3 Dec 2015 17:44:31 +0100 Subject: [PATCH] Disable HTTP fallback via "/plain" URL (CVE-2015-8400) * Disabled all methods of HTTP fallback when HTTPS is enabled. This is enforced on server side so that even modified client code (JS) can not redirect client from HTTPS to HTTP, like it was possible before (issue #355). * Current solution unfortunately also disables automatic upgrade from HTTP to HTTPS (when available), since all non-SSL connections are droped immediately. --- libhttp/http.h | 2 +- libhttp/httpconnection.c | 7 +++++++ libhttp/server.c | 7 ++++--- libhttp/server.h | 2 +- libhttp/ssl.c | 7 +++++++ libhttp/ssl.h | 2 ++ shellinabox/shellinaboxd.c | 4 +++- 7 files changed, 25 insertions(+), 6 deletions(-) diff --git a/libhttp/http.h b/libhttp/http.h index c754a29..35a5ac9 100644 --- a/libhttp/http.h +++ b/libhttp/http.h @@ -102,7 +102,7 @@ short serverConnectionSetEvents(Server *server, ServerConnection *connection, void serverExitLoop(Server *server, int exitAll); void serverLoop(Server *server); int serverSupportsSSL(); -void serverEnableSSL(Server *server, int flag); +void serverSetupSSL(Server *server, int enable, int force); void serverSetCertificate(Server *server, const char *filename, int autoGenerateMissing); void serverSetCertificateFd(Server *server, int fd); diff --git a/libhttp/httpconnection.c b/libhttp/httpconnection.c index 31e41d8..95a63cd 100644 --- a/libhttp/httpconnection.c +++ b/libhttp/httpconnection.c @@ -1480,6 +1480,13 @@ int httpHandleConnection(struct ServerConnection *connection, void *http_, *events |= POLLIN; continue; } + } else { + if (http->ssl && http->ssl->enabled && http->ssl->force) { + debug("[http] Non-SSL connections not allowed!"); + httpCloseRead(http); + bytes = 0; + eof = 1; + } } } diff --git a/libhttp/server.c b/libhttp/server.c index 451590c..d19a3a0 100644 --- a/libhttp/server.c +++ b/libhttp/server.c @@ -670,11 +670,12 @@ void serverLoop(struct Server *server) { server->looping = loopDepth - 1; } -void serverEnableSSL(struct Server *server, int flag) { - if (flag) { +void serverSetupSSL(struct Server *server, int enable, int force) { + if (enable) { check(serverSupportsSSL()); } - sslEnable(&server->ssl, flag); + sslEnable(&server->ssl, enable); + sslForce(&server->ssl, force); } void serverSetCertificate(struct Server *server, const char *filename, diff --git a/libhttp/server.h b/libhttp/server.h index 2653771..15b3c73 100644 --- a/libhttp/server.h +++ b/libhttp/server.h @@ -118,7 +118,7 @@ short serverConnectionSetEvents(struct Server *server, short events); void serverExitLoop(struct Server *server, int exitAll); void serverLoop(struct Server *server); -void serverEnableSSL(struct Server *server, int flag); +void serverSetupSSL(struct Server *server, int enable, int force); void serverSetCertificate(struct Server *server, const char *filename, int autoGenerateMissing); void serverSetCertificateFd(struct Server *server, int fd); diff --git a/libhttp/ssl.c b/libhttp/ssl.c index c11f237..083f375 100644 --- a/libhttp/ssl.c +++ b/libhttp/ssl.c @@ -167,6 +167,7 @@ struct SSLSupport *newSSL(void) { void initSSL(struct SSLSupport *ssl) { ssl->enabled = serverSupportsSSL(); + ssl->force = 0; ssl->sslContext = NULL; ssl->sniCertificatePattern = NULL; ssl->generateMissing = 0; @@ -894,6 +895,12 @@ int sslEnable(struct SSLSupport *ssl, int enabled) { return old; } +int sslForce(struct SSLSupport *ssl, int force) { + int old = ssl->force; + ssl->force = force; + return old; +} + void sslBlockSigPipe(void) { sigset_t set; sigemptyset(&set); diff --git a/libhttp/ssl.h b/libhttp/ssl.h index 0be3830..2346549 100644 --- a/libhttp/ssl.h +++ b/libhttp/ssl.h @@ -198,6 +198,7 @@ extern void *(*x_SSL_COMP_get_compression_methods)(void); struct SSLSupport { int enabled; + int force; SSL_CTX *sslContext; char *sniCertificatePattern; int generateMissing; @@ -214,6 +215,7 @@ void sslSetCertificate(struct SSLSupport *ssl, const char *filename, int autoGenerateMissing); void sslSetCertificateFd(struct SSLSupport *ssl, int fd); int sslEnable(struct SSLSupport *ssl, int enabled); +int sslForce(struct SSLSupport *ssl, int force); void sslBlockSigPipe(); int sslUnblockSigPipe(); int sslPromoteToSSL(struct SSLSupport *ssl, SSL **sslHndl, int fd, diff --git a/shellinabox/shellinaboxd.c b/shellinabox/shellinaboxd.c index cabe922..ad911cf 100644 --- a/shellinabox/shellinaboxd.c +++ b/shellinabox/shellinaboxd.c @@ -112,6 +112,7 @@ static int noBeep = 0; static int numericHosts = 0; static int enableSSL = 1; static int enableSSLMenu = 1; +static int forceSSL = 1; // TODO enable http fallback with commandline option int enableUtmpLogging = 1; static char *messagesOrigin = NULL; static int linkifyURLs = 1; @@ -1302,7 +1303,8 @@ static void removeLimits() { } static void setUpSSL(Server *server) { - serverEnableSSL(server, enableSSL); + + serverSetupSSL(server, enableSSL, forceSSL); // Enable SSL support (if available) if (enableSSL) {