Software Simplicity and Security
Software Simplicity and Security
A developer explains how to create a secure web application using the open source he has created and hosted on GitHub. Read on to check it out!
Join the DZone community and get the full member experience.Join For Free
Any seasoned software architect will tell you that the key to a successful software project is simplicity. This is such a profound truth that arguing against it is meaningless. It implies that the stuff that's not there, can't possibly go wrong. For instance, if you don't create any modal windows, you can't have a bug in your modal windows code, right? However, unfortunately, we can't write our apps with zero lines of code, even though these would be the "perfect apps." But we can still aim for zero lines, knowing we won't be successful, but at the same time realizing that the closer to zero we come, the fewer things can go wrong. With that in mind, let's imagine a specification for a web app.
- It should be possible to create new users.
- It should store its users' passwords and have highly secured settings.
- It should allow a user to log out and log into the system.
- It should allow for incrementally and dynamically updating the client side DOM according to business logic evaluated on the server.
Anyone who knows anything about security knows that points 1, 2, 3, and 4, could easily require months of coding. So before we have even started on our actual problem, we've already spent 6 months coding. Well, let me show you how step 1, 2, and 3 can be easily achieved with a handful of lines of code with Phosphorus Five.
p5.auth.users.create:some-username password:some-password role:some-role
3 lines of code that will create a new user for you, with the username of "some-username," password of "some-password," belonging to the role of "some-role." Of course, the interesting parts are the parts you don't see, or rather, the parts you don't have to create yourself. For instance, the above invocation will create a new user, store the password as a server-side salted hashed value in a password file, that is not accessible for any users but the admin ("root") users of your system. It then encrypts the entire file using a PGP key, which is not accessible from the application level of your app. In addition, it will verify that the password obeys the password rules of your system before creating the user, and if it doesn't, it will throw an exception. The password rules of your system are easily configured by editing a simple regex in your web.config file. Not too bad for 3 lines of code.
Logging into the system is as easy as follows.
login username:some-username password:some-password
Yet again, what's interesting, is the stuff that's not there. For instance, the above invocation contains automatic brute force protection, which will not allow a user to attempt more than one login attempt every 20 seconds, which again (you guessed it) is configurable through web.config. If you want to, you can add a simple "persist" argument, and set its value to boolean "true," at which point a persistent and secure cookie will be created, that will log in your current client for 90 days (yet again, configurable). And if you need a pre-existing GUI for logging into the system, guess what? One line of code:
The above would create something resembling the following.
Logging out of the system is as easy as:
One line of code destroys your persistent cookie, if it exists, and logs you out of the system.
So let's create some simple GUI to create a new user.
/* * Including CSS files. */ micro.css.include /* * Creating a simple button. */ create-widget element:button innerValue:Create user onclick /* * Creating a modal widget asking for new user credentials. */ create-widgets micro.widgets.modal:modal widgets h3 innerValue:New user micro.widgets.wizard-form:wizard text info:Username .data-field:username text info:Password .data-field:password text info:Role .data-field:role div class:right widgets button innerValue:Create onclick /* * Creating user, destroying modal widget, * and providing some feedback to user. */ micro.form.serialize:wizard p5.auth.users.create:x:/-/*/username?value password:x:/./-/*/password?value role:x:/./-/*/role?value delete-widget:modal micro.windows.info:User was successfully created.
49 lines of code, and its result will resemble the following:
And of course, if your user is not an "admin" user or a "root" user, an exception will be raised when you click "Create." If the username exists from before, an exception will occur. If the password doesn't obey the password rules of your system, yet another exception will be raised. And, in fact, you don't even need to create a GUI for your system to create new users. There's already an existing module for that, resembling the following.
So the result is that instead of having to spend months up front, creating things you shouldn't even focus on and that you'd probably not be able to implement correctly without creating security holes, you can start immediately on your "domain problem." So unless your job is to create "authorization and authentication modules," you can jump over point 1, 2, 3 and also in fact 4 from our above specification. Starting out with arguably 95% of your job already done. This allows you to focus on your *domain problem*, rather than the architecture.
I have spent 4 years on the current codebase of Phosphorus Five. Of course, it's not perfect, and I create new features and I fix bugs every day in it, and also sometimes find security holes in it which I tighten. The idea, however, is to create a "starter kit" for you, that allows you to start out your new projects running, not having to think about all the commonalities and commodities you shouldn't have to deal with anyway.
Yup, Phosphorus Five arguably makes "traditional web app development" seem like Assembly coding! And that's its point!
Opinions expressed by DZone contributors are their own.