My understanding is that both parameterized queries and stored procedures help to prevent sql injection.
Do parameterized queries make it impossible to inject sql?
Do parameterized queries with very bad stored procedures make it impossible to inject sql?
Are there examples of either of the above? thanks
Yes, parameterized queries and stored procedures do help prevent SQL injection.
But saying the they make it impossible is a bit of a stretch. Injection can certainly be thwarted by using parameters AND consideration when writing queries.
But _very bad_ queries or stored procedures can still be subject to injection.
An example would be using dynamic SQL queries in your stored procedure or query:
CREATE STORED PROCEDURE [BadStoredProcedure]
(#columnList varchar(MAX))
AS
BEGIN
DECLARE #sqlCommand varchar(1000)
SET #sqlCommand = 'SELECT ' + #columnList + ' FROM Customers'
EXEC (#sqlCommand)
END
Guess what happens if *; TRUNCATE TABLE Customers; SELECT * is passed into #columnList
Related
I am working on a SSIS package which checks the performance of stored procedures using extended events. We have an execute SQL task having a SQL query which is determined at run time as the arguments for those (Read) stored procedures are already hard coded and stored in a table.
Now, I need to run (write) stored procedures calls as well for which I can not hard code the arguments as they are (dynamically generated) dependent on output set of the previous stored procedures. Arguments and result set are not identical for each stored procedure and so the difficulty to use a single execute SQL task.
I thought of creating separate execute SQL task for each (write) stored procedure and add them to sequence container but that doesn't seem like a practical approach.
Can somebody suggest any approach to this problem?
I'd like to know the best way to retrieve the schema for a query's result WITHOUT executing the query. By Schema I want to know the name of the fields that will be returned and if they are boolean, literal or float, ...
For those familiar with SQL Server I want the same kind of behavior than using a FMTONLY.
At the moment my best approach is to perform a LIMIT 0 ... but anyway I'm nowhere to know the type of the returned fields.
What you are seeking is not generally possible.
Unlike SQL, neo4j is "schemaless", and the "schema" of a query result is generally dependent on the data in the DB. This means that, generally, a query's result schema cannot be known without actually executing the query.
I am using Esper 5.0 and need to perform a query on data from a relational database. This is in my case a MySQL database connected via JDBC. Now I would like to formulate an EPL query on the data from the database. Hence, my query is similar to this one:
String parameter = "any"; // untrusted (!) parameter from some user input
String mySqlQuery = "SELECT `sth` FROM `mytable` WHERE `att` = " + parameter;
String query = "select sth from sql:myDB ['" + mySqlQuery + "']"
Now how can I sanitize the untrusted parameter which is then send to my MySQL database? The Esper documentation says that the query is basically passed to the database software unchanged. So what can I do? I came up with four ideas:
Using EPL substitution parameters: Does not work, because it is not supported by Esper in SQL expressions.
Using EPL variables: It should be possible to define a variable via something like epService.getEPAdministrator().getConfiguration().addVariable("parameter", String.class, parameter);, then use the syntax "SELECT `sth` FROM `mytable` WHERE `att` = ${parameter}" for the MySQL query. Esper should replace the variable with the respective value. It is not nice to define a global variable for it, although one could again remove it with epService.getEPAdministrator().getConfiguration().removeVariable("parameter", true); afterwards. But much more important: That also does not sanitize the untrusted parameter and does not make it safe to pass it to the database, right?
Sanitizing the parameters on the Java side: Queries on the Java side should be done via PreparedStatement. Since it is technically impossible to get a MySQL query string out of a PreparedStatement, this is not an option. I do not think that there is another safe way to sanitize a parameter passed to a database on the Java side.
Defining all the constraints on the EPL side: One could probably just do a SELECT * FROM `mytable` without defining any constraints in order to select everything from the MySQL database and then define the constraints via EPL and use a EPPreparedStatement for it. Is this the proper way to go? I fear that this is not really performant, because a lot of entries are read from the MySQL database which are not needed.
Any ideas?
Would it work with the statement object model API? That API gives you complete control over all parts of EPL.
I thought I would use a stored routine to clean up some of my more complex SQL statements. From what I've read, it seems impossible to use a stored procedure within an sql statement, and a stored function only returns a single value when what I need is a result set. I am using mySQL v5.0
SELECT p.`id`, gi.`id`
FROM `sport`.`players` AS p JOIN `sport`.`gameinstances` AS gi
ON p.`id` = gi.`playerid`
WHERE (p.`playerid` IN (CALL findPlayers`("Canada", "2002")))
AND (gi.`instanceid` NOT IN (CALL findGameInstances`("Canada", "2002")));
For example, the procedures 'findPlayers' and 'findGameInstances' are are stored routines that execute some SQL and return a result set. I would prefer not to include their code directly within the statement above.
I don't know if mysql can use any of these techniques, but in SQl server I would try one of two different things (at least it might give you something to look for in th emysql documentation):
First a table values used defined function then join to that
Second, insert the results set of the sp into a temp table then join to the tem table
You could also consider putting the complicated logic in a view and then just adding the where clause after joining to the view. This won't work if your stored proc does dynamic things a view can't do, but it is a possibilty.
Let's say I have 'myStoredProcedure' that takes in an Id as a parameter, and returns a table of information.
Is it possible to write a SQL statement similar to this?
SELECT
MyColumn
FROM
Table-ify('myStoredProcedure ' + #MyId) AS [MyTable]
I get the feeling that it's not, but it would be very beneficial in a scenario I have with legacy code & linked server tables
Thanks!
You can use a table value function in this way.
Here is a few tricks...
No it is not - at least not in any official or documented way - unless you change your stored procedure to a TVF.
But however there are ways (read) hacks to do it. All of them basically involved a linked server and using OpenQuery - for example seehere. Do however note that it is quite fragile as you need to hardcode the name of the server - so it can be problematic if you have multiple sql server instances with different name.
Here is a pretty good summary of the ways of sharing data between stored procedures http://www.sommarskog.se/share_data.html.
Basically it depends what you want to do. The most common ways are creating the temporary table prior to calling the stored procedure and having it fill it, or having one permanent table that the stored procedure dumps the data into which also contains the process id.
Table Valued functions have been mentioned, but there are a number of restrictions when you create a function as opposed to a stored procedure, so they may or may not be right for you. The link provides a good guide to what is available.
SQL Server 2005 and SQL Server 2008 change the options a bit. SQL Server 2005+ make working with XML much easier. So XML can be passed as an output variable and pretty easily "shredded" into a table using the XML functions nodes and value. I believe SQL 2008 allows table variables to be passed into stored procedures (although read only). Since you cited SQL 2000 the 2005+ enhancements don't apply to you, but I mentioned them for completeness.
Most likely you'll go with a table valued function, or creating the temporary table prior to calling the stored procedure and then having it populate that.
While working on the project, I used the following to insert the results of xp_readerrorlog (afaik, returns a table) into a temporary table created ahead of time.
INSERT INTO [tempdb].[dbo].[ErrorLogsTMP]
EXEC master.dbo.xp_readerrorlog
From the temporary table, select the columns you want.