Tuesday, August 2, 2022

South Korea Trip, August 2

I'm gazing out of a giant window in a high rise over the beautiful district of Gangnam -- you know the place, Psy wrote his famous song "Gangnam Style" about it!  I am finally at my apartment here, a very comfortable studio apartment, and this moment seems like a wonderful reward for all of my efforts to get here.  Let me tell you, it was not easy!

Sunday started in a way typical for an upcoming trip.  I finished packing my bags, dropped my car off with a friend, and got a ride to the airport.  The first flight was pretty ordinary.  I went from Memphis to Detroit.  My second flight, from Detroit to Incheon, was over fourteen hours long, and that was not so easy.

Fourteen Hour Flight

Of course, on a fourteen hour flight, I'm not going to put myself into coach class!  I couldn't justify the cost of getting first class, but I got the closest to it that I could.  They put me in a recliner with a blanket and pillow, complimentary noise canceling headphones, and a huge selection of music and movies to play on my personal television!  Some of the food was even good too!




Even so, sitting on the plane became very difficult at around the four hour mark.  My body did not like sitting down for so long even with the nice seat.  My body yearned for a bed or even a place to walk around!  At this point of feeling the pain, I still had ten more hours to endure.  It was hard.

Landing in Incheon

Landing in Incheon was more intriguing than I expected.  I expected the landscape to look the same way it does at home when looking down from a plane.  I expected to descend into clouds that disappeared as we approached.  I expected to see the runway from a thousand feet in the air.  Nothing was like I expected.

The landscape -- the little of it that I could see through the dense clouds -- reminded me of the jagged ridges on aluminum foil that has been crumpled then laid flat.  The civilization infrastructure did look similar to home with the bridges, highways, and buildings; but the random scatterings of mountain ridges that tore like a knife through the planned infrastructure made the landscape look alien.  And beautiful!  All of these ridges are covered in vibrant green flora!

The clouds were different too, and I'm not sure if clouds are just different here or if it had something to do with the typhoon.  The texture was perfect cotton.  The colors were the usual white with blue shadows, but there was a tint of pink underneath.  The layers were numerous, and I imagined us peeling an onion as we descended.  The thickness of the lower clouds lowered the visibility to nothing.  The runway didn't appear until seconds before we touched down.



Entry Tasks

As much as I planned everything out, it was a huge struggle for me to get from the airplane to this apartment!  And I had the most fun with those challenges!

At the airport, most of the signs have an English translation, but not all of them do.  Scheduling a COVID test took me over an hour to figure out because I thought that I needed to find a tent in a parking lot to schedule the test.  No, I needed to go to the terminal next to the west parking lot exit hallway, not the actual parking lot.  The other tasks were not any easier!

Transit Card Angel!

I gave up on getting a transit card.  I understood that I needed to go to a convenience store outside of the airport, but there was not a convenience store outside of the airport.  After over an hour of searching, I just gave up and paid cash for transit.

But then on my last subway stop, as I'm walking outside, I notice a kiosk that has the word for "transit card".  Feeling like I have succeeded after all, I go up to it and attempt to purchase a transit card.  The machine tells me that I'm an idiot, and I stand there staring at it like I'm an idiot.

Soon afterwards, a young lady walked by me, continued for a while, suddenly stopped, turned around, and stood looking quizzically at me as I stared dumbly at the machine.  Passersby go around us but otherwise ignore us.  It's just the two of us and the machine.

After a few seconds, the lady walks up to me and asks in perfect English, "what are you trying to do?"  I respond that I want a transit card.  To that, she explains that the machine is only for refilling transit cards.  Convenience stores are where they are sold.  She points out that the one next to us sells transit cards.

I thank the lady for her direction.  Then she walks me into the convenience store and proceeds to order me a transit card.  She stands there patiently as they process the request.  Then I have my transit card!

I thank the lady for her help.  She asks me what I need to do next.  I take out my todo list and show her the last thing is for me to get home, but I assure her that I know it's just a short walk away.  She brings up a map on her phone and shows me that it is better for me to take the bus for one stop to get there.

I thank the angel for her help, and she dissolves back into the crowd having completed her good deeds.

I ignore her advice to take the bus and instead walk.  I arrive at my appartment dripping wet.


And now I finally go to sleep.




Thursday, July 28, 2022

South Korea Trip Preparation

 It's almost time!  I will be in South Korea starting next week!

This second pre-trip blog was originally purposed to be a test.  I'm writing this from the Chromebook that I will be using in South Korea.  I need to ensure that everything works, right?

Of course there's a second purpose!  I could've just written "test" for a test, but I am also publishing my checklist of tasks to complete before my trip.  This will help me and hopefully any future travelers.

