SQL Injection on Views - sql

We are using 3-Tier Architecture in ASP.Net.
There are 3 Layers
Presentation
Business
Data Access
The Data Access Layer contains the GetData and ExecuteQuery etc function.
What I want to know is that, that want to call the View directly from the Presentation Layer. Is there any chance of SQL injection in calling a view from front-end without using stored procedure?
Presentation Layer (C#)
protected void btnView_Click(object sender, EventArgs e)
{
DL obj = new DL();
DataTable tb = new DataTable();
string query = "select * from ViewTeacher where FID = " + txtName.Text;
tb = obj.GetData(query);
}
DBAccess
public DataTable GetData(string query)
{
DataTable datatable = new DataTable();
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = query;
try
{
if (cmd.Connection.State != ConnectionState.Open)
{
cmd.Connection.Open();
}
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(datatable);
}
}
catch (Exception ex)
{
throw new ArgumentException(ex.Message);
}
return datatable;
}

How are you "calling a view"? If you're running an ad-hoc query of:
SELECT <columns> FROM View WHERE ColumnX = 'Y'
and if that query is being constructed using (potentially) hostile input then yes, of course that can be subject to SQL injection - the whole point of injection is that the attacker can change the nature of the query:
SELECT <columns> FROM View WHERE ColumnX = 'Z'
UNION ALL
SELECT name,0,0,0,0 FROM INFORMATION_SCHEMA.TABLES --'
The attacker isn't limited to just the objects that are present in the original query.
The untrustworthy input in the two above queries was:
Y
and
Z'
UNION ALL
SELECT name,0,0,0,0 FROM INFORMATION_SCHEMA.TABLES --

As you are writing the query as follows that takes value from a textbox, 100% there is posibility for sql injection.
string query = "select * from ViewTeacher where FID = " + txtName.Text;

There should be no chance of SQL Injection while calling a view from front end, as views don't take parameters.
reference :
can we pass parameter to a view in sql?

Related

ExecuteSqlCommand possible to access table in another context?

I've built a query that involves joining 2 tables that exist in separate databases. I'd like to run this query within my .NET Core 2.1 application. Here is what I've got:
Query:
INSERT INTO Database2.dbo.Table2
SELECT * FROM Table1
WHERE Col1 = 5
This query works just fine within SQL Operations studio.
C#:
using(var context = ConnectionHelper.getContext(dbInfo))
{
string MySQLQuery =
" INSERT INTO Database2.dbo.Table2 " +
" SELECT * FROM Table1 " +
" WHERE Col1 = 5 ";
try
{
context.Database.ExecuteSqlCommand(MySQLQuery);
}
catch(Exception e)
{
Console.WriteLine(e.Message); // This doesn't get called, the query doesn't throw an error.
}
}
When I run the query through .NET Core, nothing happens. I expect ~1000 rows to be written to Database2.dbo.Table2, but 0 are written. No Error message is logged, so .NET Core seems to think it succeeded in performing the given SQL query. I'm assuming the error is being caused by my reference to Database2.
The solution to the problem was to avoid using ExecuteSqlCommand within a given context. Since I didn't specifically need any features of EF for this query, I ended up using SqlCommand.ExecuteNonQuery() from the System.Data.SqlClient library. Here's a working example:
using (SqlConnection con = new SqlConnection(< your connection string >))
{
con.Open();
SqlCommand command = new SqlCommand();
command.CommandText = " SQL STATEMENT HERE ";
command.Connection = con;
command.ExecuteNonQuery();
}

SELECT over multiple MSSQL databases in Powershell?

I need to run a SELECT statement that does a right outer join between two tables that are in two different databases from a Powershell script.
I do have code that can connect to one DB and run a select there, but I have no idea how to attach a DB connection to the second database to the same System.Data.Odbc.OdbcCommand object. Is this possible?
Connect you on one base and try Something like this:
Select *
From yourbase1.dbo.yourtable1 f1 right
Outer Join yourbase2.dbo.yourtable2 f2
On f1.key1=f2.key1
example of code C#
string connetionString = null;
OdbcConnection cnn;
connetionString = "Driver={SQL Server};Server=COLOSSUS\\SQLEXPRESS;Database=test;Trusted_Connection = Yes; ";
cnn = new OdbcConnection(connetionString);
try
{
cnn.Open();
using (OdbcCommand com = new OdbcCommand("select * from test.dbo.DemoTable f1 right outer join dbremy57.dbo.NewTable f2 on f1.ID=f2.ID", cnn))
{
using (OdbcDataReader reader = com.ExecuteReader())
{
while (reader.Read())
{
string word = reader.GetString(0);
// Word is from the database. Do something with it.
}
}
}
cnn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Can not open connection ! ");
}

