From 9768f09f6bf73b7ed35d88355a96afc3d96049c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ko=C5=82odziejczak?= <31549762+mrl5@users.noreply.github.com> Date: Fri, 25 Oct 2024 14:04:41 +0200 Subject: [PATCH] proxy: don't follow redirects for user provided JWKS urls + set custom user agent (#9514) partially fixes https://github.com/neondatabase/cloud/issues/19249 ref https://docs.rs/reqwest/latest/reqwest/redirect/index.html > By default, a Client will automatically handle HTTP redirects, having a maximum redirect chain of 10 hops. To customize this behavior, a redirect::Policy can be used with a ClientBuilder. --- .gitignore | 2 ++ proxy/src/auth/backend/jwt.rs | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2c38cdcc59..a07a65ccef 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ __pycache__/ test_output/ .vscode .idea +*.swp +tags neon.iml /.neon /integration_tests/.neon diff --git a/proxy/src/auth/backend/jwt.rs b/proxy/src/auth/backend/jwt.rs index 2185677159..69ab4b8ccb 100644 --- a/proxy/src/auth/backend/jwt.rs +++ b/proxy/src/auth/backend/jwt.rs @@ -5,6 +5,7 @@ use std::time::{Duration, SystemTime}; use arc_swap::ArcSwapOption; use dashmap::DashMap; use jose_jwk::crypto::KeyInfo; +use reqwest::{redirect, Client}; use serde::de::Visitor; use serde::{Deserialize, Deserializer}; use signature::Verifier; @@ -24,6 +25,7 @@ const MIN_RENEW: Duration = Duration::from_secs(30); const AUTO_RENEW: Duration = Duration::from_secs(300); const MAX_RENEW: Duration = Duration::from_secs(3600); const MAX_JWK_BODY_SIZE: usize = 64 * 1024; +const JWKS_USER_AGENT: &str = "neon-proxy"; /// How to get the JWT auth rules pub(crate) trait FetchAuthRules: Clone + Send + Sync + 'static { @@ -50,7 +52,6 @@ pub(crate) struct AuthRule { pub(crate) role_names: Vec, } -#[derive(Default)] pub struct JwkCache { client: reqwest::Client, @@ -357,6 +358,20 @@ impl JwkCache { } } +impl Default for JwkCache { + fn default() -> Self { + let client = Client::builder() + .user_agent(JWKS_USER_AGENT) + .redirect(redirect::Policy::none()) + .build() + .expect("using &str and standard redirect::Policy"); + JwkCache { + client, + map: DashMap::default(), + } + } +} + fn verify_ec_signature(data: &[u8], sig: &[u8], key: &jose_jwk::Ec) -> Result<(), JwtError> { use ecdsa::Signature; use signature::Verifier;