Travel Checklist

These are the tasks that I need to have completed before leaving for South Korea:  Of course, most of them are done.  I've been on top of things!  :)

  • Ensure that my passport is valid and not expired.
  • Rent an apartment in South Korea.
  • Buy a round-trip flight to South Korea.
  • Get a visa, a K-ETA.
  • Unlock phone so that I can replace the SIM card later.
  • Be fully vaccinated and have a booster shot.
  • Get a rapid PCR test within two days of departing.
  • Download the Q-Code app and enter my vaccine information and test results.

These tasks I must complete after landing in South Korea:

  1. Exchange about $200, enough for the next tasks with extra.
  2. Get a COVID-19 test at the airport.  If done before 6pm, I'll get the results that night.
  3. Pick up my SIM card from KT Roaming at Terminal 2.
  4. Text my friend so that she has my local phone number.
  5. Buy a transit card and put 50,000 원 on it.
  6. Take a subway to my home in South Korea.
  7. Get a KakaoTaxi account for future convenience.
  8. Quarantine until I receive the test results from the earlier COVID-19 test.
The next day this is what I need to do first:
  1. Exchange a few hundred more USD to 원, but use a place with a low exchange fee.

Friday, July 1, 2022

2022 South Korea Trip Prelude

I will be on the other side of the world for the month of August.  I fly out of Memphis early August 1 and won't return until September 1.

South Korea is my destination.  I will be traveling alone with no tour guide.  I only know a few Korean words and phrases.  This will be a very challenging trip, but I think it will also be rewarding.

The theme of the trip is EXID, and many of the activities are inspired by them.  However, I want to fit more into my schedule to make the most of this opportunity:  visiting tourist spots to learn more about the country, and hanging out with my (current and future) friends are also on the agenda.

Home Base

I will be staying at The Sweet Castle in Gangnam for most nights of my trip.  I will mostly be touring around Seoul, but I do have travel plans to Busan, Namyangju, Gwangju, and other cities too.  The Sweet Castle in Gangnam will be my home base.

I have given my mom and sister contact information of a couple of my Korean friends.  If I need to be contacted, they should be able to help with that.

Travel Blog

I want to do a daily blog of my travels.  Stay tuned for that content!


Wednesday, November 28, 2018

Easy Peasy Money Management Plan

This isn't something that I would normally share publicly, but I'm hoping that it will benefit a few people who really worry me too darn much!

The method below is how I manage my finances.  I learned it through trial and a lot of error.  I'm told I'm pretty good at it nowadays.  Well, this is how I do it.

Benefits:

  • No worries about daily living expenses.
  • The math is simple.
  • A buffer is built in to handle mistakes and emergencies.

Prerequisites


Before we really begin, you should know that this method won't work for everybody.  Years ago, when I was making $300 a month, this method could not be done.  However, if you meet the requirements listed below, it will work for you:
  1. Two weeks of pay should cover the roof over your head.
  2. Three weeks of pay should cover both the roof over your head and basic living expenses.
If your debts, frivolous activities, and other expenses don't fit into the first three weeks too, then that's okay.  At the end, they can fit within four weeks.  Or, you can do what I do and make sacrifices to fit all bills into three weeks and have a full week's pay for other stuff.

It's all about the budget


Worry about budget usage, not bank account balance.  If I go out partying every night at the beginning of the week, that uses up my "partying budget."  I still have money for food and rent, but I can't go out partying until the next month.

Never sacrifice one budget to pay for another.  If my light bill this month is half of what I expected, I still can't go out partying if I've used that budget up.  I feel like this is where a lot of people will get tripped up.  Your budgets are hard monthly limits and can never be negotiated.

Always ignore extra money.  Extra weeks in a month that give you more pay aren't considered in your budget.  You can't spend it.  Extra money goes into your bank account and is ignored until "a rainy day."  (More on this later.)

All needed living expenses should be covered by week three.  The fourth week can be divided up however you want after the goals (scroll down) are met.

Easy Math -- Pitted Against You


Round up for expenses and down for income.  A $123.75 bill is considered to be $150.  A $310.80 paycheck is considered to be $300.  The bigger the number, the more you should round it.  You'll get a feel for what works.

For income, every month has four weeks.  For bills, every month has five weeks.  If you make $300/week, then you actually make $1200/month.  If you spend $10/week on gas, then you actually spend $50/month on gas.

Your bills that change every month are considered to be the maximum.  An electric bill that ranges from $45 to $75 throughout the year is considered to be a steady $75.

By following the above rules, you end up with extra money.

Getting Comfy


