-
I've came upon a comment above Execute implementation for
I'm glad this is noted somewhere, as I would scratch my head on where's String implementation of Execute, but... it says nothing about the reasoning. Ok - we have writer slightly more involved when they have to put Also, I would reword this comment a bit to include said explanation. PS: I've looked through other issues/discussions, found nothing on this topic, but that may be me not being able to specify search criteria |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
This. If async fn insert_student(conn: &mut PgConnection, student_name: &str) -> sqlx::Result<StudentId> {
sqlx::query_scalar(format!("INSERT INTO students(name) VALUES('{}') RETURNING student_id", student_name))
.fetch_one(conn)
.await
}
// imagine this is user input, and wasn't properly sanitized
let student_name = "Robert'); DROP TABLE students; --";
let student_id = insert_student(&mut conn, &student_name).await?; Then suddenly, you've lost all student data for the year because the query that got executed looked like this: INSERT INTO students(name) VALUES('Robert'); DROP TABLE students; -- ') RETURNING student_id (Postgres would reject the attempt to prepare a query string with more than one statement, but MySQL and SQLite wouldn't.) The idea is that by requiring dereffing to a string slice, it will at least make the code start to smell a bit and hopefully lead to the user re-evaluating their implementation. Bind parameters don't have this vulnerability because the database knows not to interpret anything in a bind parameter as SQL; by comparison, this implementation is completely injection-safe, and is the approach that the API design was intended to push you towards: async fn insert_student(conn: &mut PgConnection, student_name: &str) -> sqlx::Result<StudentId> {
sqlx::query_scalar("INSERT INTO students(name) VALUES(?) RETURNING student_id")
.bind(student_name)
.fetch_one(conn)
.await
} I've recently spent some more time thinking about this API, because yeah the intent here is not clear at all, and always requiring a string slice makes it annoying to construct query builders. I was thinking of adopting a similar strategy to std's But I'll talk about that more in a proposal issue which I've been putting off writing. |
Beta Was this translation helpful? Give feedback.
This. If
String
was possible to use directly, it would be extremely tempting to just format user input directly into the query instead of using bind parameters, which introduces SQL injection vulnerabilities. For example, to co-opt XKCD #327: