mitigate dns rebinding in webui

pull/1112/head
Jeff Becker 6 years ago
parent b6e75e9c5a
commit 0309b574e8
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -733,8 +733,9 @@ namespace http {
} }
} }
HTTPConnection::HTTPConnection (std::shared_ptr<boost::asio::ip::tcp::socket> socket): HTTPConnection::HTTPConnection (std::string hostname, std::shared_ptr<boost::asio::ip::tcp::socket> socket):
m_Socket (socket), m_Timer (socket->get_io_service ()), m_BufferLen (0) m_Socket (socket), m_Timer (socket->get_io_service ()), m_BufferLen (0),
expected_host(hostname)
{ {
/* cache options */ /* cache options */
i2p::config::GetOption("http.auth", needAuth); i2p::config::GetOption("http.auth", needAuth);
@ -833,7 +834,28 @@ namespace http {
SendReply(res, content); SendReply(res, content);
return; return;
} }
bool strictheaders;
i2p::config::GetOption("http.strictheaders", strictheaders);
if (strictheaders)
{
std::string http_hostname;
i2p::config::GetOption("http.hostname", http_hostname);
std::string host = req.GetHeader("Host");
auto idx = host.find(':');
/* strip out port so it's just host */
if (idx != std::string::npos && idx > 0)
{
host = host.substr(0, idx);
}
if (!(host == expected_host || host == http_hostname))
{
/* deny request as it's from a non whitelisted hostname */
res.code = 403;
content = "host missmatch";
SendReply(res, content);
return;
}
}
// Html5 head start // Html5 head start
ShowPageHead (s); ShowPageHead (s);
if (req.uri.find("page=") != std::string::npos) { if (req.uri.find("page=") != std::string::npos) {
@ -976,7 +998,8 @@ namespace http {
HTTPServer::HTTPServer (const std::string& address, int port): HTTPServer::HTTPServer (const std::string& address, int port):
m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service), m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service),
m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint (boost::asio::ip::address::from_string(address), port)) m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint (boost::asio::ip::address::from_string(address), port)),
m_Hostname(address)
{ {
} }
@ -1061,7 +1084,7 @@ namespace http {
void HTTPServer::CreateConnection(std::shared_ptr<boost::asio::ip::tcp::socket> newSocket) void HTTPServer::CreateConnection(std::shared_ptr<boost::asio::ip::tcp::socket> newSocket)
{ {
auto conn = std::make_shared<HTTPConnection> (newSocket); auto conn = std::make_shared<HTTPConnection> (m_Hostname, newSocket);
conn->Receive (); conn->Receive ();
} }
} // http } // http

@ -21,7 +21,7 @@ namespace http
{ {
public: public:
HTTPConnection (std::shared_ptr<boost::asio::ip::tcp::socket> socket); HTTPConnection (std::string serverhost, std::shared_ptr<boost::asio::ip::tcp::socket> socket);
void Receive (); void Receive ();
private: private:
@ -46,6 +46,7 @@ namespace http
bool needAuth; bool needAuth;
std::string user; std::string user;
std::string pass; std::string pass;
std::string expected_host;
static std::map<uint32_t, uint32_t> m_Tokens; // token->timestamp in seconds static std::map<uint32_t, uint32_t> m_Tokens; // token->timestamp in seconds
}; };
@ -75,6 +76,7 @@ namespace http
boost::asio::io_service m_Service; boost::asio::io_service m_Service;
boost::asio::io_service::work m_Work; boost::asio::io_service::work m_Work;
boost::asio::ip::tcp::acceptor m_Acceptor; boost::asio::ip::tcp::acceptor m_Acceptor;
std::string m_Hostname;
}; };
//all the below functions are also used by Qt GUI, see mainwindow.cpp -> getStatusPageHtml //all the below functions are also used by Qt GUI, see mainwindow.cpp -> getStatusPageHtml

@ -83,6 +83,8 @@ namespace config {
("http.auth", value<bool>()->default_value(false), "Enable Basic HTTP auth for webconsole") ("http.auth", value<bool>()->default_value(false), "Enable Basic HTTP auth for webconsole")
("http.user", value<std::string>()->default_value("i2pd"), "Username for basic auth") ("http.user", value<std::string>()->default_value("i2pd"), "Username for basic auth")
("http.pass", value<std::string>()->default_value(""), "Password for basic auth (default: random, see logs)") ("http.pass", value<std::string>()->default_value(""), "Password for basic auth (default: random, see logs)")
("http.strictheaders", value<bool>()->default_value(true), "Enable strict host checking on WebUI")
("http.hostname", value<std::string>()->default_value("localhost"),"Expected hostname for WebUI")
; ;
options_description httpproxy("HTTP Proxy options"); options_description httpproxy("HTTP Proxy options");

Loading…
Cancel
Save