CVE-2017-5473 (published 2017-01-14T07:59Z)

Cross-site request forgery (CSRF) vulnerability in ntopng through 2.4 allows remote attackers to hijack the authentication of arbitrary users, as demonstrated by admin/add_user.lua, admin/change_user_prefs.lua, admin/delete_user.lua, and admin/password_reset.lua.

Severity: MEDIUM
CVSS v2 base score: 6.8 (AV:N/AC:M/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 8.8, HIGH (CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-352
cwe_name: Cross-Site Request Forgery (CSRF)
description: The web application does not, or can not, sufficiently verify whether a well-formed, valid, consistent request was intentionally provided by the user who submitted the request.
extended_description: When a web server is designed to receive a request from a client without any mechanism for verifying that it was intentionally sent, then it might be possible for an attacker to trick a client into making an unintentional request to the web server which will be treated as an authentic request. This can be done via a URL, image load, XMLHttpRequest, etc. and can result in exposure of data or unintended code execution.
         

Fix information:
repo_url: https://github.com/ntop/ntopng
commit_details: repo_url: https://github.com/ntop/ntopng
author: Luca
author_date: 2017-01-12 06:45:41-08:00
msg: Check for presence of crsf in admin scripts
repository: repo_url: https://github.com/ntop/ntopng
repo_name: ntop/ntopng
description: Web-based Traffic and Security Network Traffic Monitoring
repo_language: Lua
owner: ntop
file_changes: filename: Lua.cpp
change_type: ModificationType.MODIFY
diff: @@ -5680,7 +5680,8 @@ int Lua::handle_script_request(struct mg_connection *conn,
   char *_cookies, user[64] = { '\0' }, outbuf[FILENAME_MAX];
   AddressTree ptree;
   int rc;
-
+  bool csrf_found = false;
+  
   if(!L) return(-1);
 
   luaL_openlibs(L); /* Load base libraries */
@@ -5693,11 +5694,11 @@ int Lua::handle_script_request(struct mg_connection *conn,
   lua_newtable(L);
   if(request_info->query_string != NULL) {
     char *query_string = strdup(request_info->query_string);
-
+    
     if(query_string) {
       char *where;
       char *tok;
-
+      
       // ntop->getTrace()->traceEvent(TRACE_WARNING, "[HTTP] %s", query_string);
 
       tok = strtok_r(query_string, "&", &where);
@@ -5759,6 +5760,8 @@ int Lua::handle_script_request(struct mg_connection *conn,
 				    msg, PAGE_ERROR, query_string, msg));
 		} else
 		  ntop->getRedis()->delKey(decoded_buf);
+
+		csrf_found = true;
 	      }
 
 	      lua_push_str_table_entry(L, tok, decoded_buf);
@@ -5777,6 +5780,13 @@ int Lua::handle_script_request(struct mg_connection *conn,
     } else
       ntop->getTrace()->traceEvent(TRACE_WARNING, "Not enough memory");
   }
+
+  if(strstr(request_info->uri, "/admin/") && (!csrf_found)) {
+    const char *msg = "Missing CSRF parameter";
+    
+    return(send_error(conn, 500 /* Internal server error */, msg, PAGE_ERROR, request_info->uri, msg));
+  }
+  
   lua_setglobal(L, "_GET"); /* Like in php */
 
   /* _SERVER */

programming_language: C++
repo_url: https://github.com/ntop/ntopng
commit_details: repo_url: https://github.com/ntop/ntopng
author: Luca
author_date: 2017-01-12 10:10:20-08:00
msg: Added fixes to avoid users to be manipulated with invalid CSRF token
repository: repo_url: https://github.com/ntop/ntopng
repo_name: ntop/ntopng
description: Web-based Traffic and Security Network Traffic Monitoring
repo_language: Lua
owner: ntop
file_changes: filename: add_user.lua
change_type: ModificationType.MODIFY
diff: @@ -8,6 +8,7 @@ require "lua_utils"
 
 sendHTTPHeader('text/html; charset=iso-8859-1')
 
+if(_GET["csrf"] ~= nil) then
 if(haveAdminPrivileges()) then
    username = _GET["username"]
    full_name = _GET["full_name"]
@@ -33,3 +34,4 @@ if(haveAdminPrivileges()) then
       print ("{ \"result\" : -1, \"message\" : \"Error while adding new user\" }")
    end
 end
+end
\ No newline at end of file

programming_language: Lua
filename: change_user_prefs.lua
change_type: ModificationType.MODIFY
diff: @@ -8,6 +8,7 @@ require "lua_utils"
 
 sendHTTPHeader('application/json')
 
+if(_GET["csrf"] ~= nil) then
 username = _GET["username"]
 host_role = _GET["host_role"]
 networks = _GET["networks"]
@@ -40,3 +41,4 @@ if(allowed_interface ~= nil) then
 end
 
 print ("{ \"result\" : 0, \"message\" : \"Parameters Updated\" }")
+end
\ No newline at end of file

programming_language: Lua
filename: delete_user.lua
change_type: ModificationType.MODIFY
diff: @@ -8,6 +8,7 @@ require "lua_utils"
 
 sendHTTPHeader('text/html; charset=iso-8859-1')
 
+if(_GET["csrf"] ~= nil) then
 if(haveAdminPrivileges()) then
    username = _GET["username"]
    
@@ -22,3 +23,4 @@ if(haveAdminPrivileges()) then
       print ("{ \"result\" : -1, \"message\" : \"Error deleting user\" }")
    end
 end
+end
\ No newline at end of file

programming_language: Lua
filename: password_reset.lua
change_type: ModificationType.MODIFY
diff: @@ -8,6 +8,7 @@ require "lua_utils"
 
 sendHTTPHeader('text/html; charset=iso-8859-1')
 
+if(_GET["csrf"] ~= nil) then
 username = _GET["username"]
 old_password = _GET["old_password"]
 new_password = _GET["new_password"]
@@ -36,3 +37,4 @@ if(ntop.resetUserPassword(_SESSION["user"], username, old_password, new_password
 else
    print ("{ \"result\" : -1, \"message\" : \"Unable to set the new user password: perhaps the old password was invalid ?\" }")
 end
+end
\ No newline at end of file

programming_language: Ruby