Oracle Parameters in .net sql queries - ORA-00933: SQL command not properly ended

I am trying to do create a where clause to pass as a parameter to an Oracle command and it's proving to be more difficult than I thought. What I want to do is create a big where query based off user input from our application. That where query is to be the single parameter for the statement and will have multiple AND, OR conditions in it. This code here works however isn't exactly what I require:
string conStr = "User Id=testschema;Password=pass12341;Data Source=orapdex01";
Console.WriteLine("About to connect to Database with Connection String: " + conStr);
OracleConnection con = new OracleConnection(conStr);
con.Open();
Console.WriteLine("Connected to the Database..." + Environment.NewLine + "Press enter to continue");
Console.ReadLine();
// Assume the connection is correct because it works already without the parameterization
String block = "SELECT * FROM TEMP_VIEW WHERE NAME = :1";
// set command to create anonymous PL/SQL block
OracleCommand cmd = new OracleCommand();
cmd.CommandText = block;
cmd.Connection = con;
// since execurting anonymous pl/sql blcok, setting the command type
// as text instead of stored procedure
cmd.CommandType = CommandType.Text;
// Setting Oracle Parameter
// Bind the parameter as OracleDBType.Varchar2
OracleParameter param = cmd.Parameters.Add("whereTxt", OracleDbType.Varchar2);
param.Direction = ParameterDirection.Input;
param.Value = "MY VALUE";
// Get returned values from select statement
OracleDataReader dr = cmd.ExecuteReader();
// Read the identifier for each result and display it
while (dr.Read())
{
Console.WriteLine(dr.GetValue(0));
}
Console.WriteLine("Selected successfully !");
Console.WriteLine("");
Console.WriteLine("***********************************************************");
Console.ReadKey();
If I change the lines below to be the type of result I want then I get an error "ORA-00933: SQL command not properly ended":
String block = "SELECT * FROM TEMP_VIEW :1";
...
...
param.Value = "WHERE NAME = 'MY VALUE' AND ID = 5929";
My question is how do I accomplish adding my big where query dynamically without causing this error?
Sadly there is no easy way to achieve this.
One thing you will need to understand with parameterised SQL in general is that bind parameters can only be used for values, such as strings, numbers or dates. You cannot put bits of SQL in them, such as column names or WHERE clauses.
Once the database has the SQL text, it will attempt to parse it and figure out whether it is valid, and it will do this without taking any look at the bind parameter values. It won't be able to execute the SQL without all of the values.
The SQL string SELECT * FROM TEMP_VIEW :1 can never be valid, as Oracle isn't expecting a value to immediately follow FROM TEMP_VIEW.
You will need to build up your SQL as a string and also build up the list of bind parameters at the same time. If you find that you need to add a condition on the column NAME, you add WHERE NAME = :1 to the SQL string and a parameter with name :1 and the value you wish to add. If you have a second condition to add, you append AND ID = :2 to the SQL string and a parameter with name :2.
Hopefully the following code should explain a little better:
// Initialise SQL string and parameter list.
String sql = "SELECT * FROM DUAL";
var oracleParams = new List<OracleParameter>();
// Build up SQL string and list of parameters.
// (There's only one in this somewhat simplistic example. If you have
// more than one parameter, it might be easier to start the query with
// "SELECT ... FROM some_table WHERE 1=1" and then append
// " AND some_column = :1" or similar. Don't forget to add spaces!)
sql += " WHERE DUMMY = :1";
oracleParams.Add(new OracleParameter(":1", OracleDbType.Varchar2, "X", ParameterDirection.Input));
using (var connection = new OracleConnection() { ConnectionString = "..."})
{
connection.Open();
// Create the command, setting the SQL text and the parameters.
var command = new OracleCommand(sql, connection);
command.Parameters.AddRange(oracleParams.ToArray());
using (OracleDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
// Do stuff with the data read...
}
}
}