Getting comfy doesn't happen overnight.  Most people have debts, and few people seem to have money stashed away for emergencies.  To get comfy, meet the goals below by using your fourth week's pay.  I've listed the goals in order of priority.

Make Sacrifices


Until you meet all of the goals below, cut out as many extra expenses as you can.  Actually, you may realize that you don't miss something after it's gone.  I still don't own a TV even though I've been able to afford one for years!  ;)

Debt payments should be no more than half a week's pay.


At first, you should pay down your debts if the minimum payment is more than half a week's pay.  Pay them down as quickly as you can.  You'll get there.

It is a good idea to have some debt to build credit, so don't worry about paying all of it.  Just get it to a manageable state.  Do not pay more than a week's paycheck to do this though.  That money is needed elsewhere.

Have a buffer that covers the most important expenses.


A buffer comes in very handy for unexpected expenses or mistakes in budgeting.  I've found that the best amount is just enough to cover rent, utilities, gas, and cheap food.

Put money into your checking account until you can cover this for a month.  This is your buffer.  Then keep putting money in until it never drops below that amount.

Lastly, save up three months of pay.


After your debts are paid down and you have your buffer, start a savings account.  Put money in until you have a full three months of pay.  If you lose your job, you have at least three months to find another good one.

Be Comfy


Now you are very financially stable.  You have low debt, a good buffer, and a substantial savings account.  Money is not a worry because you can cover all of your bills so long as your stick to your budget.  But what do you do with that extra week and more of pay?

Ignore the fifth week.


If you make more money in months with five weeks, ignore that fifth week.  It goes into your savings account.  Don't try to budget it.  If you do, you'll end up with nasty fractions in your math.

Budget the fourth week however you want.


It isn't all just extra money that you can throw around.  You should budget this too.  You decide what you want to spend it on.  I budget $50 on visiting distant family and friends, $100 on stupid stuff, and the rest goes to my savings account.  You may choose to budget some of it for a television service.

Prune your buffer.


Over time, you'll notice that the buffer in your checking account grows.  Prune it down to the limit you set by transferring the extra money into your savings account.  I tend to do this every three months or so.

Enjoy the rainy days.


Over time, your savings account will grow.  Always keep three months of pay in there, but any extra can be used for a rainy day.  I'm saving up for a vacation next summer.  Alternatively, you can use it as an investment into a new business in the hope of making more money.

Hard Numbers


Well, not so hard numbers since I don't share my salary with anyone.  I am fine with speaking in terms of budget, so here it is for your reference:

$100/week: food and going out
$50/month: visiting distant family and friends
$100/month: stupid stuff
$XX/month: savings account

And that, my friends, is all that I consider.  I don't worry about rent, gas, and living expenses because I know that's covered.  And if I have to buy new tires for my car, I don't worry about that either because it's covered in my buffer.

Saturday, September 29, 2018

Information Security

In my line of work, I have to know a lot about information security. My focus is more on software and websites, but some of my coworkers set up secure networks and workstations. Yet even when everything is done correctly, that security may still fail. In most cases, the weakest link turns out to be the users.

I've organized this post for easy skimming if you want to just read the bold text.  Or, you can dive down into the details and hopefully gain a little more understanding.

Everything can be hacked.


The question isn't whether something can be hacked—it's how hard it is to hack. A flower shop computer is definitely easier to hack into than a nuclear reactor, but both can still be hacked if you know how to do it.

Your goal should be to make it very difficult to gain access to your data. The inexperienced hackers should not be able to figure it out, and the experienced hackers should not consider it worth their time. If you're storing government secrets, you will want to go even further, but that is not within the scope of this blog post.

Find a trustworthy tech person.


Even if you know a thing or two about computers, find someone whom you can trust for tech support. And be sure to make it worth their while to help you when needed.

Be sure that you can trust them.


You may have to give a tech access to your data for them to fix something, so trust is very important here. I'd recommend going with someone experienced, because experience will tell them that they really don't want to know what you have on your computer.

Dont' jump between multiple techs.


Each additional person adds a potential point of failure. Keep the circle small.

Secure your own computer.


The news mostly reports about websites and databases being hacked, but most of the data breaches I've seen first hand have been on personal computers. Make sure that your computer is not the weakest link.

Keep your computer updated.


Never turn off automatic updates, and routinely update the software that you use. As security holes are found, they are fixed. You want the latest fixes.

This also includes your virus protection software. Make sure that it is updated regularly so that it knows about the latest viruses.

Never turn off your firewall.


If your "trusted tech" tells you to turn off your firewall for more than a few minutes, then call them stupid and find someone else. It's okay for them to turn it off for a minute to diagnose a problem, but it should never be turned off permanently.

Be careful opening files that you didn't create.


