Repository navigation
Conversation
get_found_bp rebuilds the matched blueprint chain from found.blueprint_indices, each entry being a blueprint's position in its parent's child list. verify_prefix() checks bp_i[index] against the list size only on the matched path; the else branch indexes blueprints_ and last_element->blueprints_ with no check. A parent blueprint that registers no route of its own (e.g. under CROW_DISABLE_STATIC_DIR) leaves a child's parent-relative index as the first collected index, so a 404 under that child reads past the top-level blueprint vector and the garbage Blueprint* is later dereferenced. Reuse the existing bounds check before both indexing sites.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
get_found_bp rebuilds the matched blueprint chain from found.blueprint_indices, where each value is a blueprint's index within its parent's child list. The verify_prefix() lambda checks bp_i[index] against the list size only on the matched (if) path; the else path indexes blueprints_[bp_i[index]] and last_element->blueprints_[bp_i[index]] with no bounds check.
When a parent blueprint has no route of its own, no trie node carries its index. That is the normal case under CROW_DISABLE_STATIC_DIR, where run() skips add_blueprint()/add_static_dir() so a static-dir blueprint never gets a route of its own. A 404 under one of its child blueprints then leaves the child's parent-relative index as the first entry of blueprint_indices, and get_found_bp indexes the router's top-level blueprint vector with it, reading past the end when it is larger than the number of top-level blueprints. The out-of-bounds Blueprint* is pushed into found_bps and later dereferenced by get_catch_all()/get_error(), so it is reachable from any unauthenticated request URL that 404s under such a blueprint.
The fix applies the same bounds check the if-path already uses before both indexing sites, falling back to the global catchall when the index is out of range.
Added blueprint_catchall_oob to tests/unittest.cpp: it registers a parent blueprint with two child blueprints, validates without the static-dir routes (the CROW_DISABLE_STATIC_DIR path), and sends a 404 under the second child. It fails on master under -fsanitize=address (heap-buffer-overflow in get_found_bp at routing.h:1566) and passes with this change. The full test suite stays green under the ci-sanitize build.