1
0
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:
Quentin Gliech
2022-10-21 18:58:52 +02:00
parent 559181c2c3
commit f1aa42fae4
5 changed files with 34 additions and 7 deletions

View File

@ -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 = [

View File

@ -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(),

View File

@ -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,

View File

@ -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!(

View File

@ -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);