Two-Factor Authentication Primer

I recently implemented two-factor authentication into a web app and since it was a new concept for me, I thought it would be good to explain the highest conceptual level of this process.  As with a lot of new things, there’s some terminology to learn and there’s a need to understand how all the pieces fit together.

First, what’s it take to integrate this with an existing profile login?  You need a new database field and a bit of extra code for opting in and out of the two-factor authentication.  Ideally, you’ll need a library for generating a QR code, too.

Before I get too much into it, these are some of the elements of the process.  There are three pieces of data involved:

  • Shared Secret: This element is stored in the database with the user profile and is never exposed outside your application.
  • Secret Key: This is an encoded version of the Shared Secret.  It is given to the user by your application and the user enters it into their authenticator application.
  • Code: The numeric value generated by the authenticator application.  This changes every minute.

In brief, your application and the authenticator application both use the current time plus the Secret Key to generate a Code.  If they match, the user is authenticated.

To implement this, you would modify your user profile page to provide a button to enable two-factor.  When the button is clicked, you create a a random Shared Secret and save it to their profile.  You use that Shared Secret to generate and return the Secret Key.  The user puts that Secret Key in their authenticator app and the opt-in is complete.

When the user logs in to your application, if they have a Shared Secret set in their profile, they are prompted to enter the Code from their authenticator app.  Your application compares that Code to the Code it generates itself, using the Secret Key (built from the Shared Secret).  If it is the same, the user is logged in.

It really is simple.  The only thing that isn’t clear, but can be found with some moderate Internet searching is the URL to embed in the QR code.  That URL is: otpauth://totp/{0}?secret={1}, where {0} is the name of the profile to use (either your application or the user’s username or both) and {1} is the Secret Key.  Authenticator apps allow manual entry of Secret Keys, so if you don’t provide a QR code, it’s still workable, just a bit tedious.

Some of the other pieces you’d need are functions to reset the Shared Secret or clear it, if the user wanted to opt-out.  This is simple user account maintenance.  With a simple implementation, you could blank out the Shared Secret on a “forgot password” action.  With more sensitive data, you may want a second code to allow a password reset.  The big concern is users who have lost their phone or wiped out their authenticator application entries.

Because two-factor authentication is so simple and is such a low-impact to existing user profile data structures (relative to oAuth), plus the fact it can be opt-in, it’s really a no-brainer to add it to your applications.

PHP Hacked Site

While doing a search for something innocuous, I found a search result that was very out of place.  The domain was nothing related to what I was searching for, and the text abstract was, to say the least, spammy.  Although I know you’re not supposed to click things like that, I figure I’m pretty secure, so I clicked it.

I was immediately shown a page that said my download would start in 0 seconds, then I was prompted to download an EXE file.  Uh huh.  I browsed to the root domain and it really was a legitimate website.  So now, I wanted to figure out how this happened.  I navigated to the hacked page and I didn’t get any download prompt.  I went back to the search results and clicked again – I got the download prompt.  Hmmm.  More attempts and sometimes the site would send me to a dead page.

image

I looked very hard at the source code and couldn’t find the script that was being injected, but I could see there was a comment <!–counter–> that was getting replaced with the download redirect.  I did a site search on Bing and found many, many, many pages on their website that were suspect.  Also, I saw actual website pages that were in PHP.

So, I had to conclude that the website had a hacked version of PHP, and if that was compromised, the server could do anything it wanted, including checking for referrers and replacing tags in the source code files.  The best I could do was email them and let them know they were hacked and that they had to have their webmaster fix it for them.

Upon further research, it looks like it was a Joomla exploit from a couple of years ago.  I passed that info along and hopefully the website owners can make the updates needed (and clean up all the extra pages).

SSRS ReportViewer NullReferenceException on Dispose

I recently assisted on troubleshooting an error in a utility application where an exception was being thrown on the dispose of a Microsoft.Reporting.WebForms.ReportViewer.  The environmental conditions were pretty specific, so it’s possible you’d never see something like this in your environment.  But if you do, here’s how you can work around it.

