Skip to content

Commit 35b5dae

Browse files
committed
Fix integer overflow in basic password authentication
The string lengths were added and then stored in "char" which is limited in values at most up to 255. Using size_t is a much more appropriate type. In addition the code was using base64 with newlines injected (easy to fall into that trap as the default is imho wrong), which means that anything longer than ~ 60 characters never matched and you had no way to authenticate against the server.
1 parent 32470fb commit 35b5dae

File tree

1 file changed

+22
-34
lines changed

1 file changed

+22
-34
lines changed

libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h

+22-34
Original file line numberDiff line numberDiff line change
@@ -121,41 +121,29 @@ String ESP8266WebServerTemplate<ServerType>::_extractParam(String& authReq,const
121121
}
122122

123123
template <typename ServerType>
124-
bool ESP8266WebServerTemplate<ServerType>::authenticate(const char * username, const char * password){
125-
if(hasHeader(FPSTR(AUTHORIZATION_HEADER))) {
126-
String authReq = header(FPSTR(AUTHORIZATION_HEADER));
127-
if(authReq.startsWith(F("Basic"))){
128-
authReq = authReq.substring(6);
129-
authReq.trim();
130-
char toencodeLen = strlen(username)+strlen(password)+1;
131-
char *toencode = new (std::nothrow) char[toencodeLen + 1];
132-
if(toencode == NULL){
133-
authReq = "";
134-
return false;
135-
}
136-
char *encoded = new (std::nothrow) char[base64_encode_expected_len(toencodeLen)+1];
137-
if(encoded == NULL){
138-
authReq = "";
139-
delete[] toencode;
140-
return false;
141-
}
142-
sprintf(toencode, "%s:%s", username, password);
143-
if(base64_encode_chars(toencode, toencodeLen, encoded) > 0 && authReq.equalsConstantTime(encoded)) {
144-
authReq = "";
145-
delete[] toencode;
146-
delete[] encoded;
147-
return true;
148-
}
149-
delete[] toencode;
150-
delete[] encoded;
151-
} else if(authReq.startsWith(F("Digest"))) {
152-
String _realm = _extractParam(authReq, F("realm=\""));
153-
String _H1 = credentialHash((String)username,_realm,(String)password);
154-
return authenticateDigest((String)username,_H1);
124+
bool ESP8266WebServerTemplate<ServerType>::authenticate(const char* name, const char* pass) {
125+
if (hasHeader(FPSTR(AUTHORIZATION_HEADER))) {
126+
String authReq = header(FPSTR(AUTHORIZATION_HEADER));
127+
String username(name);
128+
String password(pass);
129+
130+
if (authReq.startsWith(F("Basic"))) {
131+
authReq = authReq.substring(6);
132+
authReq.trim();
133+
String toencode;
134+
toencode.reserve(username.length() + 1 + password.length());
135+
136+
toencode += username;
137+
toencode += ':';
138+
toencode += password;
139+
return authReq.equalsConstantTime(::base64::encode(toencode, false /* doNewLines */));
140+
} else if (authReq.startsWith(F("Digest"))) {
141+
return authenticateDigest(
142+
username, credentialHash(
143+
username, _extractParam(authReq, F("realm=\"")), password));
144+
}
155145
}
156-
authReq = "";
157-
}
158-
return false;
146+
return false;
159147
}
160148

161149
template <typename ServerType>

0 commit comments

Comments
 (0)