Skip to content

Commit 0a2ee67

Browse files
authored
Encode user provided state (#401)
1 parent 0358a1e commit 0a2ee67

4 files changed

Lines changed: 8 additions & 2 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ newtype-uuid = { version = "1.3.2", features = ["schemars08", "serde", "v4"] }
3434
oauth2 = { version = "5.0.0", default-features = false, features = ["rustls-tls"] }
3535
oauth2-reqwest = "0.1.0-alpha.3"
3636
partial-struct = { git = "https://github.com/oxidecomputer/partial-struct" }
37+
percent-encoding = "2.3.2"
3738
proc-macro2 = "1"
3839
quote = "1"
3940
rand = "0.8.5"

v-api/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ oauth2 = { workspace = true }
2626
oauth2-reqwest = { workspace = true }
2727
newtype-uuid = { workspace = true }
2828
partial-struct = { workspace = true }
29+
percent-encoding = { workspace = true }
2930
rand = { workspace = true, features = ["std"] }
3031
rand_core = { workspace = true, features = ["std"] }
3132
reqwest = { workspace = true }

v-api/src/endpoints/login/oauth/code.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use newtype_uuid::TypedUuid;
1919
use oauth2::{
2020
AuthorizationCode, CsrfToken, PkceCodeChallenge, PkceCodeVerifier, Scope, TokenResponse,
2121
};
22+
use percent_encoding::{percent_encode, NON_ALPHANUMERIC};
2223
use schemars::JsonSchema;
2324
use secrecy::SecretString;
2425
use serde::{Deserialize, Serialize};
@@ -205,8 +206,10 @@ where
205206
// Assign any scope errors that arose
206207
attempt.error = scope_error;
207208

208-
// Add in the user defined state and redirect uri
209-
attempt.state = Some(query.state);
209+
// Add in the user defined state and redirect uri. State is an arbitrary value and may be
210+
// malicious. It must be url-encoded before being presented back to the client. Therefore we
211+
// process once before storing so all downstream consumers see the encoded value.
212+
attempt.state = Some(percent_encode(query.state.as_bytes(), NON_ALPHANUMERIC).to_string());
210213

211214
// If the remote provider supports pkce, set up a challenge
212215
let pkce_challenge = if provider.supports_pkce() {

0 commit comments

Comments
 (0)