Wt::Dbo::Session date query format.
Added by Aleksander Fular over 10 years ago
Hello,
I've been trying to wrap the call to "find" method on the Wt::Dbo::Session object, with my own non-templated one so I can test it freely.
So instead of using standards approach and that is:
dbSession_.find<db::models::BlogPost>("where date >= ? "
"and date < ? "
"and (state = ? or author_id = ?) "
"and title_as_url = ?").bind(Wt::WDateTime(pathParser.getLowerTimeConstraint())).bind(
Wt::WDateTime(pathParser.getUpperTimeConstraint())).bind(db::models::BlogPost::kPublished).bind(
dbSession_.getLoggedInUserId()).bind(pathParser.getTitle());
I would like to use it like this:
dbSession_.fetchPosts(
Wt::WString("where date >= {1} "
"and date < {2} "
"and (state = {3} or author_id = {4}) "
"and title_as_url = {5}").arg(Wt::WDateTime(pathParser.getLowerTimeConstraint()).toString("yyyy-MM-dd")).arg(
Wt::WDateTime(pathParser.getUpperTimeConstraint()).toString("yyyy-MM-dd")).arg(db::models::BlogPost::kPublished).arg(
dbSession_.getLoggedInUserId()).arg(pathParser.getTitle()));
This way i can have one virtual function getting const Wt:WString& as parameter, and freely mock it in the tests.
Posts DbSessionImp::fetchPosts(const Wt::WString& condition) {
return find<models::BlogPost>(condition.toUTF8());
}
However it seems that I cannot get the format of the date right i get:
"Wt: fatal error: Sqlite3: select ""id"", ""version"", ""state"", ""date"", ""title"", ""title_as_url"", ""brief_src"", ""brief_html"", ""body_src"", ""body_html"", ""author_id"" from ""blog_posts"" where date >= 2014-10-14-00:00:00 and date < 2014-10-15-00:00:00 and (state = 0 or author_id = -1) and title_as_url = blogpost2: near "":00"": syntax error"
Could you point me to the correct format of WDateTime as String passed to query? I tried to search in the code but with no success.
Thanks
Replies (4)
RE: Wt::Dbo::Session date query format. - Added by Aleksander Fular over 10 years ago
It turned out that all I was missing was quotation around the arguments:
posts = dbSession.fetchPosts(
Wt::WString("where date >= \"{1}\" "
"and date < \"{2}\" "
"and (state = \"{3}\" or author_id = \"{4}\") "
"and title_as_url = \"{5}\" ").arg(Wt::WDateTime(pathParser.getLowerTimeConstraint()).toString("yyyy-MM-dd hh:mm:ss")).arg(
Wt::WDateTime(pathParser.getUpperTimeConstraint()).toString("yyyy-MM-dd hh:mm:ss")).arg(db::models::BlogPost::kPublished).arg(
dbSession.getLoggedInUserId()).arg(pathParser.getTitle()));
RE: Wt::Dbo::Session date query format. - Added by Koen Deforche over 10 years ago
Hey,
Careful though as this is an SQL Injection attack vector.
Koen
RE: Wt::Dbo::Session date query format. - Added by Aleksander Fular over 10 years ago
Hey Koen,
Internally it just invokes find method:
Posts DbSessionImp::fetchPosts(const Wt::WString& condition) {
return find<models::BlogPost>(condition.toUTF8());
}
Is there a slot for sql injection then?
Or find method from dbsession protects before that?
RE: Wt::Dbo::Session date query format. - Added by Koen Deforche over 10 years ago
Yes, this is vulnerable.
As soon as you use string concatenation to mix SQL with strings (which may be under control of the user), then you have a SQL Injection attack vector.
The bind() functions allow you to separate data from the SQL query itself.
Koen