Tarsnap email confirmation bypass
daemonology.netThe 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.
This goes to show how useful it is to share your knowledge. You never know when you might need it back. :)
That's happened to me, but unfortunately I've mostly found my old questions, not my old answers!
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?"
Heh, I was helping a colleague with some question, and I wasn't really sure about the answer, so we Googled and checked out the top hit on StackOverflow. Wound up being a question that I had answered a couple of years earlier, and forgotten the answer in the meantime.
I've actually done the next stage: researched a problem, found a really helpful Stackoverflow answer, which it turns out I had written, which was a reply to a question which it turned out I had also written.
The only disappointing thing being that due to causality constraints, I was unable to upvote past me's answer or further past me's question, which was a shame as they were both really useful.
Yes, and it is weirdly unsettling too... seeing how you used to phrase things differently.
I've gone back and referred to this (Emacs code browsing tips) http://www.kirubakaran.com/articles/efficiently-browsing-tex... many times. Definitely helps to take some time and write. Even if you aren't helping anyone else, you're definitely helping yourself. https://sites.google.com/site/steveyegge2/you-should-write-b...
In my case this is complicated by the fact that there's someone else with the same name who has both significant professional overlap and a similar writing style. There are a couple of times I've been half way through an archived mailing list post wondering how I managed to forget an answer so completely before scrolling down far enough to see his .sig at the end.
That's been occurring to me for a while with SO questions. I get about halfway through and begin to recognize the writing style. :)
I have this with stackoverflow sometimes :p
Same here. Also my old blog posts.
My weirdest one was when I was searching for an answer to a progamming question and ended up finding (and then contacting) my "long lost" cousin (the name was fairly unusual).
Turns out he became a programmer too.
This has happened to me more times than I would like heh. Makes me realise the fallibility of memory.
Ha, this actually happened to me just yesterday believe it or not. :D I looked up something and turns out it's 21 years old me who asked it in Stackoverflow four years ago.
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.
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.
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.
Code can only tell you about the implementation - never the intent. Taking an example from my code yesterday:
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.$config->{template} = $container->template;(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.)
> 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.
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).
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 //... }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).
The surrounding context is "read in this faux-XML file". I could paste the whole method that parses the file but that line would still make no sense without an explanatory comment about the lack of spec (there's about 2x as many lines of comments as code because of this) and that some files have a duplicated `template` key but some don't and all the code which uses the `template` key assumes it's in the `config` section.
Names are comments:)
But I agree with your overall point.let thisIsAString = 1This is a great point, actually. And I have seen examples of it in code bases using Hungarian notation.
In practice, though, I think this kind of "lie" both happens and persists less frequently than comments that "lie" either by inaccuracy or obsolescence. People naturally have a lazier attitude toward the upkeep of comments ("they don't really affect the code") and somehow an inaccurate variable name seems more brazen than an incorrect comment.
There are definitely cases where comments are required to describe intent...the "Why?" of the code.
But the problem with comments is that they'll inevitably get out of sync with the code. And a wrong comment is far worse than no comment at all.
In a case like Colin's, I think something as simple as including "secure" or "secret" in the name of the variable would prevent this stuff from happening. If your variable is named `secureAccountCode` then it's unlikely you'll be silly enough to render it back to a hidden input (unless you're writing code comments for "Drunk Me" like the Disqus commenter on the article, in which case all bets are off).
There's a classic Joel on Software article about this, "Making Wrong Code Look Wrong" [1]
> But the problem with comments is that they'll inevitably get out of sync with the code.
Eek, then by all means take comments seriously and change them when your code changes. I think it's particularly important to comment functions and methods (especially effectful/stateful ones) with what precisely they're expected to do, what invariants hold, etc. (insofar as the type system and function name don't make these clear). Otherwise another programmer has no way (aside from looking at and completely understanding every call site) of knowing what bits of the functionality are incidental vs intended behavior, and are likely to make small modifications for their own purposes which break other things.
Programmers seem very eager to lack of comments and I'm super unsympathetic; this is the one thing that just kills me. Comments hold together a codebase, make it much easier to learn and read, and are a way for programmers to impart all sorts of bits of knowledge about the domain that is valuable "we would do X here but foo() from library Y works in such and such a way so, blah blah blah". And if you don't like to read comments like that I'm sure your editor will fold them for you.
Agreed with zimpenfish; it's a nice sounding adage, but often we have to do things in code because of non-local reasons. We have to adapt to formats we don't control, or edge cases elsewhere in the system, and there's just no way to embed in the variables and function names that the consumer of this data expects quotes stripped off of strings, so we had better do it here.
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.
I love that colin got trapped by his weirdly pedantic obsession with Canadian invoices. I hope the next bug involves picodollars.
What you call a "weirdly pedantic obsession" is me trying to not break the law.
> 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 ) 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.
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".)
Comments can easily get out of sync with reality
This may be true, but I find that every other form of documentation becomes out of sync with reality even more easily, and/or is not in the right place to be noticed when some code is being edited.
Does he mean "token" instead of "cookie"?
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.
> 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.
Yes, HTTP cookies are so named because they're... well, cookies. The concept is more general and was around long before HTTP though.
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.
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...
Quite the opposite, it's nice to see someone put some effort into their write-ups. It's so much more readable as a story.
Oh it really is just a summary, and no commentary as to whether TFA was long-winded or not. That's left to decide for each individually.
When you write tl;dr followed by a very short summary, doesn't that itself imply that the article was long?
tl;dr has also become a general shorthand for a summary.
It's almost an abbreviation for summary!
The summary was certainly shorter than the article!
Maybe the guy who found the bug won't get $1000, according to your rules, but he definitely deserves a cookie.
Please don't turn this place into a pun-fest.
I did pay out a bounty of $200 for this.
thankyou x