Categories
Programming Technology

Search file contents in UNIX

I found myself having to search through the contents of a bunch of files in Unix the other day, and wanted to find a command to do it for me.

Cue some Googling, and I found exactly what I was looking for here.

find . -name "*" -exec grep -l "somestring" {} \;
Categories
Programming Technology

Badly Formed Maven Project Error

I recently had an error loading a Java project in Netbeans – whenever I selected it, I’d get this:

How to fix

After some Googling, the fix appears to be commenting out the <parent> tag from the project’s pom.xml file.

<!--<parent>
 <groupId>foo</groupId>
 <artifactId>bar</artifactId>
 <version>1.0.0</version>
 </parent>-->

File this under “I have no idea how, but it fixes the problem”.

Categories
Programming Technology

You Shall Not Password!: An Evil Plan

Photo by GandalfWorldTour CC BY
Photo by GandalfWorldTour CC BY

I recently read a fascinating article by Thomas Baekdal about why the password “this is fun” is 10x more secure than “JS4!2” – I highly recommend taking a look at it. His point is essentially that passwords need not trade readability and memorability for secureness. But, although the issue of password complexity vs security is interesting, it seems to me almost pointless to address it until we find solutions to larger problems with password use.

Of course, not that I’m the first (or thousandth) to realise this. As is often the case: the relevant XKCD strip.

The fact is that as long as people continue to a) reuse passwords across different services, b) write them down on paper or c) store them in plain-text files on their computers (a lecturer at uni did this), we should worry less about the inherent security of a password and more about how likely it is that someone will get their hands on it without even having to run any brute force attacks.

To Baekdal’s credit his whole point seems to be that a memorable pass-phrase should negate points b) and c) – but it does nothing to prevent people reusing passwords for different websites, meaning that an XKCD-style plan of acquiring one password and signing in to other websites with the same email/password combination could still succeed.

So what if we lived in a world where noone ever reused passwords? What could an evil genius do to acquire login details for a person’s entire online presence? I had a vision of an evil plan to do just that.

The Plan

Step 1: Create a website and attract people

Preferably, create something you’re not going to have to spend a long amount of time maintaining. That could mean outsourcing your content. I leave that step up to you – how about scraping the link to the top video on YouTube every day and embedding in on www.BestTube.com? Bam, instant 10,000 hits a day. Then spam the appropriate sources – Digg, YouTube comments, whatever.

Step 2: Force users to sign up and log in

Take a business tip from the drug dealers: make the first link free and all subsequent hits require an account. Make signing up as easy as possible! This is valid advice in any walk of web development, but doubly so for our nefarious purposes: we want as many people to sign up as possible. Store the date they joined – that’s important. Also important: do not allow the user’s browser to store their password for them. You’ll notice that online banking already does this – just set AutoComplete to false on your form.

Step 3: Force login failure

Maybe 2 weeks after the user’s signup, start failing their login attempts.

Now if I know people (and I’ve met a few) this will result in Bob retyping the same password once, maybe twice, then switching strategy and trying every other password he knows. Because “Hey, I must have used a different password”. So he types “bob1”, but that results in a login failure too. Huh, maybe “hello1bob”? Failed again. And here comes the crux of the evil plan:

Step 4: Store every password attempt

We now store every password variation which Bob attempts to sign in with.

A certain amount of subtlety comes into play here depending on how quickly you want your results, if you actually care on retaining your users, and whether you care about being found out. Assuming you’re in it for the long haul and you’re clever enough to realise you don’t want to spook your users, you might want to limit the amount of users who you do this to – maybe only target 1 in 5 of your users for this treatment. And maybe only fail the first 4 login attempts, and let the 5th password work (no matter what it is).

By the 5th attempt Bob will very likely click the “Forgot your password?” link (if there is one) anyway. Again, depending on your goals you may want to completely avoid implementing “Forgotten Password” functionality, thereby forcing the user to just keep trying passwords until they give up. You’ll maximise the number of passwords in the short term, but you’ve lost any chance of keeping the user on a long-term basis.

Step 5: Do evil things with those passwords!

Assuming a website attempted this approach, they would then have a nice list of email addresses, each of which had an associated list of passwords which the user regularly used. The evil individual behind this could now run a smarter brute force attack on common websites with a much smaller list of potential passwords – leading, I bet, to a much higher hack success rate.

Conclusion

This whole technique is known as phishing, though typically this sort of approach is done through website forgery and not forcing login failures. Unfortunately I have a feeling this could be a very successful method of hoarding someone’s passwords. In all likelihood, this is already happening, so it’s worth discussing out in the open.

