I'm trying to understand the malleable transaction attack, as it seems to me that only a rather careless operator would be vulnerable in the first place, as described below.
Mainly to clarify my own thoughts, let me describe the attack as I understand it. Dramatis personae: Alice is the attacker, and Bob is a "banker" (exchange operator, web wallet; someone who is holding coins on account for Alice.)
Alice: Hi Bob, I have 1 BTC in my account and I'd like to withdraw it. Please send it to address 1Alice1.
Bob: Okay, I've generated a transaction, its hash is 123abc. I've just posted it to the p2p network. It spends output 3 of prior transaction 987def and sends 1 BTC to 1Alice1. Your account has been debited for 1 BTC and your new balance is 0.
Alice: Thanks, I see the transaction. I'll wait for it to be confirmed.
Now Alice constructs a "mutant" transaction, with the same effect as 123abc; it still spends output 3 of 987def and sends 1 BTC to 1Alice1, and the signature still verifies, but the mutant has a different hash 456bca. Somehow, Alice gets 456bca into the blockchain instead of 123abc. Maybe she's just better connected on the p2p network than Bob is, or maybe she bribes Polly, a mining pool operator, to give priority to 456bca. Since 123abc conflicts with 456bca, 123abc will never be confirmed.
Some time passes.
Alice: Hey Bob, remember that 1 BTC I was supposed to get? The transaction never confirmed.
Bob: Let me check. Yes, I see, there's no such transaction as 123abc in the blockchain. Well, I guess you never got your coins; sorry about that. I'll recredit your account; your new balance is 1 BTC.
Alice: Thanks. Now that I have 1 BTC back in my account, I'd like to try again to withdraw it. Send it to 1Alice2.
Bob: Okay, I've generated a transaction, its hash is 246fed. I've just posted it to the p2p network. It spends output 7 of prior transaction 369dbc. Your account has been debited and has balance 0 again.
Transaction 246fed is confirmed normally.
Alice: Gotcha, Bob! Your original transaction went through after all, just in mutant form as 456bca. Now I have both it and the new transaction, and I've just stolen 1 BTC from you. Mwa ha ha!
Bob: Oh, woe is me!
However, it seems to be that this attack requires some rather careless bookkeeping on Bob's part. Even if Bob has no idea there is such a thing as a malleable transaction, he knows he generated 123abc and put it on the network, and for all he knows it is still floating around out there. So I would think that before recrediting Alice's account, common sense should dictate that Bob ensure that 123abc cannot be confirmed at some future date, perhaps by making a new transaction (963dad) that spends the same input (trans 987def output 3) to one of his own addresses (1Bob1), and waiting for 963dad to confirm. Of course, in the current scenario, 963dad never will confirm (because 456bca supersedes it), and Bob will eventually get tired of waiting and investigate further.
Or, alternatively, when Alice asks to withdraw 1 BTC for the second time, Bob's new transaction (678bbb) to Alice should again spend the same input (987def:3), ensuring that Alice can't somehow get 123abc confirmed later. This foils the attack also, because 678bbb has been invalidated by 456bca.
Furthermore, since Alice's mutant transaction 456bca did in fact spend Bob's input (987def:3), shouldn't Bob's client software inform him that this input is no longer available to him, and adjust his balance accordingly? Bob apparently believes 123abc failed and so he still controls that input, and therefore this should throw his books out of balance and alert him that something is wrong.
My understanding is that the Bobs of the world have responded to the issue by complaining that "malleable transactions" are an obscure protocol bug that they couldn't have been expected to anticipate. Whether that's true or not, it seems to me that in order to have been vulnerable, Bob's accounting practices already had to be negligent, so he really has no defense either way.
Or, if Bob saw the red flags but failed to understand the situation, and credited Alice's account anyway in the interests of customer service, it's still hard to feel much sympathy for him.
Is this account essentially accurate, or have I missed some crucial details?
Thanks, and sorry for the length.