Programs are dangerous, Word documents are questionable, and pictures are only usually safe. I say "usually" because it is possible to put a virus into any type of file. Some are easier to do this with than others, so the easier ones such as programs and documents should be given an especially thorough looking-over.

If you do not trust the person who sent you the files, or if anything looks suspicious, then don't open it until you've verified that it is safe. This can be handled a variety of ways, including: talking to the person who sent it, conferring with your "trusted tech", or simply deleting the file.

Regularly back up your files.


Even if we are super careful, we may still get into trouble. As a backup plan, you should regularly backup of all of your important files. Not only is this a good idea from a security perspective, it is also a good idea from a data retention perspective.

Surfing the 'Net


You can go overboard with security by using VPNs, proxies, and other tools, or you can just accept the fact that some websites just aren't very trustworthy. I prefer to go with the later and follow a few simple security rules.

Be careful what websites you visit.


Websites that are taboo seem to be the worst about being malicious. I'm not sure why, but it's almost as if the people who make such websites don't have very high morals.

Even websites that aren't about taboo topics may be malicious. If you don't know the website, don't trust it. You may still want to visit it, but don't enter in any of your personal information or passwords.

Get an ad blocker.


Usually, the website has little control over the ads that it serves, and some ad platforms aren't very secure. Using an ad blocker will block a lot of potentially harmful content. As an added bonus, you get legitimate advertisements blocked too!

Do not trust tech support popups.


The #1 most common way that I see people infected is by calling fake "Microsoft" because of a popup when they visited a malicious website. Instead of calling the number on the screen, call your "trusted tech" that I mentioned earlier.

Pay attention to what your browser says.


Most popular browsers will tell you in the address bar whether a connection is secure. If the website is not secure, then do not enter any sensitive information on that website. Also, if your browser stops you with a big red warning screen, that means stop and close the tab.

Social Networking


While most popular platforms are secure, they usually do sell our data. Those third parties are the weak point. A chain is only as strong as its weakest link, so these super-secure systems may not really be so secure after all. That's okay so long as you keep it in mind.

Do not share any secrets.


Not only do your friends talk, the social network does too. If you don't want something to be public, then do not share it on a social network. It will be seen by more people than you intend to see it.

Your legal notices do not work.


I see a lot of posts that go something like, "I do not give Facebook permission to share my data." People expect for that to be legally binding, but it's not.

For such a text to be legally binding, all parties must intentionally agree to it, and there must be a record of such an agreement. I've never seen Zuckerberg comment "I agree" on such posts, but I guarantee you that all of us checked "I agree" while setting up an account.

Disclaimer: While I've done my research on this topic, I am not a lawyer and this is not legal advice. Consult a lawyer if you're serious about wanting to press this issue.


Be careful what third parties you allow access to.


Those "Sign in with [whatever]" buttons are very convenient! I no longer have to create an account for every service that I use. But they come with a downside – you are giving a third party access or control of some of your data.

On all popular social networks that have this feature, you can review which third parties have an access token and what data is shared with them. Review this and revoke access to the ones that you don't want on there.

Emails


Emails are not secure. We've been throwing technologies at it for years to improve its security, but it still sucks as a secure medium. Still, the convenience of it may be worth it if you're careful.

Verify unknown senders or emails.


If you receive an email from someone's "other" account that you haven't seen before, call and verify that it's them. If you receive an email that it doesn't make sense for you to have received, call and verify that they sent it. Or, just delete the emails if they don't look important.

Encrypt or don't send sensitive information.


If you want to leave your key under the doormat, that's fine, but don't be surprised when a robber finds it. It's the same concept here. If you do not encrypt sensitive information sent over email, then don't be surprised when a hacker gets it. I use this analogy because it's really up to you whether to go with convenience or security.

Be careful of attachments.


Every time that you open an attachment, you're at risk. Even if you trust the sender, who's to say that their computer hasn't been compromised. Weigh the risks, consider the convenience, and decide whether to gamble with your security.

Is it worth it?


As a software developer, it is my job to protect computer users. My aim is for my creations to never be the weakest link, but I can never dictate what else the user may have on their computer or how they may use it. Sometimes it feels like a losing battle, but that isn't how we should look at it.

With computers, we can do so many incredible tasks that we couldn't easily do before. The cost is a little bit of security. Is the benefit worth the cost? I think that it is. We just need to be aware of the risks and take appropriate precautions.

This is by no means an exhaustive list of precautions that can be taken, but I consider these to be some of the basics. I hope that this helps some of you to be safer on computers so that you can continue to enjoy that very useful technology.

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;
    _readContents()
    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!");
    _parseConfig(f);

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
cmd.ExecuteNonQuery()

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.