The specific condition is that we have a shared library of code for both desktop and web applications.  One of the functions in that library takes some parameters for an SSRS report and returns a byte array for a rendered PDF of the report.  Because the library initially was used exclusively by the website, the WebForms version of the ReportViewer was used.  As time went on, the library was used by desktop apps and windows services.  That’s when the trouble began.

So, if you are using a WebForms.ReportViewer in a desktop application, you may get this exception when disposing the instance.  Digging into the decompiled code for the ReportViewer control suggested it was because there was no HttpContext available.  For us, the long-term fix was clear: use the WinForms version of the ReportViewer.  In the short term though, adding this line of code resolved the error:

If HttpContext.Current Is Nothing Then HttpContext.Current = New HttpContext(New HttpRequest(IO.Path.GetRandomFileName, "http://www.google.com", ""), New HttpResponse(IO.TextWriter.Null))

This created an HttpContext where there was none before, and the ReportViewer instance was able to be disposed without an error.

In Defense of Whitespace

There is a trend that I’ve been seeing recently that I find somewhat disturbing.  It primarily manifests itself with C# programmers, who also tend to be really indignant when questioned about it.  The issue is whitespace in source code.
When I see a big block of C# code and all the text is crammed into as little space as possible, it is very difficult to read.  This means that it takes longer to figure out what the code.  This means that it takes me longer to do my job, making me more expensive to my employer or client.  What benefit does this have with efficiency?  Further, although unrelated to this post, is the use of significant coding shortcut expressions in C#, which the developers praise as so efficient and elegant, but make the code barely intelligible.
Whenever I ask one of the coders about this, their answer is that whitespace is for people and compilers don’t need whitespace.  That response baffles me because it sounds like they are arguing my point.  The whole point of source code is to be human-readable.  But, somehow in their mind, it sounds like whitespace slows the application down.
Years ago, I read an excellent book, Developing User Interfaces for Microsoft Windows.  Although it’s rather outdated now, it had a lot of good advice in it, and one of the tips was to make use of whitespace for code clarity.  Up until that time, I didn’t pay much attention to blank lines and I had a different indenting scheme then what was the standard.  But then I changed both of these and my code became immediately more readable.
Although it maybe sounds a bit obvious, I demand whitespace in my code because I am  a writer and an avid reader.  I need paragraph breaks to indicate to me when a topic is changing or a new thought is starting.  If you treat writing a program like writing a story, your code will be much easier to understand; and to echo the C# developers, the compiler won’t care.
Aside from the line breaks between methods and between logical code blocks within methods, I like to put all my variable declarations at the beginning of the method.  It introduces you to all the characters in the chapter and gives you an idea of how complex the plotline of the chapter is.  This is also out of fashion with the current declare-just-before-use style.
One of my other structural designs that goes against the current fashion is to put my properties at the beginning of the class instead of at the end.  This is the same structure as a UML diagram, so I’m not sure why that design practice changed.  With methods, I try to put all my event handlers first, then order the methods by their access level (public, friend, protected, private).  Finally, I put methods that are called by other methods later in the class, so if you need to reference a called method, you almost always scroll down instead of up to find the called method.  This is made easier since private methods are last in the class.

Reading this post without whitespace is what it is like to read source code without whitespace.  It sucks.

TFS 2010 to TFS 2012 Express

Last weekend I did a full upgrade on my computers to Windows 8.  Along with that, came the upgrade of Visual Studio 2012 and SQL Server 2012, and Team Foundation Server 2012.  My plan was to have a completely fresh development environment, with no legacy 2010, 2008, 2005 versions.

This was a good plan, but I had one reservation.  In this year, I converted from Visual Source Safe to TFS 2010, and now I was going to have to upgrade again to TFS 2012.  Everyone understands how to manage a big file system structure like VSS, but TFS might be a mystery.  Actually, it’s much easier.  It’s just two SQL databases.  So I backed up those databases and did my full, fresh install.

