2

While i've been debugging my code, I've been writing the output to the console so that I can monitor the errors and sql output. Naturally to protect against sql injection I have parameterised the queries where needed. After reading some articles online regarding the methods by which some injection attacking programs work, I now question whether the below practice is a good idea anymore.

Consider the following method.

public void MyQuery(int item_id)
{

        string sql = "SELECT * FROM table WHERE item_id = @id";


        SqlCommand sqlQuery = new SqlCommand(sql,conn);

        sqlQuery.Parameters.Add("@id", SqlDbType.Int).Value = item_id;

        try
        {
            conn.Open();
            sqlQuery.ExecuteNonQuery();
            conn.Close();
        }
        catch (SqlException ex)
        {
            Console.WriteLine(sql);
            Console.WriteLine(ex.Message);
        }
}

on my dev machine the console output is fine - no risk here. But if i were to leave the code as it is now when the application was live, would that potentially open up other avenues to exploit?

Im aware that if i were to have done MessageBox.Show(ex.Message); that would certainly be bad due to it being in your face.

Takarii
  • 1,612
  • 2
  • 18
  • 29
  • 1
    you can use debug directives: http://stackoverflow.com/questions/2104099/c-sharp-if-then-directives-for-debug-vs-release https://msdn.microsoft.com/en-us/library/4y6tbswk.aspx – user1666620 Apr 21 '16 at 10:25

1 Answers1

2

You're deploying a WinForms application that connects to a SQL Server with credentials that apparently allow the application to write to that SQL Server.

Leaking SQL errors to the console is the least of your worries.

A malicious user can simply use the credentials used by your application to execute arbitrary SQL on that server.

Anything you deploy on a client machine must be considered insecure. Leaking queries is not the problem (the user could decompile your application or check its resources and inspect the SQL strings), the problem is that the client has a direct database connection.

If you want to prevent the client to know where the database is, what its credentials are and what queries your application executes, you must remove all this code from your application, and let the database stuff happen on a different machine altogether. You can then talk to this machine through a web service, for example.

Then the web service handles authentication, and refuses to execute any action for a user that isn't authenticated.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • was just an example method. credentials are set correctly, i was curious about console output. (delete was probably a bad function example) – Takarii Apr 21 '16 at 10:27
  • 1
    Sorry, but you're missing the point. If your application, running on a user's machine, can directly connect to the database server, then the user running that application can trivially capture the credentials and connect to the server using another application and run any SQL they want. – CodeCaster Apr 21 '16 at 10:27
  • even if each user using the application is authenticated using their own logins? – Takarii Apr 21 '16 at 10:33
  • @CodeCaster - how would an attacker do this? How would they get the credentials (assuming they were encrypted in the config file)? (Genuine question, curious as to how this is vulnerable) –  Apr 21 '16 at 10:34
  • @Takarii yes, as a malicious user can simply decompile your code or attach a debugger and bypass the login entirely. – CodeCaster Apr 21 '16 at 10:34
  • @CodeCaster - that answers my question too. I did suspect decompiling would allow the user to see what's goin on, but didn't consider attaching a debugger. –  Apr 21 '16 at 10:35
  • @JᴀʏMᴇᴇ besides that, the database connection string will be in-memory in plaintext at one point (if not trivially obtainable from the app.config). – CodeCaster Apr 21 '16 at 10:36
  • 2
    This is worrying. Both that I missed this, and that I'm not sure where to go next. – Takarii Apr 21 '16 at 10:39