Skip to content

yew-router does not encode path parameters #3182

Closed
@ColonelThirtyTwo

Description

@ColonelThirtyTwo

Problem
When reading a path parameter from a route, yew-router does not decode escaped characters in the path segment, and passes them to the user as they are in the URL string.

When navigating via Link, path parameters are not encoded, leading to issues when path components have spaces, forward slashes, and other forbidden characters in them.

Steps To Reproduce

Example application:

use yew::prelude::*;
use yew_router::prelude::*;

#[derive(Clone, Routable, PartialEq)]
enum Route {
	#[at("/")]
	Root,
	#[at("/search/:query")]
	Search { query: String },
}

fn switch(route: Route) -> Html {
	match route {
		Route::Root => html!{
			<Link<Route> to={Route::Search { query: "foo bar baz".into() }}>
				{"Do search!"}
			</Link<Route>>
		},
		Route::Search { query } => html!{
			<p>{"You searched for: "}<code>{query.clone()}</code></p>
		},
	}
}

#[function_component]
fn App() -> Html {
	html!{
		<BrowserRouter>
			<Switch<Route> render={switch} />
		</BrowserRouter>
	}
}

fn main() {
	yew::Renderer::<App>::new().render();
}

Clicking the link navigates to Route::Search { query: "foo bar baz" }, whose handler just prints out the query. Clicking the URL goes to http://127.0.0.1:8080/search/foo bar baz which prints You searched for: foo%20bar%20baz.

Replacing the query with "foo/bar/baz" causes the link to go to http://127.0.0.1:8080/search/foo/bar/baz, which is an entirely different route.

Expected behavior

When creating a URL, yew-router should percent-encode characters forbidden in URL components. When parsing a route, yew-router should decode those percent-encoded characters before parsing.

Otherwise, it's quite unintuitive and inconvenient that Routes are not "round-trip safe", and that linking to one route may lead to a different route if the path parameters contain slashes. This may also introduce a url injection vulnerability.

Environment:

  • Yew version: 0.20.0 (yew-router version 0.17.0)
  • Rust version: 1.66.1
  • Target, if relevant: wasm32-unknown-unknown
  • Build tool, if relevant: trunk
  • OS, if relevant: Not relevant
  • Browser and version, if relevant: Not relevant

Questionnaire

  • I'm interested in fixing this myself but don't know where to start
  • I would like to fix and I have a solution
  • I don't have time to fix this right now, but maybe later

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions