Prepared statements are good to prevent sql injection when the user supplies data and we use that data for db insertion or just even to structure the query. But is really any benefit to PDO when I'm retrieving previously-inserted user-supplied data from the database?
It sounds to me like the answer is no. It's already in. As long as the query itself that retrieves it isn't tarnished by user-supplied parameters (e.g. select * from table is not tarnished by user-supplied data), it's ok to use anything even not PDO, even if the data itself being retrieved was at one point in the past user-supplied data. Any input on this?
My guess is that once people start using PDO in their code, it becomes a matter of uniformity to keep using it for all pieces of their code and never go back to normal mysql (even if something is slightly harder with PDO).
consistency is a benefit. in fact, it's the main (theoretical) benefit of using PDO. preventing injection through bound parameters is orthogonal to PDO.
Related
I would like to know which one is a better approach in-terms of performance and security. I'm using MySql DB and the values are of type varchar.
Should I directly concatenate the values to form a query string and execute the query? (or)
Should I use parameterized queries?
Thanks in advance
You should care about data security and then performance, If you concatenate query parameters your security is risked and also this may break your query statement; this is not a better way.
So, you should parameterise your query instead of concatenation for security measure, this takes very few time to process query string.
I think security is really the only major issue here. If you don't build your dynamic query using a statement, then you leave open the possibility for SQL injection, especially if some of the inputs into the query have unsterilized data coming from the outside world. If you do use statements, then you greatly minimize the chance of this to happen.
Regarding performance, there would be some overhead in building and executing a statement, but I would wager that the penalty for using a statement over a raw string is fairly small. The bigger issue for your performance would probably be the query itself, and how you have tuned your schema.
So, my vote is for using the statement, under the assumption that performance is a minor factor to consider here.
Using parameterized query is most recommended solution. It will prevent the threat of SQL injection as well as it provides you the flexibility of updating the query as and when required without any exposure of your query.
you can use the constant query as part of basic development but when the production code is concerned one should use parameterized query and should try to use prepared statements than normal string Statements. Using prepared Statement in Java JDBC add both performance and Security benefits.
My situation:
MySQL 5.5, but possible to migrate to 5.7
Legacy app is executing single MySQL query to get some data (1-10 rows, 20 columns)
Query can be modified via application configuration
Query is very complex SELECT with multiple JOINS and conditions, it's about 20KB of code
Query is well profiled, index usage fine-tuned, I spent much time on this and se no room for improvement without splitting to smaller queries
With traditional app I would split this large query to several smaller and use caching to avoid many JOINS, but my legacy app does not allow to do that. I can use only one query to return results
My plan to improve performance is:
Reduce parsing time. Parsing 20KB of SQL on every request, while only parameters values are changed seems ineffective
I'd like to turn this query into prepared statement and only fill placeholders with data
Query will be parsed once and executed multiple times, should be much faster
Problems/questions:
First of all: does above solution make sense?
MySQL prepared statements seem to be session related. I can't use that since I cannot execute any additional code ("init code") to create statements for each session
Other solution I see is to use prepared statement generated inside procedure or function. But examples I saw rely on dynamically generating queries using CONCAT() and making prepared statement executed locally inside of procedure. It seems that this kind of statements will be prepared every procedure call, so it will not save any processing time
Is there any way to declare server-wide and not session related prepared statement in MySQL? So they will survive application restart and server restart?
If not, is it possible to cache prepared statements declared in functions/procedures?
I think the following will achieve your goal...
Put the monster in a Stored Routine.
Arrange to always execute that Stored Routine from the same connection. (This may involve restructuring your client and/or inserting a "web service" in the middle.)
The logic here is that Stored Routines are compiled once per connection. I don't know whether that includes caching the "prepare". Nor do I know whether you should leave the query naked, or artificially prepare & execute.
Suggest you try some timings, plus try some profiling. The latter may give you clues into what I am uncertain about.
It is obvious that executing database query in loops has performance issues. but if the query is used as prepared statement, does it make any difference?
What is preferable joining together the tables and get the results or using prepared statement in loop?
Using join would almost always be preferred instead of looping over a result set to get additional results.
Relational Database Management Systems are built for combining related results, and does so very efficiently... additionally, this will you save many round trips to the database, which can become costly if used excessively - regardless of if you're using prepared statements or not.
The overhead to the prepared statements is probably not going to be the escaping of the inputs, it's going to be the connection to the database, or reconnection, or act of sending of the finalized sql statement. That interface between your code and the relational database is likely to be the slow point of the process more than anything else.
However, for my part, I would generally go for whatever is simplest and most able to be maintained from the start, and only worry about performance if the performance actually shows itself to be slow. Write the data-grabbing functionality in a separate function or method so that the implementation can change if the performance proves to need optimization, though.
At that point you can then start optimizing your sql, and use joins or unions as alternatives to multiple prepared statements.
The only reliable MySQL support I know of is through node-mysql and it specifically says in the documentation:
Warning: sql statements with multiple queries separated by semicolons are not supported yet.
Which kind of sucks... Because I need to insert or update a large number of rows at a time with some logic involved, and it's easily done with one large MySQL query containing IFs and ELSEs. I can't imagine how I'd simply move all the logic over to the node.js side without an enormous loss of performance and complexity in code. So I'm not ready to give up on the pure SQL solution.
Is there any way for me to execute a large SQL query from node.js relatively easily?
Can you define your logic within a stored procedure and then call that as your single statement instead (passing whatever parameters you need)?
I am doing a mysql injection on a site (for educational purpose i promise hehe), now, It uses mysql as its database, I cannot do: "; UPDATE..." so my question is, if i do: "OR id=(update...)".. as a subquery, that of course doesn't make any sense yet will it execute the update on the table i choose?
Your success or failure will depend on a number of factors. The first major hurdle you face is whether or not you "friend" was smart enough to use PHP for his database inputs and use the line mysql_real_escape_string which will prevent you from sending any commands through his textboxes and/or other input areas.
http://php.net/manual/en/function.mysql-real-escape-string.php
Your second major hurdle after determining that mysql_real_escape_string has not been used is to determine the true name of the table you want to update. I personally never expose my true database names to the web, I use pseudo names which represent the true names.
If you have succeeded this far you should be able to manipulate the MYSQL server in any way you see fit.
Check out this link for more helpful tips. I have never utilized any of these techniques in a manner other than testing my own MYSQL servers for vulnerabilities.
http://old.justinshattuck.com/2007/01/18/mysql-injection-cheat-sheet/