There are a few things we can do to prevent this:

  1. Only sign up for trustworthy websites.
    If a website smells fishy, Google it! You’re very likely to get a good indication of whether this site is all it seems to be within the first 10 hits. If you really have to log in, use a temporary email address and a password you’ve never used before or will ever use again.
  2. Don’t try all your passwords
    If your password has failed and you’re sure it’s not a typo, just click the “Forgot my password” link and wait for the email. At worst you’re losing an hour.
  3. Use a password manager
    KeePass is an example of a great way of storing all your login information in a single file using NFA-approved encryption. All you have to remember is one secure pass phrase (and that’s where Thomas Baekdal’s advice comes in handy) to encrypt and unencrypt the file. So if a website’s login fails even though you’re sure the password was correct, you can always double check with the entry in your password manager. KeePass also has the ability to automatically populate login forms for you if you really don’t fancy remembering anything anymore :p

Throughout the history of the internet, there always have been, and there always will be, clever people trying to get your information on the internet. The only protection is a healthy dose of paranoia, and maybe some high-tech encryption to boot.

Seb


Disclaimer

The steps listed in this post are not provided as a tutorial but as an illustration of the power that any website can have over you. My intention is to inform about the hazards of password misuse, not help others capitalise on it. If I’ve managed to think about it already, so have much smarter people than me.

Categories
Programming Technology

Click it Twice, Shame On You

We recently had an interesting discussion at work about our UI paradigms.

Let’s assume we have an information management system which allows you to create, manipulate and link objects which represent, say, Persons and Dogs.

Person and Dog

Now assume that through a wizard, we allow a user to link a Person to a Dog as an “Owner”.

Person Linked to Dog

Lastly, let’s imagine a scenario in which the Person is already linked to a Dog, but the user runs through the wizard and selects the Person as an Owner anyway. Here’s the crux: inherently, our system allows multiple links between objects. But in this case, our business rules dictate that we don’t want multiple links with the same link reason (because why duplicate the same link? We’re not adding any new information)

So what do we do? We have two options:

Option 1: Bad user! Bad!

The objects shouldn’t be linked more than once, so the user is attempting an illegal operation. Show an error message telling them what they’re attempting is not possible.

Option 2: Uh, everything’s fine!

The target state of our objects is the same as the current state, so do nothing and act as if the operation has succeeded.

I understand the allure of option 1 – it’s a hardliner’s approach to dealing with illegal operations. The user is not only attempting to do something which is not logically allowed (linking twice as an Owner would add no further information to the system), but has already been done. We’re keeping things as simple as possible for ourselves. But in my mind it’s just too hard line. Yes the user’s being a bit daft but why punish them so harshly – they now have to click OK on the error dialog and close the wizard. Two extra clicks and no change in state.

On the other hand, what I proposed was an idempotent approach to our linking mechanism.

Digression
Idempotent operations are functions which can be applied many times over, but which will only make a change the first time. For example, multiplying by zero. If we take a number (say, 1) and multiply it by zero, we get zero. If we then multiply the result by zero again, we still have zero. Multiplying by 2 isn’t idempotent because we would be exponentially increasing our result – it would go from 1, to 2, to 4, to 8, to 16. And our result would keep changing.

In essence then, if a user selected a Person to be linked as an Owner, and they were already linked, we would perform no additional functionality but behave as though the operation had succeeded. The result is the same no matter how many times you link the Person as an Owner.

Some of my colleagues disagreed, and argued that we should never be silently suppressing errors. I agree. But in this case I don’t think we’re suppressing anything; we’re simply choosing not to define what the user is doing as invalid.

Furthermore, let’s think about this in terms of what a user would expect from our system. If they’re trying to do something which will only leave our system in the same state, why slap their wrist?

You’re not punished for trying to turn a light switch off again, or pressing the lock button on your car-key a second time, or double-clicking a link on a website. Because the results are the same no matter how many times you apply the operation.

Categories
Logic Programming Technology

But would they be neighbours like this?

Photo by lorenzaccio* CC BY
Photo by lorenzaccio* CC BY

The “Doors to Heaven and Hell” riddle. It’s an oldie and a goodie. I’m sure everyone’s pretty familiar with it, but in case you’re not here’s a quick recap:

Bad news, you’ve just died. You find yourself in a nondescript hallway with two identical doors, each guarded by a man. You realise you’re holding a scrap of paper. It reads:

