SQL Server search in nvarchar & ntext - search

I'm using SQL Server 2008 as my database engine in a VS2010, C# ASP.NET web app. My project is Farsi (Persian) so I've used nvarchar and ntext as my data types.
I use following query to find rows from my database but nothing is returned, while I have a row with the specified keyword. Of course my keyword is in Persian (unicode).
What is going wrong here? Is it because of using Farsi language? How can I search in nvarchar and ntext columns containing unicode characters?
myCommand = new SqlCommand("select * from tblArticle where name LIKE '%" + txtSearch.Text + "%'", SQLConnection);

You should use the N' prefix to indicate that you're searching for a Unicode string:
SELECT * FROM dbo.tblArticle WHERE name LIKE N'%......%'
Otherwise, you're converting your search string back to non-Unicode and then searching....

You must use COLLATE Latin1_General_BIN2 to get results. Works for Amharic for Ethiopians.
Select * From YourTableName where ColNameYouSearch LIKE N'%YourSerchCriteria%' COLLATE Latin1_General_BIN2"

I am not familiar with C# ASP.NET, but using nvarchar or ntext shouldn't make any difference in query type. I am wandering you are only assigning your query command to a variable and not executing it..
should you do something like myCommand.execute() ?

Related

Genexus - How to Write String Literals?

We have procedures that initialize our database triggers/functions, so they have the SQL commands inserted on varchar variables as strings in plain code, like the following example:
My questions is:
Is there any way in Genexus to write multiline strings? like c# literal strings using #, or with the recent java 13 text blocks using triple double quotes """ multilineText """
GeneXus currently has no support for multiline.
You are doing it the correct way, based on the code you shared.
You can add a string to a SQL sentence (like this: |) and then do a replace before executing the SQL.
&NewLine = NewLine()
&SQL = &SQL.Replace('|',&newLine())
Or using a regular expression.

(Oracle) LIKE Clause not Working with Numeric Bind Variables