Now I’m ready to install TFS 2012, but what about my data?  I’d seen many blogs and articles describing the upgrade process.  Every one said, uninstall TFS 2010, then install TFS 2012.  But I didn’t want to have any TFS 2010 bits on the new install.  So in order to get the database instance to restore my TFS 2010 data, I installed TFS 2012, then uninstalled it.  Then I restored my TFS 2010 data into the SQLEXPRESS instance TFS created.  Finally, I reinstalled TFS 2012, selecting the “Upgrade” option, which converted my TFS 2010 data to the new schema. 

Sounds like a roundabout solution but it worked without any problems and without resorting to older product installs.

Adventures In Installing

A pretty common feature in applications is the ability to automatically update when a new version is available.  Of course many designs have been created to address this, from having pre-launchers, to ClickOnce, to web services, to notifications, and on and on.  There’s plenty of ways to solve the problem, each with its own set of benefits and drawbacks.

The design I recently faced was one where the app would launch, check the database for a new version and if one existed, would display a notification, launch the installer and exit the application.  A couple of things were less than ideal with this.  First, the installer would be the standard interactive install, so you got used to hitting Enter 3 times to jump through the screens.  Second, after install, you’d need to relaunch the application.  So I decided to try and resolve these issues.

The first step I thought would be easy.  I would launch the install using MSIEXEC and use the /QR to make the install non-interactive.  This seemed really nice until a bug surfaced where the /QR switch would not perform an uninstall of the previous version, resulting in multiple entries in the Add/Remove Programs list.  This bug was reported back in 2010 and with VS 2012 coming out, I guess it will never be resolved.  With a lot of trial and error, since there seems to be no workaround for the problem on the Internet, I found that the /PASSIVE switch will uninstall the old version, so that was my new plan.  However, with /PASSIVE, there is no notification the install is complete.  That’s fine for now, because I was going to make the app relaunch after completion.

After a lot of study on custom actions, I got the application to launch after the install.  Now I have a problem where the application is being launched as SYSTEM instead of the current user.  This would make the database access fail.  More trial and error, because there doesn’t seem to be any info on this issue either, and I found that when you choose the InstallAllUsers=true option, MSIEXEC runs as SYSTEM, which makes sense since it would need access to write to the All Users sections.  But if you set InstallAllUsers=false, then MSIEXEC runs as the current user, which then would launch the application as the current user and all would be well.  That is, if you’re willing to give up the All Users install.

Spam Gallery–Diliver Your Package

A colleague and I were talking at lunch recently about spam and how clever spam and phishing attempts are getting.  But still, there is still so far to go.  One of the biggest failures of spammers is their sheer stupidity.  If they’re going to use a template from a well-known company, why do they insist on changing the wording of the email?  These people don’t have a grasp of the American English language, much less what professional business correspondence looks like.

image2

Starting with the misspelling in the subject, the horrible grammar continues throughout the message.  The point of the email though, is to inform that one of their trucks “is burned tonight”.  This is not a typical business email.

And this spam email suffers from the same problem as every other one.  How did you get my email address? How do you know the package is mine?  I have to assume that people believe that everyone just knows your email address somehow.  Anyone sending you a package seems to implicitly know your email, since UPS and FedEx are sending me package delivery failure email notices all the time.

Spam Gallery–Traffic Violation

The Spam Gallery is a series of posts that give examples of spam messages, explaining telltales signs of how they are spam.

image_thumb1

I received a series of these emails, as usual with slightly different wording.  The email subject, street name and date varied between the messages.

This has the usual signs of spam: no personal information provided, somewhat unusual language  (“sanction and fine”, “camera shot”), sender email address is not from a domain that suggests an official law enforcement company, and a single available action – opening the attachment.

Some things you would need to ask about the email:

  • How did the “violation center” get my email from my license plate?
  • How do you pay the fine when there is no payment address
  • And most importantly, why is the attachment named “cumshot”?

Maybe the email will catch some people out of curiosity.  Even if you know it’s fake or you know it’s not you, you’re still curious as to what the attachment is.  There’s nothing to be gained by opening any attachment from anyone you don’t know.  If someone walked up to you on the street, handed you a USB drive and told you to run whatever program is on that drive, would it be any more logical than opening an attachment from a stranger?

My, How Big You’ve Grown

image_thumb

