MySql NetScaler DataStream Content Switching failing to detect select - load-balancing

We are using the new DataStream feature introduced in NetScaler 9 (we're on v10) to do content switching (described here: http://support.citrix.com/proddocs/topic/netscaler/ns-dbproxy-wrapper-con.html). We have a read-only virtual server that balances across several read-only MySql slaves. We use our Content Switching to send all "Selects" over to the read-only server.
the policy is configured as such:
mysql.req.query.command.contains("select")
our users send multi-part queries to our database server. Most often they are simple, like:
use database;
select col1 from table1;
Sometimes they will put comments at the head of the query. for example:
-- this is my query
select col1 from table1;
What we've found is that if the query simply starts with a select, everything works swimmingly. However, in the cases where there is a use statement or comments preceding the query, the content swticher fails to detect that this is a select query and it bypasses our read-only virtual server.
I am about to tell all of our developers that they must fully alias every table in every query and avoid use statements (yes, this is a good thing anyway), and also that they cannot use comments in their sql (that's just silly).
Does anyone know how I can configure my NetScaler DataStream Content Switching to ignore comments and use statements?

The decision on where to send the query is done on the first line received after successful authentication... so ignoring the comment won't work.
You could setup a responder policy which sends back an error message saying "Please don't use SQL Comments in commands sent to the Load Balanced VIP". A bit draconian, but your devs would get the message fairly quick.. but there's no way to ignore the comment, but still base a decision on the select statement. However, I was under the impression that the select statement is up to the first semi colon... so in your example above, it should (in theory) still find the select statement. I'd need to test that to be certain of the behaviour however.
Also - the USE statement is critical. This is the DB on which all subsequent commands are issued.
It would be best practice to NOT use the USE statement, but instead, change the select statement to:
select col1 from database.table1;
Once the USE statement is seen, it prevents any subsequent commands being pipelined down the same connection... So if there are a lot of Use statements, you will not get to enjoy the connection multiplexing functionality that comes with DataStream.

We learned that Block Level comments are acceptable, but single line comments are not.
This is properly ignored:
/* my comment */
These comment styles are treated as part of the query:
-- my comment
# my comment

kind of ridiculous when having SET autocommit=0 is perfectly reasonable. What about in that situation.

Related

Sql Injection queries

I have a website which contains sql injection vulnerability but i can exploit it, just because of some filtration by the web server.
So i have a payload order by 4 to find the columns but i can't find. I don't know whats happening but when i use this payload it works
' order by 4--+ when this payload executes i get the column error.
So what happens with the second one? The main doubt is what is the work of the --+ and why is it necessary to put a single tick (') in second payload?
I think that the -- in sql means : comment what is forwarding.
You should use a ' to don't get sql syntaxe errors on your injection and to see the result.
If you use PHP, just take a look for The Documentation. Wish it could help you.
Good luck

cgi generic sql injection problems

I was scanning a site when the following vulnerability popped up: CGI Generic SQL Injection
nessus sais that An attacker may exploit this flaw to bypass authentication, read confidential data, modify the remote database, or even take control of the remote operating system.
So i continued reading and found out that the vulnerability sits in this piece of code:
Using the POST HTTP method, Nessus found that :
The following resources may be vulnerable to SQL injection :
The '_codeTextBox' parameter of the /LoginTeacherForm.aspx CGI :
/LoginTeacherForm.aspx [loginButton=Login&_VIEWSTATE=dDwtMTU2NDIxMDkwN
Ts7Pg%3d%3d&btnChangePassword=Wijzig%20Pincode&_pinCodeTextBox=&_codeTex
tBox='+convert(int,convert(varchar,0x7b5d))+']
-------- output --------
Exception Details: System.Data.SqlClient.SqlException: String or
binary data would be truncated.
The statement has been terminated.
But i'm wondering how an attacker can exploit this vulnerability, because when i paste that piece of code it just give me the error.
So my question is how would an attack be able to actually hack into the site and bypass login etc. (Educational purpose only of course)
It looks like a false positive caused by the Nessus request causing your page to insert too long a string into a field. Nessus has detected the error was a SQL server error and has said that it may be a SQL injection vulnerability.
To test yourself try the request with _codeTextBox= set to a single quote to see if you still get a SqlException. If so amend this to two single quotes and if the error then goes away you are probably vulnerable.
The error System.Data.SqlClient.SqlException indicates an error in your SQL query statement. This implies that value stored in the _codeTextBox parameter is not validated or otherwised sanitized before being put into the query.
This would have varying implications depending on the query and logic surrounding its return value. It is impossible to determine the worst case scenario without a thorough understanding of the web application. Suffice it to say, this issue should be fixed by the developer. Fortunately, it is usually easy to fix once identified.
In this case, it looks like the _codeTextBox parameter is being passed to the convert function. I doubt anyone could exploit this. But, this indicates insecure coding practices that probably appear in other areas that Nessus is not aware of. Read below for more info.
I see this most often when the programmer simply concatenates the values with the SQL query string:
Unsafe Example (java) (Source OWASP)
String query = "SELECT account_balance FROM user_data WHERE user_name = "
+ request.getParameter("customerName");
try {
Statement statement = connection.createStatement( … );
ResultSet results = statement.executeQuery( query );
}
Since the value simply gets appended to the end of the query, the user can change query to do something nefarious like login as any user or view all transactions. In the above example, the user could change the customer name parameter to something like '' or 1=1 or worse.
Expected query:
SELECT account_balance FROM user_data WHERE user_name = someuser
Bad query:
SELECT account_balance FROM user_data WHERE user_name = '' OR 1=1
OWASP recommends the following defensive measures. Your situation will dictate what is appropriate:
Primary Defenses:
Use of Prepared Statements (Parameterized Queries)
Use of Stored Procedures
Escaping all User Supplied Input
Additional Defenses:
Also Enforce: Least Privilege
Also Perform: White List Input Validation
You really need to check out OWASP's site and read more about SQL injection.

FM ExecuteSQL returns different results than direct database query

I am wondering if anyone can explain why I get different results for the same query string between using the ExecuteSQL function in FM versus querying the database through a database browser (I'm using DBVisualizer).
Specifically, if I run
SELECT COUNT(DISTINCT IMV_ItemID) FROM IMV
in DBVis, I get 2802. In FileMaker, if I evaluate the expression
ExecuteSQL ( "SELECT COUNT(DISTINCT IMV_ItemID) FROM IMV"; ""; "")
then I get 2898. This makes me distrust the ExecuteSQL function. Inside of FM, the IMV table is an ODBC shadow, connected to the central MSSQL database. In DBVis, the application connects via JDBC. However, I don't think that should make any difference.
Any ideas why I get a different count for each method?
Actually, it turns out that when FM executes the SQL, it factors in whitespace, whereas DBVisualizer (not sure about other database browser apps, but I would assume it's the same) do not. Also, since the TRIM() function isn't supported by MSSQL (from what I've seen, at least) it is necessary to make the query inside of the ExecuteSQL statement something like:
SELECT COUNT(DISTINCT(LTRIM(RTRIM(IMV_ItemID)))) FROM IMV
Weird, but it works!
FM keeps a cache of the shadow table's records (for internal field-id-mapping). I'm not sure if the ExecuteSQL() function causes a re-creation of the cache. In other words: maybe the ESS shadow table is out of sync. Try to delete the cache by closing and restarting the FM client or perform a native find first.
You can also try a re-connect to the database server via the Open File script step.
HTH

SQL Parameters - where does expansion happens

I'm getting a little confused about using parameters with SQL queries, and seeing some things that I can't immediately explain, so I'm just after some background info at this point.
First, is there a standard format for parameter names in queries, or is this database/middleware dependent ? I've seen both this:-
DELETE * FROM #tablename
and...
DELETE * FROM :tablename
Second - where (typically) does the parameter replacement happen? Are parameters replaced/expanded before the query is sent to the database, or does the database receive params and query separately, and perform the expansion itself?
Just as background, I'm using the DevArt UniDAC toolkit from a C++Builder app to connect via ODBC to an Excel spreadsheet. I know this is almost pessimal in a few ways... (I'm trying to understand why a particular command works only when it doesn't use parameters)
With such data access libraries, like UniDAC or FireDAC, you can use macros. They allow you to use special markers (called macro) in the places of a SQL command, where parameter are disallowed. I dont know UniDAC API, but will provide a sample for FireDAC:
ADQuery1.SQL.Text := 'DELETE * FROM &tablename';
ADQuery1.MacroByName('tablename').AsRaw := 'MyTab';
ADQuery1.ExecSQL;
Second - where (typically) does the parameter replacement happen?
It doesn't. That's the whole point. Data elements in your query stay data items. Code elements stay code elements. The two never intersect, and thus there is never an opportunity for malicious data to be treated as code.
connect via ODBC to an Excel spreadsheet... I'm trying to understand why a particular command works only when it doesn't use parameters
Excel isn't really a database engine, but if it were, you still can't use a parameter for the name a table.
SQL parameters are sent to the database. The database performs the expansion itself. That allows the database to set up a query plan that will work for different values of the parameters.
Microsoft always uses #parname for parameters. Oracle uses :parname. Other databases are different.
No database I know of allows you to specify the table name as a parameter. You have to expand that client side, like:
command.CommandText = string.Format("DELETE FROM {0}", tableName);
P.S. A * is not allowed after a DELETE. After all, you can only delete whole rows, not a set of columns.

How to get the query displayed when a change is made to a table or a field in a table in Postgresql?

I have used mysql for some projects and recently I moved to postgresql. In mysql when I alter a table or a field the corresponding query will be displayed in the page. But such a feature was not found in postgresql(kindly excuse me if I'm wrong). Since the query was readily available it was very helpful for me to test something in the local database(without explicitly typing the query), copy the printed query and run it in the server. Now it seems like I've to manually do all the trick. Even though I'm familiar with the query operations,at times it can be pretty time consuming process. Can anybody help me? How can I get the corresponding query to get displayed in postgresql(like in mysql) whenever a change is made to the table?
If you use SELECT * FROM ... there should not be any reason for your output to not include newly added columns, no matter how you get your results - would that be psql in command line, PgAdmin3 or any other IDE.
After you add new columns, it is possible that these changes are still in open transaction in other window or SQL command - be sure to COMMIT such transaction. Note that your changes to data or schema will not be visible to any other database clients until transaction commits.
If your IDE still does not show changes, maybe you need to refresh list of tables or if that option is not available, restart your IDE. If that does not work still, maybe you should use better IDE.
If you have used SELECT field1, field2, ... FROM ... then you must add new fields into your SELECT statement(s) - but this would be true for any other SQL implementation, MySQL included.
You could use the LISTEN / NOTIFY mechanism in PostgreSQL to notify your client on altering the database schema.