You are right. Any web application or service that uses a username/password login system should store its users' passwords using a salted hash, perhaps even a slow salted hash, maybe with a pepper. If this is starting to sound more like breakfast than crypto, don't worry:unlike your password (hopefully), storing passwords securely isn't too difficult a topic. to decipher.
A hash function is essentially a one-way encryption:you convert the plaintext password to a passcode, but there is no key to convert it back, which means you can never derive the password. real pass from the hashed version.
Here's how most secure websites manage their passwords:
With a hash, the app/site never stores your actual password anywhere, and a hacker breaking in will only get a list of letters and numbers that can't be decoded. Depending on the strength of the algorithm, these hashes can be quite difficult to decipher.
However, hashes are not hack-proof. All an attacker has to do is run a dictionary of potential passwords through the hash function and then compare those hashes to database hashes. When two hashes match, the hacker can simply look at which password generated that hash.
To save time and computing power, many attackers simply use a lookup table (or "rainbow table", a space-saving version of lookup tables), a pre-generated table full of words potential passwords and their hashes. You can actually try hashing a plaintext and then use a lookup table on the hash yourself; It is not too hard. Essentially, if your password is common, the hash of that password is probably already in a lookup table. This is a good reason not to use common passwords.
Unlike slugs, salt makes hash stronger. Since the entire hash changes even if a single letter of the plaintext is changed, all a site needs to do to thwart the lookup tables is add additional plaintext to the password before that it's chopped. The attacker will be able to read the salt in the clear since it is stored in the database, but this forces him to recalculate all possible combinations of passwords and potential salts.
Of course, salted hash can always be crushed. Hackers can simply add the salt to the password they are guessing, hash the combination, and wait for the matches to appear – a standard dictionary attack. Given that modern GPUs can make billions of guesses per second, this isn't infeasible at all, but it does make the process a whole lot more boring. Otherwise, brute force attacks are slow but very effective.
Slow hashing algorithms, like PBKDF2 or bcrypt, use a technique known as "key stretching" to slow down dictionary and brute force attacks. This basically involves setting up the hash function to iterate a certain number of times (although this is a bit more involved than just running the same thing over and over again) so that to achieve the correct hash you have to use a lot of Power calculation. If a site does all of this, its security is pretty good.
To be on the safe side, you can also "pepper" your hashes - which hopefully are already salty. A pepper, like a salt, is a set of values attached to the password before it is hashed. Unlike a salt, however, there is only one pepper value, and it is kept secret, separate from salts and hashes. It adds another layer of security to the salted hash, but if the attacker manages to find it, it's not very useful anymore because the attacker can just use it to compute new lookup tables.
Password security has come a long way, and so has the art of cracking that security. Unfortunately, humans are still bad at managing passwords, and databases don't upgrade security as often as they should. In general, assume that whenever you create an account, the password is stored with relatively weak security. If your password is common or a dictionary word, there is a pretty high risk of being hacked. Make your passwords long, mix letters, numbers, and symbols, and you'll help hash functions do their best job.
Image credits:Hash function