diff --git a/CHANGELOG.md b/CHANGELOG.md index cd3709f9b..9538745df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - core: fix memory leak in function util_parse_delay - irc: display nick changes and quit messages when option irc.look.ignore_tag_messages is enabled ([#2241](https://github.com/weechat/weechat/issues/2241)) - perl: fix build when multiplicity is not available ([#2243](https://github.com/weechat/weechat/issues/2243)) +- relay/api: reject any invalid or unknown password hash algorithm in handshake resource - relay/weechat: fix empty buffers in client when WeeChat is running on Solaris/illumos - build: fix build on Solaris/illumos (issue #2251) diff --git a/src/plugins/relay/api/relay-api-protocol.c b/src/plugins/relay/api/relay-api-protocol.c index b1e8fc976..8ba53a478 100644 --- a/src/plugins/relay/api/relay-api-protocol.c +++ b/src/plugins/relay/api/relay-api-protocol.c @@ -401,9 +401,13 @@ RELAY_API_PROTOCOL_CALLBACK(handshake) json_body = cJSON_Parse (client->http_req->body); if (json_body) { + if (!cJSON_IsObject (json_body)) + return RELAY_API_PROTOCOL_RC_BAD_REQUEST; json_algos = cJSON_GetObjectItem (json_body, "password_hash_algo"); if (json_algos) { + if (!cJSON_IsArray (json_algos)) + goto invalid_hash_algo; cJSON_ArrayForEach (json_algo, json_algos) { ptr_algo = (cJSON_IsString (json_algo)) ? @@ -411,7 +415,17 @@ RELAY_API_PROTOCOL_CALLBACK(handshake) if (ptr_algo) { index_hash_algo = relay_auth_password_hash_algo_search (ptr_algo); - if ((index_hash_algo >= 0) && (index_hash_algo > hash_algo_found)) + if (index_hash_algo < 0) + { + relay_api_msg_send_error_json ( + client, + RELAY_HTTP_400_BAD_REQUEST, NULL, + "Hash algorithm \"%s\" not found", + ptr_algo); + cJSON_Delete (json_body); + return RELAY_API_PROTOCOL_RC_OK; + } + if (index_hash_algo > hash_algo_found) { if (weechat_string_match_list ( relay_auth_password_hash_algo_name[index_hash_algo], @@ -422,6 +436,8 @@ RELAY_API_PROTOCOL_CALLBACK(handshake) } } } + else + goto invalid_hash_algo; } } } @@ -460,6 +476,14 @@ RELAY_API_PROTOCOL_CALLBACK(handshake) cJSON_Delete (json_body); return RELAY_API_PROTOCOL_RC_OK; + +invalid_hash_algo: + relay_api_msg_send_error_json ( + client, + RELAY_HTTP_400_BAD_REQUEST, NULL, + "Invalid hash algorithm"); + cJSON_Delete (json_body); + return RELAY_API_PROTOCOL_RC_OK; } /* diff --git a/src/plugins/relay/api/weechat-relay-api.yaml b/src/plugins/relay/api/weechat-relay-api.yaml index 57842eb7a..f1b2d2d7e 100644 --- a/src/plugins/relay/api/weechat-relay-api.yaml +++ b/src/plugins/relay/api/weechat-relay-api.yaml @@ -58,6 +58,12 @@ paths: application/json: schema: $ref: '#/components/schemas/Handshake' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' '503': description: Out of memory content: diff --git a/tests/unit/plugins/relay/api/test-relay-api-protocol.cpp b/tests/unit/plugins/relay/api/test-relay-api-protocol.cpp index 13a0f16d6..08f55daa9 100644 --- a/tests/unit/plugins/relay/api/test-relay-api-protocol.cpp +++ b/tests/unit/plugins/relay/api/test-relay-api-protocol.cpp @@ -321,14 +321,23 @@ TEST(RelayApiProtocolWithClient, CbHandshake) /* unknown password hash algorithm */ test_client_recv_http ("POST /api/handshake", NULL, "{\"password_hash_algo\": [\"invalid\"]}"); - STRCMP_EQUAL("HTTP/1.1 200 OK\r\n" + STRCMP_EQUAL("HTTP/1.1 400 Bad Request\r\n" "Access-Control-Allow-Origin: *\r\n" "Content-Type: application/json; charset=utf-8\r\n" - "Content-Length: 74\r\n" + "Content-Length: 48\r\n" "\r\n" - "{\"password_hash_algo\":null," - "\"password_hash_iterations\":100000," - "\"totp\":false}", + "{\"error\":\"Hash algorithm \\\"invalid\\\" not found\"}", + data_sent[0]); + + /* invalid password hash algorithm */ + test_client_recv_http ("POST /api/handshake", NULL, + "{\"password_hash_algo\": [{}]}"); + STRCMP_EQUAL("HTTP/1.1 400 Bad Request\r\n" + "Access-Control-Allow-Origin: *\r\n" + "Content-Type: application/json; charset=utf-8\r\n" + "Content-Length: 34\r\n" + "\r\n" + "{\"error\":\"Invalid hash algorithm\"}", data_sent[0]); /* two supported hash algorithms */