Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(prusalink): increase nonce valid period #3371

Merged
merged 2 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions lib/WUI/nhttp/req_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,13 +306,11 @@ bool RequestParser::nonce_valid(uint64_t nonce_to_check) const {
uint32_t random = static_cast<uint32_t>(nonce_to_check >> 32);
uint32_t time = nonce_to_check & 0xffffffff;
uint32_t age = ticks_s() - time;
// Make valid period for POST and PUT longer, to avoid infinit uploading
// loops if nonce get stale for upload request.
uint32_t max_valid_age = has_body(method) ? http::extended_valid_nonce_period : http::valid_nonce_period;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ternary is no longer needed with a max_valid_age of 300.


// sanity check
if (nonce_random != 0) {
// really valid?
if (random == nonce_random && age < max_valid_age) {
if (random == nonce_random && age < http::valid_nonce_period) {
return true;
}
}
Expand Down
13 changes: 7 additions & 6 deletions src/common/http/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,12 @@ static const size_t MAX_URL_LEN = 168;
using Url = std::array<char, MAX_URL_LEN>;

// # of seconds after which nonce becomes stale for digest authentication
// the extended version is used for requests with body, so that PrusaLink
// hopefully never gets stale nonce for request uploading a gcode, which
// can cause an infinit upload loop, if the browser does not read errors
// before sending the whole body.
static const uint32_t valid_nonce_period = 5;
static const uint32_t extended_valid_nonce_period = 8;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The extended_valid_nonce_period variable is no longer needed, since the only value used in now 300.

// The value of 300 has been chosen as it's the default value used in the Apache
// web server, see:
// https://httpd.apache.org/docs/2.4/mod/mod_auth_digest.html#authdigestnoncelifetime
//
// This value use to be much lower but would cause issues with Safari-based browser
// See https://github.com/prusa3d/Prusa-Firmware-Buddy/issues/3287
static const uint32_t valid_nonce_period = 300;

} // namespace http
8 changes: 4 additions & 4 deletions tests/unit/lib/WUI/nhttp/server_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ TEST_CASE("Digest stale nonce") {
REQUIRE(client_conn == 1);

SECTION("Real stale nonce") {
set_time(0x0000000f);
set_time(0x00000fff);
string request = digest_auth_header("GET", "maker", "aaaaaaaa00000000", "/secret.html", "0cbf0ac5ca4c879c35a3b91430214a47");
server.send(client_conn, request);
}
Expand All @@ -580,7 +580,7 @@ TEST_CASE("Digest stale nonce") {

const auto response = server.recv_all(client_conn);
// Note: connection should be kept alive, beacause it is save to do with GET
check_unauth_digest(response, "aaaaaaaa0000000f", "true", "keep-alive");
check_unauth_digest(response, "aaaaaaaa00000fff", "true", "keep-alive");
}

// should resolve to stale=false, because client should not retry with different nonce
Expand All @@ -592,13 +592,13 @@ TEST_CASE("Stale nonce and wrong auth") {
const size_t client_conn = server.new_conn();
REQUIRE(client_conn == 1);

set_time(0x0000000f);
set_time(0x00000fff);
string request = digest_auth_header("GET", "invaliduser", "aaaaaaaa00000000", "/secret.html", "1dd8be56e6996b274258d7412e671e5f");
server.send(client_conn, request);

const auto response = server.recv_all(client_conn);
// Note: connection should be kept alive, beacause it is save to do with GET
check_unauth_digest(response, "aaaaaaaa0000000f", "false", "keep-alive");
check_unauth_digest(response, "aaaaaaaa00000fff", "false", "keep-alive");
}

TEST_CASE("Not authenticated digest error close") {
Expand Down