In layman terms:
Typical web applications are three-tiered(browser +web server + backend databases). When a user accesses a website, his browser receives html and js which is product of static web pages as well as dynamically generated ones using server side code (e.g. php, asp). When you login, for instances, you send your password and username to the web server, which processes such parameters and applies the pre-programmed authentication logic (in php,asp).Such logic requires verifications using a database that stores users data and allows the simple verification: username matches password. So, the server side logic takes your arguments and queries the database (e.g. MySQL).
SELECT * FROM Users WHERE username='your_supplied_username' AND password='your_supplied_password';
The database processes this and returns (if the database is correctly designed) only one (username and password match) or zero (wrong password) matches which "represent you".
What about SQL Injection Bro?
I am not your bro, bro :P. A sloppy developer would take the parameters sent by you and put them directly on the your_supplied_* fields. If the user wasn't malicious, this would be no problem at all. Yet, for a malicious attacker, this opens a huge door for attacks. If you are familiar with SQL, you know that AND requires both left and right expressions to evaluate to true. Also, in SQLi, the comment character "--" is an helpful friend so, what if i write my_username';--?
SELECT * FROM Users WHERE username='your_supplied_username';--' AND password='your_supplied_password';
Server side code will take my input, apply it to the stringed query and send it to the database. The database will interpret "--" as a comment which will exclude:
' AND password='your_supplied_password';
while keeping:
SELECT * FROM Users WHERE username='your_supplied_username'
This is a valid query which will easily evaluate to true. Now, the behavior here varies. If the username is unique (typically it is), there will only be one record returned. If it isn't, multiple records will be returned and the web server code (e.g. php) will typically pick the first. If you are familiar with SQL, you may now get creative and chain queries, use wildcards and get wild. Now the question is:
As a developer, what can i do?
Now, this depends on the server side language you are using but the coding primitives are typically named alike. You can escape special sequences using php (http://php.net/manual/en/mysqli.real-escape-string.php) or use prepared statements (http://php.net/manual/en/mysqli.quickstart.prepared-statements.php).
How do i know if the server suffers from SQLi?
You can run tools such as SQLMap or SQLNinja. You can also go to the forms and write
'gibberish
where the ' will hopefully confuse the php query parser and leak an error shown on your browser (SQL statement error). There are other techniques such as injecting a sleep statement on queries to check if the database hangs for a few seconds before returning. As a defense mechanism, you should always process your SQL errors on the server side code before sending them to the user to avoid intel leakage.
Stay safe ;)