Bitcoin Forum
May 06, 2024, 05:19:17 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Warning: One or more bitcointalk.org users have reported that they strongly believe that the creator of this topic is a scammer. (Login to see the detailed trust ratings.) While the bitcointalk.org administration does not verify such claims, you should proceed with extreme caution.
Pages: [1]
  Print  
Author Topic: Fix for manual payout bug for mmcfe (greedi version) - for those who need it  (Read 660 times)
fcmatt (OP)
Legendary
*
Offline Offline

Activity: 2072
Merit: 1001


View Profile
June 20, 2013, 06:34:13 PM
 #1

The manual payout option for mmcfe has a bug that could allow an attacker to make multiple submissions to it in a very short
amount of time. The current code might allow multiple payouts. Here is my fix.

I assume you are running your payout.php script from cron every 60 seconds.

Create a new column in accountBalance called Being_Paid_Flag . Make it an INT and verify it defaults to 0. It should.

Make a copy of your original accountdetails.php for a backup.

Edit the file and and look for this chunk of code:

Code:
                                if($isValidAddress){
                                        //Subtract TX feee
                                        $currentBalance = $currentBalance - 0.1;
                                        //Send money//
                                        if($bitcoinController->sendtoaddress($paymentAddress, $currentBalance)) {
                                                $paid = 0;
                                                $result = mysql_query("SELECT IFNULL(paid,'0') as paid FROM accountBalance WHERE userId=".$userId);
                                                if ($resultrow = mysql_fetch_object($result)) $paid = $resultrow->paid + $currentBalance;

                                                //Reduce balance amount to zero & make a ledger entry
                                                mysql_query("UPDATE `accountBalance` SET balance = '0', paid = '".$paid."' WHERE `userId` = '".$userId."'");

                                                mysql_query("INSERT INTO ledger (userId, transType, amount, sendAddress) ".
                                                            " VALUES ".
                                                            "('$userId', 'Debit_MP', '$currentBalance', '$paymentAddress')");

                                                $goodMessage = "You have successfully sent ".$currentBalance." to the following address:".$paymentAddress;
                                                //Set new variables so it appears on the page flawlessly
                                                $currentBalance = 0;
                                        }else{
                                                $returnError = "Commodity failed to send.";
                                        }
                                }else{
                                        $returnError = "That isn't a valid Bitcoin address";


Change that chunk of code to look like this:

Code:
                                if($isValidAddress){

                                        mysql_query("UPDATE `accountBalance` SET Being_Paid_Flag = '1' WHERE `userId` = '".$userId."'");
                                        $goodMessage = "You have successfully sent " .$currentBalance. " to the following address: " .$paymentAddress. " Processing in less then 60 seconds";

                                }else{
                                        $returnError = "That isn't a valid Bitcoin address";



Next, find your cronjob script called payout.php. Make a backup copy of it.

Add this to the bottom of the file:

Code:
// Pay users who have Being_Paid_Flag set to 1 in accountBalance then set back to 0 when processing is done //
$resultZ = mysql_query("SELECT userId, balance, IFNULL(paid, 0) as paid, IFNULL(sendAddress,'') as sendAddress, Being_Paid_Flag FROM accountBalance WHERE Being_Paid_Flag = 1");
while ($resultR = mysql_fetch_object($resultZ)) {
        $currentBalance = $resultR->balance;
        $paid = $resultR->paid;
        $paymentAddress = $resultR->sendAddress;
        $userId = $resultR->userId;

        if ($paymentAddress != '')
        {
                $isValidAddress = $bitcoinController->validateaddress($paymentAddress);
                if($isValidAddress){
                        // Subtract TX fee & calculate total amount the pool will pay
                        $currentBalance = $currentBalance - 0.1;
                        $tot_paid = $resultR->paid + $currentBalance;

                        // Send the BTC!
                                // debug
                                // echo "sending: ". $currentBalance . " to ". $paymentAddress;

                        if($bitcoinController->sendtoaddress($paymentAddress, $currentBalance)) {
                                // Reduce balance amount to zero, update total paid amount, and make a ledger entry
                                mysql_query("UPDATE `accountBalance` SET balance = '0', paid = '".$tot_paid."' WHERE `userId` = '".$userId."'");

                                mysql_query("INSERT INTO ledger (userId, transType, amount, sendAddress) ".
                                            " VALUES ".
                                            "('$userId', 'Debit_MP', '$currentBalance', '$paymentAddress')");

                                mysql_query("UPDATE `accountBalance` SET Being_Paid_Flag = '0' WHERE `userId` = '".$userId."'");

                        }
                }
        }
}

Any final cosmetic tweaks to the website explaining this new way of doing things to users.
For example in accountdetails.php you might want to have this text blurb under "CASH OUT" to appear for users to read:
"Minimum withdrawl is 0.50 LTC. Manual payments are processed in less then 60 seconds. Please note: a 0.1 ltc transaction will apply when processing "On-Demand" manual payments"
Tweak if for your needs.


What this does for you is this: When a person tries to do multiple submissions for a manual payout all they are doing is setting the
Being_Paid_Flag to 1. That is all they can do.

When the payout.php script runs it will actually do the payout. This will defeat the attack and is probably the best way to solve
this since http/php is stateless.

If anyone sees a mistake or a way to improve this please post here.
If anyone wishes to throw me a LTC tip: LSLTFCpFX1V3offArHtvEGwtUKVs1H9zCJ
1714972757
Hero Member
*
Offline Offline

Posts: 1714972757

View Profile Personal Message (Offline)

Ignore
1714972757
Reply with quote  #2

1714972757
Report to moderator
1714972757
Hero Member
*
Offline Offline

Posts: 1714972757

View Profile Personal Message (Offline)

Ignore
1714972757
Reply with quote  #2

1714972757
Report to moderator
1714972757
Hero Member
*
Offline Offline

Posts: 1714972757

View Profile Personal Message (Offline)

Ignore
1714972757
Reply with quote  #2

1714972757
Report to moderator
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1714972757
Hero Member
*
Offline Offline

Posts: 1714972757

View Profile Personal Message (Offline)

Ignore
1714972757
Reply with quote  #2

1714972757
Report to moderator
fcmatt (OP)
Legendary
*
Offline Offline

Activity: 2072
Merit: 1001


View Profile
June 20, 2013, 11:57:43 PM
 #2

Bump for sec issue. Could save a pool op coins.
Remember remember the 5th of November
Legendary
*
Offline Offline

Activity: 1862
Merit: 1011

Reverse engineer from time to time


View Profile
June 21, 2013, 12:16:24 AM
 #3

I have the vague feeling I reported this issue a month or so ago. While it is true that the issue is eliminated with cronjobs, it's not instant payout anymore.

BTC:1AiCRMxgf1ptVQwx6hDuKMu4f7F27QmJC2
fcmatt (OP)
Legendary
*
Offline Offline

Activity: 2072
Merit: 1001


View Profile
June 21, 2013, 12:23:40 AM
 #4

I have the vague feeling I reported this issue a month or so ago. While it is true that the issue is eliminated with cronjobs, it's not instant payout anymore.

less then 60 seconds until payout is instant enough. and it avoids the stateless issue and overly complex php code.

and yes, some people knew about it. but not enough in my mind.
Remember remember the 5th of November
Legendary
*
Offline Offline

Activity: 1862
Merit: 1011

Reverse engineer from time to time


View Profile
June 21, 2013, 12:25:37 AM
 #5

I have the vague feeling I reported this issue a month or so ago. While it is true that the issue is eliminated with cronjobs, it's not instant payout anymore.

less then 60 seconds until payout is instant enough. and it avoids the stateless issue and overly complex php code.

and yes, some people knew about it. but not enough in my mind.
Well, I personally like the idea of seeing a tx hash as soon as I click payout.

BTC:1AiCRMxgf1ptVQwx6hDuKMu4f7F27QmJC2
fcmatt (OP)
Legendary
*
Offline Offline

Activity: 2072
Merit: 1001


View Profile
June 21, 2013, 12:28:49 AM
 #6

I have the vague feeling I reported this issue a month or so ago. While it is true that the issue is eliminated with cronjobs, it's not instant payout anymore.

less then 60 seconds until payout is instant enough. and it avoids the stateless issue and overly complex php code.

and yes, some people knew about it. but not enough in my mind.
Well, I personally like the idea of seeing a tx hash as soon as I click payout.

i admit that is appealing but mmcfe never provided that in the first place if I recall correctly.
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!