I'm having problems getting Oracle's LIKE clause working with numeric bind variables.
In the examples below the TABLEID column is numeric.
In SQLDeveloper I can write SELECT * FROM TABLEX WHERE TABLEID LIKE ('201%'); which works fine. However, when I try the same query in code using a bind variable: SELECT * FROM TABLEX WHERE TABLEID LIKE :bindVar
I get an ORA-01722: invalid number error.
I've tried surrounding the bind var with () and have tried adding the % symbol to the end of the bind value with no luck.
I'm using NodeJS to make the database calls.
Any ideas as to what I might be doing wrong here?
Datatypes should match.
If TABLEID column's datatype is NUMBER and you're comparing it to a string ( (in like '201%', '201%' is a string), then you'd apply TO_CHAR function to that column:
select * from tablex
where to_char(tableid) like :bindVar
So as it turns out the problem ended up being not with my code but the data within the table itself. Sorry to waste yall's time!

Extract a JSON property with an asterisk in the property name using get_json_object() in SparkSql

I have a table in Databricks that has a column (called "properties") which contains JSON data. I've successfully used get_json_object() in a SparkSql notebook to retrieve properties from it like so:
%sql
select distinct_id, get_json_object(properties, "$.time")
from my_table
This works well. However, there are sub-properties in the properties column that have asterisks in their names, e.g. *Plan. Accessing these properties in the standard way, e.g. $.*Plan doesn't work, since * has special meaning for get_json_object(). I've tried accessing these properties using escape chars, like so:
%sql
select distinct_id, get_json_object(properties, "$.\*Plan")
from my_table
... along with alternative escapes, but to no avail. Is there a way to extract JSON sub-properties that can escape the asterisk?
Thanks!
You can use LATERAL VIEW and json_tuple as a workaround. It's not so fussy about special characters eg:
SELECT x.*
FROM my_table
LATERAL VIEW json_tuple( properties, '*Plan' ) x
Or if you are wedded to using get_json_object you can clean up the string beforehand (although you have somewhat defeated the point of using JSON):
%sql
select
distinct_id,
get_json_object(replace(properties, '*', ''), '$.Plan' ) z
from my_table
I couldn't personally get any escaping methods to work ( eg \u0042 or \ ) but happy to be corrected.
Ideally, don't put such strange characters in your JSON in the first place.

SSIS: Filtering Multiple GUIDs from String Variable as Parameter In Data Flow OLE Source

I have an SSIS package that obtains a list of new GUIDs from a SQL table. I then shred the GUIDs into a string variable so that I have them separated out by comma. An example of how they appear in the variable is:
'5f661168-aed2-4659-86ba-fd864ca341bc','f5ba6d28-7283-4bed-9f11-e8f6bef225c5'
The problem is in the data flow task. I use the variable as a parameter in a SQL query to get my source data and I cannot get my results. When the WHERE clause looks like:
WHERE [GUID] IN (?)
I get an invalid character error so I found out the implicit conversion doesn't work with the GUIDs like I thought they would. I could resolve this by putting {} around the GUID if this were a single GUID but there are a potential 4 or 5 different GUIDs this will need to retrieve at runtime.
Figuring I could get around it with this:
WHERE CAST([GUID] AS VARCHAR(50)) IN (?)
But this simply produces no results and there should be two in my current test.
I figure there must be a way to accomplish this... What am I missing?
You can't, at least not using the mechanics you have provided.
You cannot concatenate values and make that work with a parameter.
I'm open to being proven wrong on this point but I'll be damned if I can make it work.
How can I make it work?
The trick is to just go old school and make your query via string building/concatenation.
In my package, I defined two variables, filter and query. filter will be the concatenation you are already performing.
query will be an expression (right click, properties: set EvaluateAsExpression to True, Expression would be something like "SELECT * FROM dbo.RefData R WHERE R.refkey IN (" + #[User::filter] + ")"
In your data flow, then change your source to SQL Command from variable. No mapping required there.
Basic look and feel would be like
OLE Source query

Can I be vulnerable to SQL injection by appending input with no whitespace to my query?

I am taking in a string from user input, and splitting it on whitespace (using \w) into an array of strings. I then loop through the array, and append a part of the where clause like this:
query += " AND ( "
+ "field1 LIKE '%" + searchStrings[i] +"%' "
+ " OR field2 LIKE '%" + searchStrings[i] +"%' "
+ " OR field3 LIKE '%" + searchStrings[i] +"%' "
+ ") ";
I feel like this is dangerous, since I am appending user input to my query. However, I know that there isn't any whitespace in any of the search strings, since I split the initial input on whitespace.
Is it possible to attack this via a SQL injection? Giving Robert');DROP TABLE students;-- wouldn't actually drop anything, since there needs to be whitespace in there. In that example, it would not behave properly, but no damage would be done.
Can anyone with more experience fighting SQL injections help me either fix this, or put my mind at ease?
Thanks!
EDIT:
Wow, that is a lot of great input. Thank you everyone who responded. I will investigate full-text search and, at a minimum, parameterize my query.
Just so I can better understand the problem, would it be possible to inject if all whitespace AND single quotes were escaped?
Any time you allow a user to enter data into a query string like this you are vulnerable to SQL injection and it should be avoided like the plague!
You should be very careful how you allow your searchStrings[] array to be populated. You should always append variable data to your query using parameter objects:
+ field1 like #PropertyVal Or field2 like #PropertyVal Or field3 like #PropertyVal etc...
And if you're using SQL Server for example
Query.Parameters.Add(new SqlParameter("PropertyVal", '%' + searchStrings[i] + '%'));
Be very wary how you build a query string that you're going to run against a production server, especially if it has any data of consequence in it!
In your example you mentioned Little Bobby Tables
Robert');DROP TABLE students;--
And cited that because it needs white space, you couldn't do it - but if the malicious user encoded it using something like this:
Robert');Exec(Replace('Drop_Table_students','_',Char(32)));--
I would say - better to be safe and do it the right way. There's no simple way to make sure you catch every scenario otherwise...
Yes, this script did not contain any whitespaces, just encoded characters that SQL decoded back and executed:
http://www.f-secure.com/weblog/archives/00001427.html
The injected script was something like this:
DECLARE%20#S%20NVARCHAR(4000);SET%20#S=CAST(0x440045004300
4C00410052004500200040005400200076006100720063006800610072
00280032003500350029002C0040004300200076006100720063006800
610072002800320035003500290020004400450043004C004100520045
0020005400610062006C0065005F0043007500720073006F0072002000
43005500520053004F005200200046004F0052002000730065006C0065
0063007400200061002E006E0061006D0065002C0062002E006E006100
6D0065002000660072006F006D0020007300790073006F0062006A0065
00630074007300200061002C0073007900730063006F006C0075006D00
6E00730020006200200077006800650072006500200061002E00690064
003D0062002E0069006400200061006E006400200061002E0078007400
7900700065003D00270075002700200061006E0064002000280062002E
00780074007900700065003D003900390020006F007200200062002E00
780074007900700065003D003300350020006…
Wich SQL decoded to :
DECLARE #T varchar(255)'#C
varchar(255) DECLARE Table_Cursor
CURSOR FOR select a.name'b.name from
sysobjects a'syscolumns b where
a.id=b.id and a.xtype='u' and
(b.xtype=99 or b.xtype=35 or b…
and so on, so its possible to do whatever you want with every table in the database without using any whitespaces.
There are just too many ways to get this wrong, that I wouldn't rely if anyone told me "no, this will be safe, because ..."
What about escaping the whitespace in some form (URL-Encode or somethign). What about using non-obvious Unicode whitespace characters that your simple tests don't check for. What if your DB supports some malicious operations that don't require a white space?
Do the correct way: Use a PreparedStatement (or whatever your platform uses for injection-safe parameterization), append and prepend the "%" to the user input and use that as a parameter.
The rule of thumb is: If the string you're appending isn't SQL, it must be escaped using prepared statements or the correct 'escape' function from your DB client library.
I totally agree that query parameters are the absolutely safest way to go. With them you have no risk of SQL injection whatsover (unless you do something stupid with the parameters) and there is no overhead of escaping.
If your DBMS does not support query parameters, then it MUST support string escaping. In the worst case you can try to escape single-quotes yourself, although there still is a Unicode exploit that can circumvent this. However, if your DBMS does not support query parameters, it probably doesn't support Unicode either. :)
Added: Also. queries like you wrote up there are killers for performance - no indexes can be used. I'd advise to look up your DBMS' full-text-indexing capabilities. They are meant exactly for cases such as this.
Yes, they could still inject items, without spaces it might not do much, but it is still a vulnerability.
In general blindly adding user input to a query is not a good idea.
Here's a trivial injection, if I set field1 to this I've listed all rows in your database. This may be bad for security...
'+field1+'
You should use parameters (these are valid in inline SQL too), e.g.
AND Field1 = #Field1

Resources