Why I don't like: Find the Flaw
After done almost all "Find the Flaw" labs I'm trying to give a feedback about this mode.
On one hand it's quite handy and nice, to see and define flaws and link them to the corresponding CWE. But sometimes it takes time... very long time (for 20 pts!).
Here's an example, I want to share which I'm struggling with and which does not makes sense for me - and there are many FtF labs like this which are forcing me to do try and error.
Let's take "Find the Flaw: Rust β Identification and Authentication Failures".
You'll have a code like (for brevity I've shortend it a little bit):
...
#[derive(Deserialize)]
struct PasswordForm {
token: String,
password: String,
}
#[derive(Deserialize)]
struct UserIdQuery {
user_id: String,
}
async fn reset_password(
Query(user_id_query): Query<UserIdQuery>,
pool: axum::extract::Extension<SqlitePool>,
Form(form): Form<PasswordForm>,
) -> Html<String> {
let user_id = user_id_query.user_id;
let token = form.token;
let password = form.password;
if password.len() < 8 || !password.chars().any(|c| c.is_lowercase()) {
return Html("Password must be at least 8 characters long and contain at least one lowercase letter.".to_string());
}
let hashed_password = sha256(password.as_bytes());
let hashed_password_hex = hex::encode(hashed_password);
let pool = pool.0;
let result = query("SELECT user_id FROM password_resets WHERE token = ?").bind(token)
.fetch_optional(&pool)
.await;
match result {
Ok(Some(_)) => {
let update_result = query(
"UPDATE users SET password = ? WHERE id = ?")
.bind(hashed_password_hex)
.bind(user_id)
.execute(&pool)
.await;
...
}
pub async fn main() -> Result<(), std::io::Error> {
...
.route("/reset_password", post(reset_password))
...
so, on the first glimpse you'll notice:
let result = query("SELECT user_id FROM password_resets WHERE token = ?").bind(token)
.fetch_optional(&pool)
.await;
and you think: cool, as long as I have a valid token I can reset ANY password, because the UserIdQuery holds the user_id from the query parameters. That must be the error.
And it's clearly CWE-640 - Weak Password Recovery Mechanism for Forgotten Password.
Boom! But lab says: "Correct Vulnerability but Incorrect Line"
Then you say, ok.. something might be missing... or too much. you'll remove lines, 3... 2.. 1.. nothing.
maybe I need to add the update password procedure?
so let's click the lines on:
let result = query("SELECT user_id FROM password_resets WHERE token = ?")
.bind(token)
.fetch_optional(&pool)
.await;
and... ? "Correct Vulnerability but Incorrect Line"
now you start clicking on 1 up to 7 lines in all different combinations (no .await, but .bind) but:
"Correct Vulnerability but Incorrect Line"
You add another part of the code, which could make sense like:
let user_id = user_id_query.user_id;
let token = form.token;
let password = form.password;
Again here you start shuffling all the options (now you click between 1 up to 10 lines in all different variations) but all you get is this "Correct Vulnerability but Incorrect Line".
You read again the hint you've got with the wrong answer: "Consider how the password is being reset". Yes I did, really! All the time!
and so on and so on... probably I've clicked now hundreds of different combinations and so on and I start believing there's a bug in the lab (would not be the first one on this collection).
So, how is it for you those "Find the flaw" labs? You like them? You struggle with them?
greetings
-steven
ps: If you have the solution or any other hint for this one, ping me :)