Saturday, March 10, 2018

The Exception to the Rule

Exceptions in Programming Languages

I learned a neat little construct recently: exceptions!

Okay, so it's been 13 years since I first heard about them, but it wasn't until I read this StackOverflow question that I felt like I actually understood them. I finally felt like I knew when to use exceptions and when not to use exceptions.

I don't want to focus on the details of exceptions, but perhaps a little crash course is appropriate.

What are exceptions?

Exceptions can be thrown and caught. When you "throw" an exception, your program stops dead in its tracks. It picks back up wherever you have chosen to "catch" the exception. There's a little behind-the-scenes stuff too, but that's the gist of it.

    try {
        cout << "The program gets to here... ";
        throw exception();
        cout << "... and it never gets here." << endl;
    catch (exception & e) {
        cout << "... and it picks up here." << endl;

If you run this code, it will output the following:

The program gets to here... ... and it picks up here.

It works, but is this good code? Are there better ways to do the same thing?

Pros and Cons of Exceptions

Exceptions are slow. Yes, they can be terribly slow! It is much faster to use conditionals instead of exceptions. (Or, in the case of the program above, just drop the dumb lines that are only there for the example's sake.) Exceptions are just plain slow!

However, not having an exception is faster than conditional execution (like if, while, etc.). If you /can/ throw an exception but you don't, that's super fast! They are only slow when they are actually used.

That's the gist of the answers on the StackOverflow question I linked earlier.

When do you use exceptions?

After meditating on that StackOverflow question and its answers, I feel like I finally know when to use exceptions. Bare with me, and I'll explain.

A few givens:
  • Exceptions are slow, so you don't want to use them.
  • Having exceptions but not using them is fast.
  • Conditionals are almost as fast as unused exceptions. *
* at least in the languages I cared to research last weekend.

My conclusion is that exceptions should never happen. They should never be used. They should never be thrown. They should never be caught.

The exception to the rule "exceptions should never happen" is "an exception happens".

Thoroughly confused...

I get up and go to work every morning at 7:50am. I do this every weekday. This is normal to me.

Six months ago, I got in my car at 7:50am, and it wouldn't start. This is an exception! I had to change my plans because of this unexpected event.

I have come to the realization that exceptions in programming are exactly the same thing. In normal operation, how should the program work? Use exceptions for exceptions to this rule of how things should work.
  1. Use a conditional when: It's something that needs checked or just happens sometimes. Your program is coded to handle anything amiss.
  2. Use an exception when: Uh oh! Something happened, and the program wasn't built for this!
In short, exceptions never happen, and the exception to this rule is when they happen.

I need an example.

Perfect! Let's say you've got a text editor. Usually, you'll be trying to open valid files, but sometimes the user tells you to open a file that doesn't exist.

bool openFile(const char * filename)
    this->f = fopen(filename);
    if (!f)
        return false;
    return true;

This is a member function of our TextEditor class. You try to open a file. If it doesn't exist, then no harm done. The program keeps on chugging away as usual, probably prompting them for a valid file name.

Now let's look at a different case. What if you are trying to open a configuration file for your program?

    FILE *f = fopen("myConfig");
    if (!f)
        throw exception("Config not found!");

It's different. We expect the config file to exist. If it doesn't, we just can't continue. This is an exception.

We will, of course, catch the exception somewhere. If we're good, we might try to recreate the config and try again. But, for the moment, we've hit an unexpected obstacle that needs fixed before we can continue normal operation.

Thursday, February 23, 2017

SQL Injection: What it is and how to avoid it

A while back, we (where I work) took over a project from another company. I was going to make some small changes and have it up before my second cup of coffee! Then I opened the code and realized I would be working late that day instead.

Among other issues, the code was vulnerable to SQL Injection.

SQL Injection is one of the easiest hacks to do. It's also one of the easiest to protect against. Still, it's a pretty common vulnerability! As much as I would love to have a backdoor into tons of sites, I can't help but lose sleep over this problem being out there. I have to share a few solutions.

What is SQL Injection?

For an example, let's take a very simple login page. I won't post the code, but the basic idea is to take a username and password, compare it to what's in the database, and log them in if it's a match. Easy peasy!

Here's the SQL to match it up in the database:

SELECT id FROM users WHERE username='bob' AND password='1234'

If it doesn't return anything, the username and password is wrong. If it finds a match, it returns the user's ID.

What if we change the username to bob'--?

SELECT id FROM users WHERE username='bob'--' AND password='1234'

Whoah! We just made it so that we don't even need the password! We can log in as anybody so long as we know their username!

The problems don't stop there. We can change a page that displays a list of items to sort/filter however we wish. We can increase the number of results returned and use that to do a very good DOS attack.

If the webhost is particularly unlucky, we can even execute SQL for other websites that they host -- even if those sites aren't vulnerable! (Hint: "USE abcDatabase;")

How do we protect against it?

That's easy. Sanitize your inputs!

Way 1 - Escaping data

You can properly escape the data before putting it into the SQL query.

Most languages have a function to escape out harmful characters, and it's usually pretty easy to use. This post is language-agnostic, but the basic idea in most languages is to pass in a potentially harmful string and get back a properly escaped one. The SQL query becomes the following:

SELECT id FROM users WHERE username='bob''--' AND password='1234'

As you can see, the SQL injection attempt will now be unsuccessful!

This time.

Watch out!

What if we have the following query that deletes the message with a given ID?

DELETE FROM messages WHERE messageId=12

It looks pretty harmless. Of course, we'll be sanitizing any user input anyways, right?

What if we give our code "1 OR 1=1" as the ID to delete? There are no special characters to escape. The string will get substituted as-is. What does this do to our query?

DELETE FROM messages WHERE messageId=1 OR 1=1

Oh, it just deletes everything. Even though we escaped all of the harmful characters, we are still vulnerable to SQL injection!

The quick solution is to put single quotes around every "variable" you're substituting in. It will work, but then you might run into weird logic errors when doing comparisons. A better solution is to use parameterized queries. Read on.

Way 2 - Parameterized Queries

Parameterized queries will properly escape any data, will verify that the type of data matches up, and will (hopefully) make sure everything's dandy with the character encodings. They are the best way to do SQL queries.

SELECT id FROM users WHERE username=@username AND password=@password;
DELETE FROM messages WHERE messageId=@messageId;

It might look a little different in different languages, but that's the basic idea.

Now you need the code that puts in the data. This depends a lot on the language, but the basic idea is to say what type of data each parameter is and then to set it to a value. In VB.Net, here is the code for the second query:

Dim query = "DELETE FROM messages WHERE messageId=@messageId"
Dim cmd As New SqlCommand(query, connection)
cmd.Parameters.Add("@messageId", SqlDbType.Int)
cmd.Parameters("@messageId").Value = 12

Parameterized queries are more verbose and somewhat confusing at first, but do use them. Use parameterized queries. Use parameterized queries.

Conclusion and Final Thoughts

SQL Injection is very easy to do, very common, and yet very easy to protect against. The simple solution is to just use parameterized queries everywhere. This OWASP page has some handy code snippets for your reference.

Here's a rule: Always use parameterized queries. Never insert your data directly into a query string (even if properly validated and escaped first). I don't care what your teacher or textbook says. Use parameterized queries. The only exception to this rule is when you know the risks and make an informed decision to go another route.

Saturday, January 12, 2013

Playing a Pitch in an Android App with AudioTrack

 I've been working on an android app lately that can be used to tune instruments. I've run into a road block with the pitch detection, so I'm starting over and making the code nicer. While I'm at it, I figure I may as well share some of what I've learned!

Sunday, January 6, 2013

AVL vs. Red-Black: the conclusion

    I accidentally deleted my original blog post about this, and I can't recover it despite trying all sorts of different tricks. So, here it is reposted. Sorry for any broken links.

Thursday, January 3, 2013

Year of Change

December 21, 2012 came and went, and the world is still here.  I didn't look a lot into the Mayan Calendar, but I think I remember reading that every time one of their circle calendar thingeys rolls over, it's a new era that brings change.

Every year, on December 31, people decide to make new years resolutions.  This year, why not assume the Mayans had something going right and make a resolution to see change?

People have been chanting about "change" a lot lately, but what has really changed?  And why are we still living relatively ordinary lives?  Myself, I am terrified of change!  I like my comfort zone, and I'm sure most of you prefer to not take risks, too.

We all have opportunities.  Why not take them?  You have a lot to lose, but you have even more to gain!

I stopped spending so much time programming a while back.  I got a guitar and played it until my fingers blistered and cracked.  On the 31st, I bought a new car.  Yesterday, someone called me and asked me to come work at some company.

Change.  I have an option to refuse it and continue to live in comfort.  I think I'll make a change in my habits and seek to change.  I'm taking the risk, making a gamble, and I think the odds are in my favor.  Will you join me?

I got my first blow yesterday.  I'm apparently not as great at singing and playing the guitar as I thought.  I knew I wasn't great, but am I not at least a little good?  Nope!  But I also found some encouragement in an unlikely place.  I found a youtube video of one of my favorite singers when she was younger.  I love her to death, but she just could not sing!  Now, she's going on world tours!  If she can do it, why can't I?  And if I can do it, why the hell are you still reading this?  Get out there and live a little!

Tuesday, December 11, 2012

Resistance Accomplished With Penguin Jokes!

My heart is saddened and worried as I resist the urge to dive into my old computer habits to avenge my newest love.  "That would be so cruel!"  Or, "I should get caught!"

I'm reminded of the last guy who thought he was clever with his 1337 5k*11z...  I sometimes miss his crazy ideas of how to annoy me.  And the guy before him who avoids me like the plague?  So sad...  so sad.

My evil side is hurt that I abandoned my computer world even though it was out of evil anger.  Yes, folks, with the exception of little scripts here and there to help me accomplish a task, I quit programming.  It's caused more harm than good, so I am looking for a new talent.

My newest talent is joke telling!  No, not really, but I am looking for good penguin jokes to make me feel better.  They must be penguin jokes!  Here are a few I've found so far (and 2 I knew):

FAT PENGUIN!!!!!!!!!!!!!!!!!!!!!!!!!!!
First joke, to break the ice!!!

Q: What do you call a penguin in the desert?
A: Lost!

Q: Why don't you ever see penguins in Britain?
A: Because they're afraid of Wales!

Two penguins are standing on an ice floe. The first penguin says, "you look like you're wearing a tuxedo." The second penguin says, "what makes you think I'm not?"

Penguins are black and white.  Old TV shows are black and white.  Therefore, penguins are old TV shows.

Q: And, lastly, how do you express your delight at a penguin joke?
A: Cool!

Any more?  Please share them below!

P.S. Don't take anything you read above seriously except for the request for more penguin jokes.  Most of it is silliness.  It's sad that I feel like I have to say this, but that's the world for you!  So, no hate mail from penguins!  Thanks!

Wednesday, November 28, 2012

Dreams of Fortune

    I won't tell what inspired this right now.  I want to know if you, dear reader, can take any meaning from my first attempt at poetry.  Please, be critical.  Be insulting if you need to be.  I have no confidence in my poetic skills, so you won't hurt my feelings in the least bit.  Shall I keep things like this in my notebook hidden away, or should I share?

Dreams of Fortune
What dreams of fortune to come our way are worth the time to contemplate?
Yet stuck we are obsessed with fame, but all we want is them to know our name.
How long will it take to rise to power? And will it be worth the wasted hours?
We will fail, and we will fall.  Then, we will cry and take our fate.
Giving up is the hardest necessity, but someone has to work for the clock.
All the while, we have that dream that someday we will live the life where we can be the idol who sleeps worry-free.
But someday soon, our fire will die, and we will be left an empty shell wondering the streets doing our duties and admiring those who got that lucky break.