Why do so many sites disallow the use of non-alphanumeric characters in passwords? - security

When going through registration, a lot of sites will disallow the use of symbols in passwords. This drives me up the wall from a usability perspective since I include multiple symbols in all my passwords, and as a programmer that deals with web authentication from time to time, I can't figure out why it wouldn't be allowed. Am I missing something? Are they worried about SQL injection? Don't want to deal with escaping characters? Or is there something with non-Latin-alphabet characters that can mess things up?
Similar question, about sites that restrict length here.

Laziness, 2. Using legacy systems that don't support those characters for auth

They are morons
They are almost certainly storing the plain text password somehwere (see 1)

They aren't in the US: In Europe, you have a different keyboard every few miles. Good luck finding your special character on an Italian keyboard. Or a Greek one. Or Turkish.
The only keys which are probably there are the alphanumeric keys and most people will be able to find their way around them, even if a couple of the keys will be swapped (Y and Z, for example).
Lastly, people are notoriously bad at remembering passwords. Forcing them to use "honey" instead of "jh(/&DFA93475" greatly reduces the rate of calls for support ("I can't remember my password...")
If it's a web app, the developers were not really able to make sure that umlauts survive the transfer from the form to their backend. It would be great if all browser would simply send UTF-8 but most backends can't handle UTF-8 without some careful tuning, either.

It probably means they're lazy or not very smart. If you only store a hash, you won't have to worry about character sets, injections, or space. Pretty much what was explained in that other question you gave.

Our system once had to work together with 3rd party hardware which was operated through touchscreen. Their on-screen errr.... 'keyboard', surely didn't had a non-alphanumeric characters, therefore - we ran into quite serious trouble with passwords - clients had to change them.

Legacy Systems Support
I can't say if it is true for many websites, but in many antiquated network environments that use radius or another form of centralized authentication, often you have to restrict your passwords to the lowest common denominator for all of the disparate systems that you are supporting. So if you are supporting password authentication for a poorly written legacy application that has problems with non-ascii characters and that server piggy backs onto the central authentication server, you are forced to limit all of the other servers to the same password restrictions.
Poor Input Validation and Lack of Password Hashing / Encryption
The applications could have had SQL injection issues in the past and over-zealous programmers just disabled all not ascii rather than address the fundamental flaws in their design.
Unneeded Simplification
The developers may want to minimize issues with binary data petering into the password store and are over-zealous in their data validation. Honestly, I think this is the most likely scenario. The programmers may have already taken an ascii-only approach to usernames and just extended the same line of thinking to passwords.

Bad programming, and the fact they're storing it in clear text, I'm sure.

One possible reason: the site's UI is designed by a marketing type or a non-technical product manager. Someone who doesn't understand combinatorics and thinks they actually provide their developers with precise requirements by dictating that the password field must contain exactly 8 alphanumeric characters.

It's possible that the same password will need to be entered via the phone keypad, (1 = 1, A, B, or C).
Realizing that this is terribly insecure, one way of increasing the security would be to lock the account after X bad password attempts. Often bank websites are just a front end for a horribly old mainframe application and can't change password policies.

The reason they require alphanumeric is usually an attempt to prevent SQL injection when passwords are entered. For example:
On some sites you can actually type in:
U: admin
P: ' or 't' = 't
Normally programmers get through this by using programming practices such as parameterized SQL, but I am willing to bet this is why they are doing it.

it's a toe crunching, teeth grinding issue especially when banks do it; however, I think some of the issues are with the ';' and ' ' " ' characters.
Back in the day some programmers, i suspect, thought by forcing alphanumeric characters, that people might forget their passwords easily.

Related

How to detect homographic text, unicode spoofing with node.js

Users can get their own subsites on ours, so that www.example.com/subsite/gary would then be a specific users subsite.
However I am worried about the possibility of homographic / unicode spoofing attacks, where a malicious user creates an account with a different username but with unicode characters that will appear the same to others, and in that way can pass around a link purporting to be gary when it is in fact someone else.
The only solution I've seen to this that looks mature is UCAPI http://www.casaba.com/products/UCAPI/ but I would prefer not to use it, I would like to have something that works with node.js. (to the extent that I would rather implement myself if need be)
has anyone an example where they can check for these kinds of homographic / spoofing attacks with node.js?
You could try using Unicode normalization with String.prototype.normalize which is available in Node.js v0.12, but I doubt that takes care of every possible attack vector.
Use UCAPI — it’s made for your exact use case.
Wait long enough and someone will implement it for you - https://www.npmjs.com/package/homoglyph-search

