3

I am trying to prevent something similar to this from happening:

http://hackingdistributed.com/2014/04/06/another-one-bites-the-dust-flexcoin/

Basically the financial exchange was using non-ACID transactions and multiple requests sent very near in time to each other could result in duplicate withdrawals, or something of this nature.

One preliminary question I have is, what is this vulnerability termed? A timing attack of some sort?

Here is my setup:

I am setting up two tables, one for a payments queue (ie pending payment to be withdrawn), the other for a payments history (ie a receipt after the payment queue item has been withdrawn).

My processing flow consists of finding the payments queue by id, doing a bunch of asynchronous stuff, processing a payment, then creating a payment history object and deleting the payment queue object.

What are some strategies in regards to the process flow I could implement to make sure that if a user attempted to access this flow twice in a row very quickly, there would not be duplicates, or any similar problems?

I have considered that before starting the process I could delete the payments queue object, therefore with ACID transactions that would guarantee that the process could not be duplicated in a timing attack, correct? Is this the best way to do it?

ROCK
  • 96
  • 6
  • 1
    I think asking how to secure a multi-threaded app may be too general a question to answer on this site. Do you have a specific question? – Neil Smithline Jan 03 '16 at 04:39
  • is there a way for me to prevent a user from accessing request, which initiates a database query, very quickly multiple times where afterwards I am doing an asynch operation before finally modifying the database, to make sure the payments are not duplicated by such requests. I considered sql locking, but the postgre docs said it does not apply for reading. – ROCK Jan 03 '16 at 04:50
  • Basically: read queue-> do asynch stuff -> write payment balance and delete queue. How can I make sure that after the read, the user is blocked from doing the rest of the request until after this current request is finished, in case the user does it twice in a row and the asynch code has not finished so the document can still be read and the balance is modified twice. The only thing I can thing of besides have a special field in the document to check for when reading initially, and to modify it before doing the rest of the operation, would be to just delete the document at the beginning – ROCK Jan 03 '16 at 04:53
  • I guess I have answered my own question, but I would be interested if there are other solutions or more information about this type of attack. I guess it is technically categorized as a timing attack probably. – ROCK Jan 03 '16 at 04:54
  • This is sounding more like a programming question than security. I wonder if it should be migrated to stackoverflow.com. – Neil Smithline Jan 03 '16 at 04:58
  • It is basically only possibly because of asynchronous code between ACID operations or a non ACID db like mongodb, in the example provided. – ROCK Jan 03 '16 at 04:58
  • Usually, a timing attack means something different: https://en.wikipedia.org/wiki/Timing_attack . ... Your linked problem boils down to a programmer not being good enough to make financial software, the solution is to replace the programmer. It's no awesome attack for some tiny hidden bug somewhere, it's the lack of understanding anything about synchronization [partially caused by companies not willing to pay a good programmer] – deviantfan Jan 03 '16 at 14:53
  • Yes, I have definitely stated that I am not sure what to call this, I mentioned the phrase because it is sort of similar to some timing attacks I have heard of in javascript. I guess what you're saying is this is just a general vulnerability, fair enough. I am the programmer here, as I stated I have a few primitive ways I could prevent this, I am mainly wondering if there is a best practice for this situation for locking user access temporarily while an asynchronous request finishes. I probably should have phrased it like that instead of the example, but then it would not have enough details. – ROCK Jan 03 '16 at 23:55
  • Perhaps there is no answer as to what a general purpose method of locking the operation from multiple requests is. – ROCK Jan 03 '16 at 23:57
  • What's your RDBMS? Postgres supports something called `select... for update` that might solve the problem. – ruipacheco Jan 03 '16 at 12:59
  • Yes I am using postgres. I will read about that thanks. Im not sure if it will help me though, is it possible to use this to both select and delete in one query? Otherwise I assume I just use a transaction – ROCK Jan 03 '16 at 23:58
  • 1
    I ended up using a postgre transaction to select a row where column "locked" is false and simultaneously update the column "locked" to true, – ROCK Jan 05 '16 at 02:52
  • In hindsight I think this is termed "race conditions" – ROCK Jan 07 '16 at 18:22
  • @Globlee Yes, this is a race condition. – deviantfan Jan 09 '16 at 00:08

0 Answers0