You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-29 22:01:14 +03:00
Disallow Ulid generation without explicit timestamp and rng
This commit is contained in:
@ -4,6 +4,8 @@ doc-valid-idents = ["OpenID", "OAuth", ".."]
|
||||
disallowed-methods = [
|
||||
{ path = "rand::thread_rng", reason = "do not create rngs on the fly, pass them as parameters" },
|
||||
{ path = "chrono::Utc::now", reason = "source the current time from the clock instead" },
|
||||
{ path = "ulid::Ulid::from_datetime", reason = "use Ulid::from_datetime_with_source instead" },
|
||||
{ path = "ulid::Ulid::new", reason = "use Ulid::from_datetime_with_source instead" },
|
||||
]
|
||||
|
||||
disallowed-types = [
|
||||
|
@ -54,6 +54,8 @@ impl Options {
|
||||
pub async fn run(&self, root: &super::Options) -> anyhow::Result<()> {
|
||||
use Subcommand as SC;
|
||||
let clock = Clock::default();
|
||||
// XXX: we should disallow SeedableRng::from_entropy
|
||||
let mut rng = rand_chacha::ChaChaRng::from_entropy();
|
||||
|
||||
match &self.subcommand {
|
||||
SC::Register { username, password } => {
|
||||
@ -61,9 +63,9 @@ impl Options {
|
||||
let pool = config.connect().await?;
|
||||
let mut txn = pool.begin().await?;
|
||||
let hasher = Argon2::default();
|
||||
let rng = rand_chacha::ChaChaRng::from_entropy();
|
||||
|
||||
let user = register_user(&mut txn, rng, &clock, hasher, username, password).await?;
|
||||
let user =
|
||||
register_user(&mut txn, &mut rng, &clock, hasher, username, password).await?;
|
||||
txn.commit().await?;
|
||||
info!(?user, "User registered");
|
||||
|
||||
@ -126,6 +128,8 @@ impl Options {
|
||||
|
||||
insert_client_from_config(
|
||||
&mut txn,
|
||||
&mut rng,
|
||||
&clock,
|
||||
client_id,
|
||||
client_auth_method,
|
||||
encrypted_client_secret.as_deref(),
|
||||
|
@ -109,6 +109,7 @@ pub(crate) async fn post(
|
||||
State(policy_factory): State<Arc<PolicyFactory>>,
|
||||
Json(body): Json<ClientMetadata>,
|
||||
) -> Result<impl IntoResponse, RouteError> {
|
||||
let (clock, mut rng) = crate::rng_and_clock()?;
|
||||
info!(?body, "Client registration");
|
||||
|
||||
// Validate the body
|
||||
@ -127,10 +128,12 @@ pub(crate) async fn post(
|
||||
let mut txn = pool.begin().await?;
|
||||
|
||||
// Let's generate a random client ID
|
||||
let client_id = Ulid::new();
|
||||
let client_id = Ulid::from_datetime_with_source(clock.now().into(), &mut rng);
|
||||
|
||||
insert_client(
|
||||
&mut txn,
|
||||
&mut rng,
|
||||
&clock,
|
||||
client_id,
|
||||
metadata.redirect_uris(),
|
||||
None,
|
||||
|
@ -21,13 +21,14 @@ use mas_iana::{
|
||||
};
|
||||
use mas_jose::jwk::PublicJsonWebKeySet;
|
||||
use oauth2_types::requests::GrantType;
|
||||
use rand::Rng;
|
||||
use sqlx::{PgConnection, PgExecutor};
|
||||
use thiserror::Error;
|
||||
use ulid::Ulid;
|
||||
use url::Url;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::PostgresqlBackend;
|
||||
use crate::{Clock, PostgresqlBackend};
|
||||
|
||||
// XXX: response_types & contacts
|
||||
#[derive(Debug)]
|
||||
@ -317,6 +318,8 @@ pub async fn lookup_client_by_client_id(
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn insert_client(
|
||||
conn: &mut PgConnection,
|
||||
mut rng: impl Rng + Send,
|
||||
clock: &Clock,
|
||||
client_id: Ulid,
|
||||
redirect_uris: &[Url],
|
||||
encrypted_client_secret: Option<&str>,
|
||||
@ -391,9 +394,15 @@ pub async fn insert_client(
|
||||
.execute(&mut *conn)
|
||||
.await?;
|
||||
|
||||
let now = clock.now();
|
||||
let (ids, redirect_uris): (Vec<Uuid>, Vec<String>) = redirect_uris
|
||||
.iter()
|
||||
.map(|uri| (Uuid::from(Ulid::new()), uri.as_str().to_owned()))
|
||||
.map(|uri| {
|
||||
(
|
||||
Uuid::from(Ulid::from_datetime_with_source(now.into(), &mut rng)),
|
||||
uri.as_str().to_owned(),
|
||||
)
|
||||
})
|
||||
.unzip();
|
||||
|
||||
sqlx::query!(
|
||||
@ -413,8 +422,11 @@ pub async fn insert_client(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn insert_client_from_config(
|
||||
conn: &mut PgConnection,
|
||||
mut rng: impl Rng + Send,
|
||||
clock: &Clock,
|
||||
client_id: Ulid,
|
||||
client_auth_method: OAuthClientAuthenticationMethod,
|
||||
encrypted_client_secret: Option<&str>,
|
||||
@ -451,9 +463,15 @@ pub async fn insert_client_from_config(
|
||||
.execute(&mut *conn)
|
||||
.await?;
|
||||
|
||||
let now = clock.now();
|
||||
let (ids, redirect_uris): (Vec<Uuid>, Vec<String>) = redirect_uris
|
||||
.iter()
|
||||
.map(|uri| (Uuid::from(Ulid::new()), uri.as_str().to_owned()))
|
||||
.map(|uri| {
|
||||
(
|
||||
Uuid::from(Ulid::from_datetime_with_source(now.into(), &mut rng)),
|
||||
uri.as_str().to_owned(),
|
||||
)
|
||||
})
|
||||
.unzip();
|
||||
|
||||
sqlx::query!(
|
||||
|
@ -442,7 +442,7 @@ pub async fn set_password(
|
||||
password: &str,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let created_at = clock.now();
|
||||
let id = Ulid::from_datetime(created_at.into());
|
||||
let id = Ulid::from_datetime_with_source(created_at.into(), &mut rng);
|
||||
tracing::Span::current().record("user_password.id", tracing::field::display(id));
|
||||
|
||||
let salt = SaltString::generate(&mut rng);
|
||||
|
Reference in New Issue
Block a user