How secure is the "if" statement?

Regardless of the language I'm always puzzled by the concept of security through an if. All the code I write relies on success of that one line with if statement:
user = getUserName();
password = getPassword();
if (match(user, password)) {
print secret information;
}
Since it's only one line I feel like sabotage can be relatively simple. Am I overlooking things, or is a single if really the best way to do this?
You are right, an if like this is easily hacked. If one reverse engineers this application, you can easily modify a few instructions to skip the if.
There are various options, like obfuscating the executable or adding more complex checks and in add them in various places in your application. But whatever you do, your application can always be hacked.
Best thing is not to worry about it. By the time your application is so good and great and widely used that people are actually willing to put effort in cracking it, you will probably make enough money to protect it better. Until then, it's a waste of time to even think about it.
In the specific case you are showing, if you were really worried about unauthorized people seeing the secret information output by "print secret information;" you would encrypt the "secret information" with the supplied password. This would ensure that only the person who was able to provide the proper password would be able to see the secret information.
There's one thing about IF's that is often overlooked. It's called timing attack. Suppose you have a web application that does comparison based on direct matching of password sent against password stored in the DB (yes, I know that nobody in his mind will store passwords in the DB, but as Cheshire Cat said, "we are all mad here"). Then comparison procedure takes different time depending on whether the passwords don't match on the first character, on the second one or on the last one. While it might seem that the time difference is tiny, it's enough for attacker to attempt to guess the password even across internet, not talking about local analysis. Timing attack is a bit more complicated, than I described, but in general IF comparison is not 100% safe, at least not in all cases.
The if statement is absolutely secure, and can never be the cause of a vulnerability. Vulnerabilities arise from nearly everything else in your code.
It is possible that the comparison operator that you are using is flawed. For instance the == operator employs fuzzing matching where a range of possible values are accepted. This might not be good for secuirty but its hard to come up with a good example, it doesn't really matter for a password. A simple $password==$_GET['password'] should work just fine.
Your if statement could also be relying on bad regular expression such as
if(preg_match('/(.+)\\.js/'.$_GET['file'])){
readfile($_GET['file']);
}
In this case the regex is looking for a .js anywhere in the string, not enforcing it to be at the end.
?file=../../.js/../../../../../../../etc/passwd
(And this vulnerability won me $3,000 in the Mozilla bug bounty program ;)
If this is a server code - this is not a problem, as long as you keep your server secure.
If this is a client code - you are right. Someone can manipulate your code - either the binary file or the memory image (once loaded). However, this is true for any client application. You can only make it harder (by using tools like PECompact + Anti-debug plugin for example), but you can't achieve very strong security.
I'm not sure to understand your question.
Software security techniques are imperfect, and AFAIK they pre-suppose few bugs in the compiler, and a "perfect" hardware (that is, the processor is interpreting correctly the machine code).
I am not familiar (but interested) with approaches for imperfect hardware (except of course by using redundancy or other techniques, e.g. ECC, to detect hardware errors).
There is nothing insecure about one line with an if in it.
If the code is running on your server, what matters is how secure that server is. If an hacker gains access to it, it doesn't matter how complicated your code is, he will be able to circumvent it.
Similarly, if your code runs on the computer of a potential attacker (like a computer game that you want to protect), there is nothing you can do to stop the attacker. You can make his work slightly more difficult, but that's all.
You shouldn't worry about the security of one line, but of the system as a whole. If you make your code more complicated, all you did is introduce more potential for bugs. Using more complicated code is an attempt at security through obscurity, which doesn't work.
If you can't trust your computer to execute a simple if correctly, you can't trust it at all.

PHP Password Hashing in 2011