There used to be a time when SQL Server was a database engine.  Setup of the product was easy.  You told it where to install, then you set up the service accounts.  Over time, the feature set of SQL Server grew and it became more of a suite of products.  This involved some more installation steps with more information to be gathered.

Somewhere around 2008, a significant change occurred with the SQL Server setup.  It involved pre-install checks, rule checks, confirmations, and other stages that significantly slowed down the install process.  What used to be a two minute wizard is now a process that can easily consume 15 minutes.  Add to the mix the growth of the feature set of SQL Server and the full install could take hours.

Following along the left of this post is a screenshot of the setup process.  We have three rule checks, one before you start, one after choosing the features to install, and one after you configure the features you want to install.  For my install, I chose “All features with defaults” thinking it would be the fastest and easiest.  Nope, I still had to run through all the steps.

The most annoying change to the install process is the rule checks.  Even if everything checks out, you still have to click Next on the wizard.  If it’s all good, why do I need to review it?  As mentioned before, this happens three times during installation.  It’s almost as if the setup program is saying, “Look at how hard I’m working.  See, I made you a big list of everything I did.”  It’s like an employee that isn’t confident of his work and has to document everything he does to justify what he’s done.

The feature growth of SQL Server has become outrageous as well:  Analysis Services, Reporting Services, Distributed Relay, Failover Clusters.  I would be very interested in seeing if SQL Server Express is selected more often just because the feature set is more realistic for most projects.

I am also curious to see if this post’s text is longer than the installation steps for SQL Server.  And I even tried to be more verbose so I could fill space.

And as it turns out, I didn’t write enough and the next post continued right next to the image.  I guess that’s a slight issue with the WordPress theme template.

Spammers Getting Angry

There has been some spam going around for quite a while with an infected zip file attachment sent under the guise of being explicit photos found of you or your girlfriend.  The email subjects and bodies had many variations, but were all pretty much the same.  Some samples:

FW:Why did you put this photo online?

Hi ,

I have a question- have you seen this picture of yours in attachment?? Three facebook friends sent it to me today… why did you put it online? wouldn’t it harm your job? what if parents see it? you must be way cooler than I thought about you man :))))

and

Hey ,

But I really need to ask you – is it you at this picture in attachment? I can’t tell you where I got this picture it doesn’t actually matter… The question is is it really you???.

and

Hey ,

I got to show you this picture in attachment. I can’t tell who gave it to me sorry but this chick looks a lot like your ex-gf. But who’s that dude??.

The emails are somewhat casual, friendly, surprised, or impressed.  But recently, these emails have tried a different tactic, fear and anger.  Look at some of the new messages:

These pictures should be taken down immediately.

Sorry to disturb you …
Why did you have to put these photos online? All the hell is gonna break loose now don’t you understant? Take them down immediately! Don’t tell me you don’t know what photos I’m talking about! Check attachment!

This escalated to:

The criminal investigation agains you has started. Grave privacy violation is a serious thing.

Sorry to disturb you …
Why did you try to break into my FB??? This is the reply from FB support in attachment they idendified you as an attacker who tried to steal my password! Do you know that this is crime actually??

and

You’ll reap just what you sow! You’ll be really sorry about what you’ve done to me.

Hate to bother you …
Do you know who posted these photos online?? This is strange cause there’s your FB acc there. Why did you do it and how did you get my photos?? This is a crime actually do you know?? I put one photo in attachment. We have to clear this thing or else I’ll have to contact my lawer!

Other subject lines:

Let’s put this behind us once and for all  I know you broke into my email.
The police investigation is under way now. You’ll be really sorry about what you have done.
How can you be so cruel to me? I’ll have to react and destroy you.
You can’t say I haven’t warned you  now enjoy the consequences.

While it could be understandable that if written in anger, the email composition and grammar would be terrible, which is normally a giveaway for spam.  But like most spam, these emails play off of curiosity, even if you know you’re not the one the attacker is looking for.  Who wouldn’t want to see the picture that’s gotten the author so upset?  The new tactic is to get the recipient in a defensive or worried state so they confirm that it really isn’t them involved in the fake incident.