To String Conversion while doing Join in LINQ

I am using LINQ query to fetch the data from database and also doing joins in the LINQ query as,
(
from accountTransaction in AccountTransactions
join xlkpQualifier in Enumerations on
accountTransaction.LkpQualifier.ToString() equals xlkpQualifier.Value
select top accountTransaction)
.Take(10);
I am getting Exception on accountTransaction.LkpQualifier.ToString() that System.ToString() can't be used in LINQ Entities.
But I am getting problem here in conversion to string on Join.
How can I do it?
Until you provide us with some more information on the SQL types of the fields LkpQualifier and xlkpQualifier, I will answer as follows:
You should either (1) change your table data schema and set the same data types or (2) write the raw SQL version of your LINQ query and execute the query
Raw SQL query using EF:
using (var db = new Entities())
{
string myQuery = "SELECT * FROM Table";
var result = new ObjectQuery<DbDataRecord>(myQuery, db);
var resultList = result.ToList();
}
In the raw SQL query itself, you will probably have to use the CAST function with the right type:
CAST(Enumerations.xlkpQualifier AS System.Int32)
Raw SQL query without using EF:
There is also a way to write raw SQL without using EF (useful when your table doesn't have the primary key set and you don't have access to change that):
using (var conn = new SqlConnection(connectionString))
{
conn.Open();
using (var cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = "SELECT * FROM Table";
var result = cmd.ExecuteScalar(); // or other variations
}
}

SQL - OleDbCommand not changing Sql Parameter

Below is the code for my Select * Function - It WORKS well and does everything great until i change the SQL string from Select * From Company to
query = "Select * From #1";
and then do the following
query = "Select * From #1";
OleDbCommand Command = new OleDbCommand(query, sqlConnStr);
DataTable Table = new DataTable();
DataSet dataSet = new DataSet();
Table = null;
//Add Parameters
Command.Parameters.AddWithValue("#1", SQLTables.Company);
try
{
Command.ExecuteNonQuery();
adapter.SelectCommand = Command;
adapter.Fill(dataSet);
Table = dataSet.Tables[0];
}
catch (Exception e)
{
MessageBox.Show("A Error occured whilst trying to execute the command.\n" + e.Message);
}
return Table;
The DBMS keeps sending back "Query incomplete" - I assume The Command variable is sending the string query through without changing the Parameter from #1 to Company
Here is a piece of code (mine) where this does work. This is an insert statement rather that a select - Correct me if i am wrong but should it not also work with the SELECT aswell
private void MainActionsInsert(string Action, bool Checked)
{
OleDbCommand Command = new OleDbCommand("INSERT INTO MainActions Values (ID, Action, BoolValue)", DataBaseConnection);
//Add Parameters
Command.Parameters.AddWithValue("ID", GenerateID());
Command.Parameters.AddWithValue("Action", Action);
Command.Parameters.AddWithValue("BoolValue",Checked);
//Add Command
MainActionsAdapter.InsertCommand = Command;
//Execute Agains DataBase
Command.ExecuteNonQuery();
//Accept Changes
}
`
OLEdb doesn't recognize named parameters. You must use ? in the query text.
However, you also can't use dynamic table names with parameterized queries, so even using a ? will not help.
You need to use full dynamic SQL, though that can open you up to SQL Injection. Make sure you read the full article I linked.
OleDbCommand Does accept Parameterized SQL just not in the From Clause - It Has to be either in a WHERE clause or something like that. Like you said it Worked with the insert function because it expects "parameters" there. For example this will work
query = "Select * From Company Where #param = 1";
OleDbCommand Command = new OleDbCommand(query, sqlConnStr);
DataTable Table = new DataTable();
DataSet dataSet = new DataSet();
Table = null;
//Add Parameters
Command.Parameters.AddWithValue("param", "ID");
try
{
Command.ExecuteNonQuery();
adapter.SelectCommand = Command;
adapter.Fill(dataSet);
Table = dataSet.Tables[0];
}
catch (Exception e)
{
MessageBox.Show("A Error occured whilst trying to execute the command.\n" + e.Message);
}
return Table;
Funny though that it doesn't work for the Select part though