
Order of Operations - ph0rque
http://adam.blog.heroku.com/past/2009/3/18/order_of_operations/
======
jerf
I disagree strongly with making "security" step 4. By the time you finally get
around to making the app functional you may have fallen into several
fundamental traps that require massive work to get out of the hole.

The vast, vast bulk of security holes are due to simple things that are easier
to get right even in the prototype stage than to retrofit later. Concatenating
strings into an SQL statement is _harder_ than using a proper library for
escaping. Properly escaping HTML isn't that hard if you know what you are
doing _and_ plan for it in advance, but is hell to go back and fix later.
Buffer overflows are easy to avoid today by using secure libraries or
languages in the first place but can be very difficult to fix in an audit
phase. Even things like implementing a basic role/capability system are a lot,
lot easier to implement from the beginning than to try to retrofit, and they
are not hard. If you have some experience and know what you are doing
frequently the right way has been made easier than the wrong way anyhow.

If you are still at an experience level where you still have to think about
how to properly encode an SQL query value... well, charge forward I suppose,
but I promise you, you will pay. There's no way around that.

Concerns with a similar pattern: Handling string encoding. You will come out
ahead if you start out aware of how encoding works and how to handle it,
rather than trying to retrofit it later. Internationalization: If you know
what you are doing, it is not significantly harder to do at least basic
internationalization first (a string table instead of typing a raw string,
with a bit of work you can make it an emacs macro so it costs one whole extra
keystroke per string), and retrofitting it is extremely hard. If you encounter
one particularly hard string, label it in a comment and bail if you're in a
hurry, but you're still ahead for having thought about it and having
everything else set up properly.

If you feel you should object to my point by saying "But those things are too
hard!", you're missing my point. For someone with decent experience, they
_shouldn't_ be. I don't have to think too hard about any of these things even
in my prototypes. (Except encoding, which is hard to think about because it's
a hard problem, even for a prototype, unless you are blessed to be working in
an environment that has a sane encoding story.)

~~~
lsb
I agree that security shouldn't be a last-minute thought, but those are
terrible examples!

If you're prototyping, think at a higher level, and prototype with native
language objects, or if you need to use a DB, use an ORM. Writing raw SQL is
only fast the first time, and then you're no better than assembly-coding your
database.

For string encoding, just take out non-alphanumeric characters, unless you're
dealing specifically with non-English, and then expand your target audience
once you can do it safely. Most blogs, for example, don't deal with i18n in
urls; they just convert any non-alphanumerics (include spaces) to hyphens,
which is safe and easy. Again, that's a simple regexp: in Ruby,
.gsub(/[^0-9a-z]/,'-') . If non-Anglophones sign up in droves, you have a
massive user base, which is motivational inertia enough.

~~~
jerf
"If you're prototyping, think at a higher level, and prototype with native
language objects, or if you need to use a DB, use an ORM. Writing raw SQL is
only fast the first time, and then you're no better than assembly-coding your
database."

Yes, good job, part of my point.

"For string encoding, just take out non-alphanumeric characters, unless you're
dealing specifically with non-English, and then expand your target audience
once you can do it safely."

No, the real solution is to learn what encoding actually entails and learn how
to do it right without a lot of fuss. That approach is actually harder than
doing it right, because it's "only one regexp" in a quick HN comment; in
practice it'll blow up in your face. That's just a panic response brought on
by not knowing what you're doing with encoding.

------
bk
Rather than thinking of these steps as a strict sequence, one should think of
them as parallel processes with shifting resource allocations.

Ultimately, the development process comes down to the experience and habits of
the developer. If you have a lot of experience, your marginal cost of "getting
it right" from the beginning is lower, because you already have the necessary
domain expertise.

For example, if you're inexperienced, you might build a login system that
simply stores plain text with a note to "hash passwords" later. You might then
move through unsalted via manually salted hashing to finally arrive at
something like bcrypt.

