SSD Advisory – AppWeb Authentication Bypass (Digest, and Basic)
Credit to Author: SSD / Noam Rathaus| Date: Wed, 14 Mar 2018 19:01:53 +0000
Want to get paid for a vulnerability similar to this one?
Contact us at: sxsxdx@xbxexyxoxnxdxsxexcxuxrxixtxy.xcom
See our full scope at: https://blogs.securiteam.com/index.php/product_scope
Vulnerability Summary
A critical vulnerability in the EmbedThis HTTP library, and Appweb versions 5.5.x, 6.x, and 7.x including the latest version present in the git repository.
In detail, due to a logic flaw, with a forged HTTP request it is possible to bypass the authentication for HTTP basic and HTTP digest login types.
Confirmed Vulnerable
Appweb version 7.0.2 and prior
Credit
An independent security researcher, Davide Quarta (@_ocean) and Truel IT, has reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program.
Vendor Response
Vendor response was exceptionally quick, within 2 days from reporting the vulnerability to them they had a patch available and new version Appweb version 7.0.3 and information available to the public: https://github.com/embedthis/appweb/issues/610
CVE
CVE-2018-8715
Vulnerability Details
Due to a logical flaw in the authentication procedure, knowing the target username, it is possible to completely bypass authentication of both form and digest type authentications, by means of a crafted HTTP POST request.
File http/httpLib.c – function authCondition()
This function is responsible for calling the two functions that are responsible of authentication: getCredentials, and httpLogin. Notice the lack of checks around httpGetCredentials, it will be useful later.
File http/httpLib.c – function httpGetCredentials()
This function receives two pointers to char arrays that will contain the username and password parsed from the request. Since there are no checks in authCondition, it doesn’t matter if the “parseAuth” function fail, this means we can insert in the WWW-Authenticate header or in the post data for authentication any field we want:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 1640 /* 1641 Get the username and password credentials. If using an in-protocol auth scheme like basic|digest, the 1642 rx->authDetails will contain the credentials and the parseAuth callback will be invoked to parse. 1643 Otherwise, it is expected that “username” and “password” fields are present in the request parameters. 1644 1645 This is called by authCondition which thereafter calls httpLogin 1646 */ 1647 PUBLIC bool httpGetCredentials(HttpConn *conn, cchar **username, cchar **password) 1648 { 1649 HttpAuth *auth; 1650 1651 assert(username); 1652 assert(password); 1653 *username = *password = NULL; 1654 1655 auth = conn->rx->route->auth; 1656 if (!auth || !auth->type) { 1657 return 0; 1658 } 1659 if (auth->type) { 1660 if (conn->authType && !smatch(conn->authType, auth->type->name)) { 1661 if (!(smatch(auth->type->name, “form”) && conn->rx->flags & HTTP_POST)) { 1662 /* If a posted form authentication, ignore any basic|digest details in request */ 1663 return 0; 1664 } 1665 } 1666 if (auth->type->parseAuth && (auth->type->parseAuth)(conn, username, password) < 0) { 1667 return 0; 1668 } 1669 } else { 1670 *username = httpGetParam(conn, “username”, 0); 1671 *password = httpGetParam(conn, “password”, 0); 1672 } 1673 return 1; 1674 } |
File http/httpLib.c – function httpLogin()
This function will check for the username to be not null, when there is already a session associated, the password pointer can instead be null.