I'm bringing this up after spending a few hours trawling through a number of posts on SO with regards to the most secure way to handle passwords in PHP/MySQL. Most answers seem to be fairly out of date, as are links that people are directed to. Many recommend md5 and sha-1.
We all know that MD5 and SHA-1 are no longer worth using due to the fact that they have been reversed, and also because there are a number of databases out there that have built up millions of md5/sha1 strings. Now, obviously you get around this with salt, which I intend to do.
I have however recently started playing around with whirlpool, which seems much more secure, and up to date. Would I be right in thinking whirlpool+salt is ample protection for passwords?
I was actually considering something like this:
<?php
$static_salt = 'some_static_salt_string_hard_coded';
$password = 'some_password_here';
$salt = 'unique_salt_generated_here';
$encoded = hash('whirlpool', $static_salt.$password.$salt);
?>
What do you think? Overkill or sensible?
This is probably good enough for most applications.
However, salts become (almost) useless if your DB is leaked -- including the static one if your configuration file is leaked too. They are a good protection against rainbow tables, but nowadays it's easier to use a bunch of GPUs to brute-force a given hash.
IMHO, currently the best solution is to use bcrypt. It's apparently supported in PHP 5.3+, and here's an example of how to use it.
This will be enough (however, there is no sense in static hardcoded salt). And, why not to use SHA256? Whirlpool is rarely used.
It's particularly meaningless to discuss the merits of particular algorithms without a much wider consideration of the threat models and specifics of implementations.
Yes, whirlpool does appear to have some advantages in terms of how effective it is as a hash, but as Nickolay says that may be deceptive and due to the fact it is less widely used. But there are other considerations too - for some purposes storing a 128 character string for each account may be an unnecessary overhead. For everyone it's a question of what the software supports (and some people might want to use the same account record to control access to different systems).
At the end of the day, it doesn't matter how sophisticated your hashing algorithm is:
given a free choice, users pick bad, guessable passwords
users will use the same password for different services
If it works for you - then great - but there is no universal solution.

