I am using SQL Server always encrypted on feature for SSN column. I have created a stored procedure and calling it from .net code. I am using column encryption setting=true in my connection string. Calling the dynamic stored procedure from the .net code throws this error:
Operand type clash: varchar is incompatible with varchar(4) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'ColumnKey', column_encryption_key_database_name = 'DatabaseName') collation_name = 'SQL_Latin1_General_CP1_CI_AS'
Could someone please provide a sample code which would work to retrieve data with the search on encrypted column using parameterization?
CREATE PROCEDURE [dbo].[testSSN_Dynamic]
#Last4SSN VARCHAR(50)
AS
BEGIN
DECLARE #query NVARCHAR(4000);
SET #query = 'Select [SSNumber], [last4SSNumber] from table_XXX WHERE last4SSNumber = #Last4SSN ;'
EXEC sp_executesql #query, N'#Last4SSN varchar(4)', #Last4SSN ;
END
In the application SSN number is encrypted using Randomized encryption. Last4SSNumber is encrypted using Deterministic encryption. The search is based on last 4 digit of SSN number and the filtered list will get the SSN number only with the last 4 matching digit, rest all the digits are masked in the application. Since both the encryption Randomized and deterministic do not support like operation the column last4SSNumber was added.
When I call the above Stored procedure without the dynamic SQL from .NET code, it works fine and I am able to retrieve the list of matching last 4 digit of SSN..
In the application there are existing stored procedure with quite a few parameters passed to them. The search criteria is based on if the value is passed to the parameter or not. Last4SSNumber is one of the parameter passed. I have provided a simple sample of the stored procedure and not the entire stored procedure with all of the parameters. The search criteria is build, depending on the value passed to the parameter.
In various post it has been pointed out that the Dynamic SQL has to be converted to Parameterized query in order to use the always encrypted on feature. I applied parameterization to the above stored procedure still I receive the error when calling the stored procedure from the .NET code.
Use Dynamic SQL with parameters that evaluate against encrypted columns is currently not supported.
Unfortunately executing the query in the manner below is not supported by Always Encrypted
EXEC sp_executesql #query, N'#Last4SSN varchar(4)', #Last4SSN ;
However, if you are able to restructure your stored procedure in the following manner, you may have a working solution.
CREATE PROCEDURE [dbo].[testSSN]
#Last4SSN VARCHAR(50)
AS
BEGIN
Select [SSNumber], [last4SSNumber] from table_XXX WHERE last4SSNumber = #Last4SSN ;
END
Related
I wanted to 'Call' MariaDB Procedure from Azure Data Factory.
How can this be achieved, are there any other service which can be integrated with ADF to call this MariaDB procedures
I tried calling the procedure by writing the query using lookup activity.
It fails while showing this error.
ErrorCode=InvalidParameter,'Type=Microsoft.DataTransfer.Common.Shared.HybridDeliveryException,Message=The value of the property 'columns' is invalid: 'Value cannot be null.
Parameter name: columns'.,Source=,''Type=System.ArgumentNullException,Message=Value cannot be null.
Parameter name: columns,Source=Microsoft.DataTransfer.Common,'
Lookup activity reads and returns the content of the query. I tried to repro this by creating three stored procedures in Azure SQL database for Maria DB.
First Stored procedure is written to update the data in the table.
DELIMITER $$
CREATE PROCEDURE update_inventory()
BEGIN
UPDATE inventory SET quantity = 150
WHERE id = 1;
END$$
DELIMITER ;
When this procedure is called in ADF lookup activity, error occurs.
Second stored procedure is written with select query.
DELIMITER $$
CREATE PROCEDURE select_inventory()
BEGIN
select * from inventory;
END$$
DELIMITER ;
When this SP is called, ADF pipeline is executed successfully.
In order to execute the stored procedure with update statements (or any statements), a select statement is added in the Stored procedure.
DELIMITER $$
CREATE PROCEDURE update_select_inventory()
BEGIN
UPDATE inventory SET quantity = 150
WHERE id = 1;
select * from inventory;
END$$
DELIMITER ;
When this stored procedure is called through Lookup activity, it got executed successfully.
Try adding select statement in the stored procedure and execute it in Lookup activity. Or add Select statement after Call stored procedure statement.
By selecting the 'query' option, you can call the stored procedure using lookup activity. From your error message, it looks like you are missing the parameter columns while calling the stored procedure.
Did you try executing the same code using the client tools like MySQL workbench? If you can execute the stored proc from other client tools, then you should be able to execute the same using the lookup activity.
I tested from my end and was able to execute the Stored procedure using lookup activity. Please see the below screenshot for your reference.
I'm working with the Microsoft Parallel Data Warehouse appliance and attempting to use flyway to handle table migrations in that environment. The issue I'm running into is that the default script for establishing the schema_version table fails.
Here is the default script as far as I can tell that is being executed upon calling baseline().
CREATE TABLE [dbo].[dbresult_migration] (
[installed_rank] INT NOT NULL,
[version] NVARCHAR(50),
[description] NVARCHAR(200),
[type] NVARCHAR(20) NOT NULL,
[script] NVARCHAR(1000) NOT NULL,
[checksum] INT,
[installed_by] NVARCHAR(100) NOT NULL,
[installed_on] DATETIME NOT NULL DEFAULT GETDATE(),
[execution_time] INT NOT NULL,
[success] BIT NOT NULL
);
ALTER TABLE [dbo].[dbresult_migration] ADD CONSTRAINT [dbresult_migration_pk] PRIMARY KEY ([installed_rank]);
CREATE INDEX [dbresult_migration_s_idx] ON [dbo].[dbresult_migration] ([success]);
Specifically the Microsoft Parallel Data Warehouse (MS PDW or APS as it is now known) doesn't support expressions with default constraints.
Msg 104338, Level 16, State 1, Line 1
An expression cannot be used with a default constraint. Specify only constants for a default constraint.
Which causes an error when GETDATE() is used as the default for the installed_on column.
The ALTER TABLE statement will also fail as PRIMARY KEYs and INDICES are managed differently in the environment.
Is there a way to override the default initialization script for the schema_version?
UPDATE
Further investigation reveals that the next failure occurs when attempting to insert records into the schema_version table. Specifically the current implementation attempts to identify the current user based on a call to dbSupport.getCurrentUserFunction(). For SQL Server this function is SUSER_SNAME(). While this function is available on both the standard SQL Server and the Parallel Data Warehouse the current implementation of the Parallel Data Warehouse does not allow for function calls within the values portion of an insert statement. As such, the following error is returned:
Insert values statement can contain only constant literal values or variable references.
When the query that is attempted is logged as:
INSERT INTO [dbo].[dbresult_migration] ([installed_rank],[version],[description],[type],[script],[checksum],[installed_by],[execution_time],[success]) VALUES (#P0, #P1, #P2, #P3, #P4, #P5, SUSER_SNAME(), #P6, #P7)
UPDATE 2
I now have a fork of flyway-core that correctly identifies if you are connecting to SQL Server vs SQL Server parallel data warehouse. Another issue that I have identified is that SQL Server PDW does not allow DDL within transactions and so an attempt to baseline fails as this appears to be attempted from within a transaction template. Ultimately this is evolving from a question of understanding how to modify an initialization script to a need for support of a new database platform. I've submitted this as a new issue on the flyway repo on github here.
I would like to know how to accomplish this task. I've looked at CASE, DECODE or IF condition and I'm not able to make it work. My goal is to pass a block of predefined column/value pair constructed from ASP.NET data to my Oracle stored procedure. I am trying to only update certain columns out of many to preserve other columns not needing updates. So here's my set up:
Stored procedure:
UpdateSelectedColumns(myValuePairString, updatedBy)
-- Passed variable from ASP.NET, myValuePairString = 'col1 = 10,col2 = 'Dog''
-- update statement final
UPDATE MyTable
SET
col1 = 10,
col2 = 'Dog'
col3 = 'john';
COMMIT;
Thank you in advance...
Ricky
For once I'm gonna advise to not use a stored proc. There is no point here in using a stored procedure.
As it is your stored procedure would blindly accept its arguments and execute the update without adding any value. Furthermore, by using this procedure, you preclude the use of binds and exposes yourself to bugs (whenever you encouner a value with a quote '), performance hit and SQL injection vulnerability.
The advantage of PL/SQL (simple transparent binding, transparent use and reuse of cursors, strict static SQL parsing and metadata dependancy) are all pointless if you take an aribtrary string as argument and put it in a dynamic cursor.
You'll be better off to use your language native cursors and use bind variables.
If you really want to use PL/SQL, replace your single argument with a couple of tables. One for the column names, one for the variable values. You could then use DBMS_SQL to parse the statement and use appropriate bind variables. You'll need some convention to be able to parse date, number and character values. You'll need to read metadata from the database to check the datatypes. This would be a lot of code for not a bit of value.
I am working on an multilingual web application being developed in VS 2010 - ASP.Net (C#).
I can insert it without any problem if I use a simple insert statement without stored procedure for example
Insert INTO Test (E,A) VALUES('Some English Text',N'الرَّحْمَٰنِ الرَّحِيمِاللَّهِ الرَّحْمَٰنِ الرَّحْمَٰنِ الرَّحِيمِاللَّهِ الرَّحْمَٰنِ الرَّحْمَٰنِ الرَّحِيمِاللَّهِ الرَّحْمَٰنِ الرَّحْمَٰنِ الرَّحِيمِاللَّهِ الرَّحْمَٰنِ')
It works fine when I add N for unicode data. My question is how can I add this 'N' in stored procedure so that it can save data without any issues. I tried to put N in different way but stored procedure give syntax error
Below is the example of stored procedure I am using.
ALTER PROCEDURE [dbo].[usp_AddNewPageDetails]
-- Add the parameters for the stored procedure here
#PageNameEnglish varchar(100),
#PageNameArabic nvarchar(300),
#PageTitleEnglish varchar(300),
#PageTitleArabic nvarchar(900),
#PageDescEnglish varchar(400),
#PageDescArabic nvarchar(1200),
#PageKeywordsEnglish varchar(120),
#PageKeywordsArabic nvarchar(400),
#PageBodyEnglish varchar(MAX),
#PageBodyArabic nvarchar(MAX),
#PageLinkPosition int,
AS
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
BEGIN
INSERT INTO pg_Pages(
PageNameEnglish,PageNameArabic,PageTitleEnglish,PageTitleArabic,PageDescEnglish,
PageDescArabic,PageKeywordsEnglish,PageKeywordsArabic,PageBodyEnglish,
PageLinkPosition,PageLayoutPosition,PageBannerImageEnglish,)
VALUES
(#PageNameEnglish,#PageNameArabic,#PageTitleEnglish,#PageTitleArabic,#PageDescEnglish,
#PageDescArabic,#PageKeywordsEnglish,#PageKeywordsArabic,#PageBodyEnglish,)
END
Reply is appreciated.
The N is part of a Unicode string literal, just as the quotes. Probably you tried to add an N with the #parameter name, but this is not necessary (even wrong).
So calling your SP in T-SQL using syntax like
EXEC usp_AddNewPageDetails 'english text', N'arab text', etc.
is sufficient.
If you call the SP from .Net via SqlCommand etc., no additional code is required, as .Net always uses Unicode strings.
Can you confirm the data types of the columns in table pg_Pages are NVARCHAR where appropriate? If the columns are VARCHAR then unicode text will be converted to junk without warning.
I've been preaching both to my colleagues and here on SO about the goodness of using parameters in SQL queries, especially in .NET applications. I've even gone so far as to promise them as giving immunity against SQL injection attacks.
But I'm starting to wonder if this really is true. Are there any known SQL injection attacks that will be successfull against a parameterized query? Can you for example send a string that causes a buffer overflow on the server?
There are of course other considerations to make to ensure that a web application is safe (like sanitizing user input and all that stuff) but now I am thinking of SQL injections. I'm especially interested in attacks against MsSQL 2005 and 2008 since they are my primary databases, but all databases are interesting.
Edit: To clarify what I mean by parameters and parameterized queries. By using parameters I mean using "variables" instead of building the sql query in a string.
So instead of doing this:
SELECT * FROM Table WHERE Name = 'a name'
We do this:
SELECT * FROM Table WHERE Name = #Name
and then set the value of the #Name parameter on the query / command object.
Placeholders are enough to prevent injections. You might still be open to buffer overflows, but that is a completely different flavor of attack from an SQL injection (the attack vector would not be SQL syntax but binary). Since the parameters passed will all be escaped properly, there isn't any way for an attacker to pass data that will be treated like "live" SQL.
You can't use functions inside placeholders, and you can't use placeholders as column or table names, because they are escaped and quoted as string literals.
However, if you use parameters as part of a string concatenation inside your dynamic query, you are still vulnerable to injection, because your strings will not be escaped but will be literal. Using other types for parameters (such as integer) is safe.
That said, if you're using use input to set the value of something like security_level, then someone could just make themselves administrators in your system and have a free-for-all. But that's just basic input validation, and has nothing to do with SQL injection.
No, there is still risk of SQL injection any time you interpolate unvalidated data into an SQL query.
Query parameters help to avoid this risk by separating literal values from the SQL syntax.
'SELECT * FROM mytable WHERE colname = ?'
That's fine, but there are other purposes of interpolating data into a dynamic SQL query that cannot use query parameters, because it's not an SQL value but instead a table name, column name, expression, or some other syntax.
'SELECT * FROM ' + #tablename + ' WHERE colname IN (' + #comma_list + ')'
' ORDER BY ' + #colname'
It doesn't matter whether you're using stored procedures or executing dynamic SQL queries directly from application code. The risk is still there.
The remedy in these cases is to employ FIEO as needed:
Filter Input: validate that the data look like legitimate integers, table names, column names, etc. before you interpolate them.
Escape Output: in this case "output" means putting data into a SQL query. We use functions to transform variables used as string literals in an SQL expression, so that quote marks and other special characters inside the string are escaped. We should also use functions to transform variables that would be used as table names, column names, etc. As for other syntax, like writing whole SQL expressions dynamically, that's a more complex problem.
There seems to be some confusion in this thread about the definition of a "parameterised query".
SQL such as a stored proc that accepts parameters.
SQL that is called using the DBMS Parameters collection.
Given the former definition, many of the links show working attacks.
But the "normal" definition is the latter one. Given that definition, I don't know of any SQL injection attack that will work. That doesn't mean that there isn't one, but I have yet to see it.
From the comments, I'm not expressing myself clearly enough, so here's an example that will hopefully be clearer:
This approach is open to SQL injection
exec dbo.MyStoredProc 'DodgyText'
This approach isn't open to SQL injection
using (SqlCommand cmd = new SqlCommand("dbo.MyStoredProc", testConnection))
{
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter newParam = new SqlParameter(paramName, SqlDbType.Varchar);
newParam.Value = "DodgyText";
.....
cmd.Parameters.Add(newParam);
.....
cmd.ExecuteNonQuery();
}
any sql parameter of string type (varchar, nvarchar, etc) that is used to construct a dynamic query is still vulnerable
otherwise the parameter type conversion (e.g. to int, decimal, date, etc.) should eliminate any attempt to inject sql via the parameter
EDIT: an example, where parameter #p1 is intended to be a table name
create procedure dbo.uspBeAfraidBeVeryAfraid ( #p1 varchar(64) )
AS
SET NOCOUNT ON
declare #sql varchar(512)
set #sql = 'select * from ' + #p1
exec(#sql)
GO
If #p1 is selected from a drop-down list it is a potential sql-injection attack vector;
If #p1 is formulated programmatically w/out the ability of the user to intervene then it is not a potential sql-injection attack vector
A buffer overflow is not SQL injection.
Parametrized queries guarantee you are safe against SQL injection. They don't guarantee there aren't possible exploits in the form of bugs in your SQL server, but nothing will guarantee that.
Your data is not safe if you use dynamic sql in any way shape or form because the permissions must be at the table level. Yes you have limited the type and amount of injection attack from that particular query, but not limited the access a user can get if he or she finds a way into the system and you are completely vunerable to internal users accessing what they shouldn't in order to commit fraud or steal personal information to sell. Dynamic SQL of any type is a dangerous practice. If you use non-dynamic stored procs, you can set permissions at the procesdure level and no user can do anything except what is defined by the procs (except system admins of course).
It is possible for a stored proc to be vulnerable to special types of SQL injection via overflow/truncation, see: Injection Enabled by Data Truncation here:
http://msdn.microsoft.com/en-us/library/ms161953.aspx
Just remember that with parameters you can easily store the string, or say username if you don't have any policies, "); drop table users; --"
This in itself won't cause any harm, but you better know where and how that date is used further on in your application (e.g. stored in a cookie, retrieved later on to do other stuff.
You can run dynamic sql as example
DECLARE #SQL NVARCHAR(4000);
DECLARE #ParameterDefinition NVARCHAR(4000);
SELECT #ParameterDefinition = '#date varchar(10)'
SET #SQL='Select CAST(#date AS DATETIME) Date'
EXEC sp_executeSQL #SQL,#ParameterDefinition,#date='04/15/2011'