1. One of these doors leads to Heaven, one leads to Hell.
2. The man guarding Hell’s door always lies. The man guarding Heaven’s door always tell the truth.
3. You may ask one of them one question.

(Note: You also can’t use any external reference points e.g “Does 1 + 1 = 2?” You have to limit your questions to the men and their situation. Nor can you do a Karl Pilkington and try to trick God into coming to the door to sign for his post)

So if you were to ask them, “Where does your door lead?” the man guarding Heaven would say “Heaven”, as would the man guarding hell (since he’d lie). That would be a bad question, since if you asked either of them, they would give the same answer. The aim of the riddle is to ask a question which is guaranteed to let you know which door leads to heaven and which leads to hell. The good thing is, there is a solution.

The answer is annoyingly simple once you hear it. The correct question to ask is “If I was to ask the other guy what door he was guarding, what would he say?” If you happened to ask the man guarding heaven, he’d know the other guy was guarding hell, and he’d know he’d lie, so he’d say “Heaven”. Likewise if you happened to ask the man guarding Hell what the other guy would say, he’d know the guy guarding heaven would say “Heaven”, so he’d lie and say “Hell”. The answer they give is the answer to which door they’re guarding.

In fact there are several variations of the question which you could ask (E.g. “If I was to ask the other guy what door you were guarding, what would he say?”) Another interesting variation is “If I were to ask you what door you were guarding, what would you say?”. The liar’s process would have to be:

1. OK, I’m guarding hell
2. If he was to ask me what door I was guarding, I’d say “Heaven”
3. But I need to lie about the answer to (2)

And he’d have to say “Hell”. So you’d know he was guarding hell.

The same principle behind each of these questions is the principle of chaining their systems in series. Let’s use some logic gates to show you what I mean.

So a basic NOT gate (or inverter) takes in a value and returns its opposite.

That's not a knife that's a spoon

So 0 goes in, 1 come out. Another way to put this:

Hell goes in, heaven come out. The liar in the riddle is a basic inverter. He is forced to tell the opposite of what he knows is the truth. The truth-teller, on the other hand, does nothing to the truth. The input travels unmolested through his “process”.

Asking one of these guys what the other would say guarantees that we are passing our input through both processes. And we know that one of them is an inverter, and the other does nothing to the input. So with a question structured to invoke both processes, we know the output will be the negative of the answer we really want. And again, in logic gates:

Similarly, my alternative “What would you say if I were to ask you…” example is the equivalent of passing the input twice through the inverter. In other words, the input would exit the process having been inverted twice, thereby having suffered no modifications.

Interesting stuff. And who’d have thought I’d actually find some use for my logic-gate knowledge?

Categories
Programming Technology

Debugging .NET 2.0 apps in Visual Studio 2010

Some guys at work ran into an interesting problem yesterday: since upgrading to VS2010, they found none of their breakpoints were being hit when debugging their apps.

Without giving too much away, my work consists of writing .NET apps which run on top of a custom platform application we’ve developed. These apps are compiled to .NET 2.0. Debugging typically involves setting our platform app as the startup program to debug into, and launch from there. Trust me, this is relevant. Also relevant – none of our developers working on Vista of Windows 7 machines had any issue – just the Windows 2003/XP crowd.

Something about the combination of Visual Studio 2010, .NET 2.0, and Windows XP meant that we could no longer debug into our applications.

P-p-p-productivity breaker!
Why do you hate me, breakpoint?

So anyway, after a bit of Googling, I managed to find a workaround, thanks to this anonymous Microsoft Employee. The issue seems to be that when debugging into code which is invoked from a native exe, Visual Studio will assume you’re debugging in .NET 4.0. Subsequently all your .NET 2.0 code will run, but the debugger won’t hit any of your breakpoints.

The fix is to give the debugger a helpful hint, in the form of a .exe.config file in the directory you’re launching your startup exe from. And in handily numerated form:

1. Find the exact version of .NET 2.0 installed on your PC. One way to do this is to click here or type

javascript:alert(navigator.userAgent)

in Internet Explorer. There are probably myriad other ways of doing it. Note the version down.

2. Create a <YourProgram>.exe.config file in your program’s directory with the following contents:

<xml version="1.0">
<configuration>
<startup>
<supportedRuntime version="v2.0.<whatever you noted down>" />
</startup>
</configuration>

3. Debug to your heart’s content!

Step 3 is essential.

Note that I still have absolutely no idea why the original issue should arise only in Windows 2003 and XP machines. If anyone a) reads this and b) has an idea why, please let me know.