What real life examples of security by obscurity have you seen/worked with? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Bonus points for explaining how you improved it.
Real life security by obscurity?
The key to the front door is stashed under a rock nearby, or under the welcome mat, or on top of a high railing.
These are all instances of security through obscurity, as in, it is right out in the open for anyone to grab, but most people wont be able to find it without huge amounts of searching. However, a dedicated attacker can walk right in.
Some people like to make their javascript difficult to read (and therefore hack) by using obfuscation. Google is among the users of this technique. At the simplest level, they change the variable and method names to a single inscrutable letter. The first variable is named "a", the second is named "b" and so on. It does succeed in making the javascript exceedingly difficult to read and follow. And it adds some protection to the intellectual property contained in the javascript code, which must be downloaded to the user's browser to be usable, therfore making it accessible to all.
In addition to making it difficult to read the code, this shortening of variable names reduces the size of the javascript code that has to be downloaded to the user's browser. Theoretically, this can reduce network traffic.
Here's an article about Google's obfuscation, and here's a list of available tools.
On a website I did some contract work on I noticed that they were storing double-hashed passwords. From memory, they were storing something like
$encrypted_password = md5( sha1( plaintext_password ) );
When I asked what the purpose of this was, I found out that the guy who wrote the account creation/login script had been reading about dictionary attacks. He figured that no one would ever think to create a dictionary where they hash inputs with md5 and sha1.
I improved the system by adding a random salt column to their user table. I left the double-hashing in though. It doesn't do anything to hurt the security of the system, and to be honest, I thought it was pretty clever for someone who didn't really know much about security to think of this.
Seen: Websites use a complex url to access ajax components rather than actually password protect them such as:
domain.com/3r809d8f09feefhjkdjfhjdf/delete.php?a=03809803983djfhkjsdfsadf
the string has remained constant, the query is random and is designed to stop attackers.
Improvement: Restrict the page to being accessed only from certain IP addresses. Add an authentication string to the query that is a salted hash of the access time.
In a more "real life" example, I don't know if it's intentional or not, but I like the way none of the doorbells in my block have any names on them, and that their numbers seem to have no correlation to the apartement numbers whatsoever. Ie. ring on #25 for apartement 605, #13 for apartement 404 and so on. :)
One vendor we deal with requires us to post the username and password in the querystring in ROT-13 "encrypted" format. No joke.
Security through obscurity is a valid tactic. Plenty of people have turned off replying with version information as a best practice for ftp and apache. Honeypots can be considered an obscured practice, since the attacker doesn't know the layout of the network and gets sucked into them. One high security site I know of assigns their username by a five digit alphanumeric phrase (such as '0a3bg') instead of using logical usernames. Anything that makes breaking into a system more difficult, or take longer, is a valid measure.
Security exclusively through obscurity is bad.
People writing their password on pieces of paper and putting it under their keyboard.
I solved it by logging into their computer with their account and sending out an embarrassing email to the group.
Seen: phpMyAdmin moved into the directory _phpmyadmin
Improvement: Disallowed access from outside the company's network.
Similar to #stech's solution.
Some of the admin pages in our application on the web, check for a local IP subnet range, else display access denied.
Improvement is accessed is restricted to users who are inside the network or VPNed to it.
Back in the old DBase/Clipper days I worked for a guy who developed an application for a friend of his. This friend wanted to have some "secretly" accessible program or data (I don't recall) that required a password only known to him.
The solution, I was told, was that Clipper opened a DOS prompt in the secret directory, with black text on black background colors (some ANSI control characters accomplished this).
The user had to type in the password, but this being input line of the DOS command prompt, the "password" was really the name of a batch file that was then executed.
I once saw a photography website where you could strip some characters off from the photo thumbnail pictures url to get the full version.
Many professional photographer websites use Javascript to prevent people from right-clicking on images to "save as ...". Most of those sites also don't do any watermarking.
I used to surf with referer headers disabled... it's quite surprising how many websites will blow up or flat-out reject you if they don't know where you came from.
One website had a poll and used cookies to prevent you from voting multiple times. You could simply erase that cookie and keep voting. And you could script it all using wget, too.
The example I see of this all the time is something being done in source code that the developer assumes no one will ever see. You see this a lot with crypto-keys in particular, embedded right in the source code. A lot of times it is not even a question of decompiling the code, they could outright just use the library.
The solution is always to teach the developer to assume that someone has the source code and can use it against you.
Going to great lengths to hide software names and version numbers .
Ie. changing Tomcat server name and version to some quotes and random numbers (like 666), changing the name and version numbers of regular javascript libraries like scriptaculous and prototype and so on.
In a current project we're using Google Web toolkit (GWT) and this sneaky little thing compiles Java to javascript (which you have little to no control over) and includes the string "GWT" and version number. Totally unacceptable of course so we'll need to make a script that will run after GWT compile to remove all these references(!).
/admin without password.
Yes I've seen it, it's very real.

What are the security concerns I need to consider while coding?

I know SQL Injection is one... what are the others...
OWASP.org keeps a list. Start with the OWASP top ten.
Others have said this, but...
Essentially all security vulnerabilities come from data. If your program doesn't process any data it's likely to be secure. It's also likely to be pretty useless :).
That leads to what I think is the core concept of making code secure:
Don't trust your data. Ever.
Sanitize everything you possibly can. You can rely on the security guarantees of your platform (for instance, it's highly unlikely that you'll see a classic string based buffer overflow in a managed language like Java or C#), but otherwise you need to validate everything that comes into your application.
Never store plaintext passwords, either. (I can't tell you how many commercial packages I've evaluated for my company which did -- and then acted nonchalant about it when I called them out. My favorite excuse, from a CRM vendor: "Will your end users typically have Enterprise Manager or Query Analyzer on their desktops?")
Here is a list of Top 10 Secure Coding practices. It is as good a start as any. Consider #8, Defense in Depth, in particular.
Massage and filter ALL input to your program before processing.
Never process input without filtering and truncating.
-R
Buffer overflows are the classic if you're writing C, as they often allow the execution of arbitrary code by an attacker.
This is for web stuff but since you left it open ended...
JavaScript injection. If you allow any input from any source that's being outputting somewhere JavaScript could be typed in the input and then when it's outputting (unless properly encoded/decoded) it will output the raw javascript.
You could consider the chapters of this book to be a pretty good checklist...
19 Deadly Sins of Software Security
Simply program defensively. For each function/method/procedure/subroutine consider "What is the expected input? What do I do when the input deviates from that? How can I most easily ensure that the input will not deviate from that." Know your input; know your output. Don't go overboard, but also understand that data in a database might have been compromised. If a particular set of data can be constrained in some particular way then select your data types and variables to play to that. Keep numeric things numeric.
Whenever I see a String object in a program I facetiously ask "What would happen if this string contained the lyrics to Gilbert and Sullivan songs?" Simple if-else checks and premature return statements at the beginning of a function can prevent that sort of thing from wreaking havoc later.
I like to model my system with Threat Modeling Tools. This particular one lets you model different applications and gives you all types of information about what types of threats are applicable based on the model as well as some mitigations and their risks. It also let's you track these risks throughout the dev. life cycle to come up with mitigation plans. It's pretty cool. :)
I second the recommendation for: 19 Deadly Sins of Software Security
It isn't just a checklist, read it to understand many of the aspects of software security. Some are broad items, that let you understand the reasoning behind many of the different security issues.
Avoid sending plain text usernames.
how about verifying user input? For example, you're expecting a 10 digit phone number, but you get "800OHNOES!"
In addition to the wonderful guidance on OWASP, also check out the SANS/CWE.
Sending plain text passwords without first encrypting them is never a good idea.

Resources