
Tarsnap email confirmation bypass - mcobrien
http://www.daemonology.net/blog/2015-09-04-tarsnap-email-confirmation-bypass.html
======
caf
The value of writing comments intended for your future self was confirmed in a
strange way for me: I once found myself googling some faintly obscure question
of systems programming, and soon found an article that answered my question
perfectly. At that point I noticed with considerable surprise that I was
reading a web archive of a Usenet posting I had made myself, some 10 years
prior - of all the people to randomly run into on the Internet, your past self
is one of the strangest.

~~~
tome
That's happened to me, but unfortunately I've mostly found my old questions,
not my old answers!

~~~
bentcorner
I've had this happen to me a few times, but usually it's "I've answered this
before for someone else, and now I have the same question. What was my answer
again?"

------
jballanc
There was a paper a couple years ago out of Microsoft research (if I recall
correctly), that looked at a number of vulnerabilities in OAuth as used by
Facebook, Twitter, and a few others. The ah-hah moment for me, though, was
that they identified these vulnerabilities by turning the usual view of a web
app inside-out: instead of viewing the client/browser as one endpoint on a
communications channel, they treated the browser as a _de facto_ man-in-the-
middle. For OAuth, it is responsible for passing along messages between the
OAuth provider and the authentication requesting website. In the case
described in this article, the browser is just a MITM for a server sending
messages to itself.

~~~
sanderjd
I haven't seen that paper, but it strikes me as being exactly the right model.
A lot of vulnerabilities on the web seem to arise from the tension between the
goal to require as little persistent state as possible to serve requests, and
the browser as a public channel that any non-persisted state must be sent
across.

------
jonahx
I love writeups like this, and enjoyed the level of detail Colin provided.

I take away a different lesson, though: even simple web security is easy to
get wrong, even for a very smart, very talented developer. I'm not sure what
the solution is, though.

As for the comments, while I don't take a hard line here, I agree with Bob
Martin's quote: "Every time you write a comment, you should grimace and feel
the failure of your ability of expression." Wherever possible, you are better
off rewriting the code and variable names to clarify _in the code itself_
whatever you wanted to say in the comments. It's hard to say how to accomplish
that here without knowing more about the code, though. And it may have been so
difficult that a comment was the right choice.

~~~
zimpenfish
Code can only tell you about the implementation - never the intent. Taking an
example from my code yesterday:

    
    
        $config->{template} = $container->template;
    

There's not much can be clarified here, I don't think. But it tells you
precisely nothing about why it's required in this instance.

(There's no spec for the file format - all have the `template` key in the
`container` section but some also have it in the `config` section. Since I
can't change these files, I have to deal with the duality. But you'd never be
able to guess that from this code without a comment.)

~~~
jonahx
> Code can only tell you about the implementation - never the intent.

Maybe in some purely technical sense this is true, but in a meaningful one it
isn't. At an absolute minimum, names reveal intent -- which is why naming is
so important.

Regarding your other example, you are always free to wrap what you don't
control in objects that have the intention-revealing semantics (read:
correctly named behavior) that you desire.

It's impossible to tell from that single line of code if there are other
options as well (the surrounding context is missing, and that's where meaning
comes from), but you always have some options. I'll grant that in some cases
the cure is worse than the disease -- that is, the changes needed to truly
reveal your intent in the code would lead to over-engineered complexity. But
typically I find that is not the case.

~~~
MichaelGG
Naming at the higher level is important (type names). But locals, eh, it's
unlikeky that you can comprehend lines without the full context, as you say.
And our working memory is limited. So might as well use 1- or 2-char names and
keep the code less and thus more easily kept in-head. If this is confusing,
there's probably too many locals, so setup new scopes (either by nesting or
via separate functions).

~~~
jonahx
I agree higher level names are far more important.

But I think clarity at the local level is nice, too. Let's say your function
takes a name, sanitizes it, and then does some other processing, perhaps
storing it. I think this makes the code more immediately clear than 2
character names:

    
    
        function storeName(name) {
            safeName = sanitize(name);
            // do other stuff that works with safeName
            //...
        }

~~~
MichaelGG
In that case it's better to rebind name instead of introducing a new binding -
it makes it impossible to misuse it. I hate languages that don't let me rebind
(or sometimes, not even shadow).

------
junto
Lesson of the day: Hidden form values are not hidden from the user, they just
aren't plainly visible to the user on screen.

Never "hide" sensitive data in those hidden input fields.

------
idlewords
I love that colin got trapped by his weirdly pedantic obsession with Canadian
invoices. I hope the next bug involves picodollars.

~~~
cperciva
What you call a "weirdly pedantic obsession" is me trying to not break the
law.

------
paulannesley
> That last part is ultimately the most important lesson from this: Comments
> matter!

In most cases, logically granular commits with good commit messages, and a
knowledge of `git log` and `git blame` etc, is better than leaving comments.
Comments can easily get out of sync with reality (see
[https://twitter.com/nzkoz/status/538892801941848064](https://twitter.com/nzkoz/status/538892801941848064)
) and create a lot of noise that make reading the code harder (especially when
the comment and code contradict each other).

I only leave brief comments where some code is necessary but at a glance
doesn't look right, or has a non-obvious reason. But first I find a way to
make it look right or be obvious.

~~~
MichaelGG
Comments are helpful as an overview of a module, briefly outlining what the
goals and major ideas. I'm currently starting to work on a large project, all
in C, heavily manually threaded, with essentially zero comments. It's open
source so I can't complain, but boy does it make figuring things out
difficult. Especially in C, where so much code is pushing bytes and pointers
around, that there could easily be unintended functionality that might not be
desired.

Getting devs to write separate documentation is more difficult than comments,
and is more likely to get out of sync. Better if they write some general
overview inline. (On the opposite end, I also recently reviewed a project that
has almost no comments, except on calls to malloc and free, with comments "get
some memory" and "release memory".)

------
nchelluri
Does he mean "token" instead of "cookie"?

~~~
cperciva
A token is something you are given so that you can give to someone else. A
cookie is a token where the "someone else" is the person who originally gave
it to you.

I meant cookie.

~~~
nchelluri
> it sends that cookie to you as part of a URL in the confirmation email

This certainly isn't a web cookie in the sense that I'm used to (a cookie
would be a part of the HTTP header, and you can't specify that header in a
URL). It is more like a token as I understand it. Maybe what you are
describing is how the web cookie term was started (based on the behavior of
generating a thing that someone else gives back to you) but it doesn't sound
like a cookie at all to me.

~~~
cperciva
Yes, HTTP cookies are so named because they're... well, cookies. The concept
is more general and was around long before HTTP though.

------
glag0lit
tl;dr

a friendly guy reported to tarsnap that you could sign up without needing the
emailed confirmation link by creating that same confirmation link yourself
with the cookie/token being hidden, but present in the HTML code.

also, there is no bug bounties for the tarsnap website, only for tarsnap code.

~~~
cperciva
_a friendly guy reported to tarsnap that you could sign up without needing the
emailed confirmation link by creating that same confirmation link yourself
with the cookie /token being hidden, but present in the HTML code._

That's a decent summary, but I didn't think I was all _that_ long-winded...

~~~
ninguem2
Maybe the guy who found the bug won't get $1000, according to your rules, but
he definitely deserves a cookie.

~~~
monochromatic
Please don't turn this place into a pun-fest.

------
chloeloubag
thankyou x

