Membership – Easy subscription price hack

Hi Everyone,

once registered if you firebug paypal subscription button, you can modify the price in the html to 0.01$ and proceed, paypal return the 0.01 payment and membership accept it as good!!!!

Shouldn’t the paypal IPN script check that the price for the subscription matches the price paid??

Please advise…

Thanks

Paolo

  • poltaj
    • Site Builder, Child of Zeus

    Barry,

    this was a big hack years ago, I couldn’t belive this would works for membership, so as a proof of concept, I tried on staypress.com and was able to download my developer copy for only 0.01$

    My site is live and it’s really unfortunate that I discovered this only after it’s release, as now I can’t switch it off for those who already subscribed….

    I’m really really concerned my site could be hacked just like I did with yours and steal my code!

    The paypal IPN script MUST check that the price for the subscription matches the price paid!

    Please advise asap!

    Paolo

  • Barry
    • DEV MAN’s Mascot

    I’ll check in with Barry on this and see if he can confirm the situation with StayPress.

    Hi, you’ll probably notice that staypress has blocked you completely and flagged your account. Pity you didn’t let me know you were going to try it out as our dear Ciaran has just put in a fraudulent account report into PayPal.

    But thanks, I’ll check – I moved a lot of the additional code over from the staypress customisations to the latest version

  • poltaj
    • Site Builder, Child of Zeus

    Barry,

    I tested on staypress because is the only live site I know using membership (and I know it’s yours, so it should be secure).

    This is the normal process for testing a bug, if you check anywhere you will see proof of concept.

    How was I to know it was not just some custom code or a setting i had missed.

    To see if that security issue had really been overlooked, I had to go all the way through with paypal, as normally paypal IPN script should check that the price for the subscription matches the price paid.

    This is something that has been around for a while now….

    I have deleted your staypress files and have not intention of using them.

    Instead of reporting the bug I could have publish the news all over the web and create you a lot more

    troubles… for both staypress and wpmu dev!

    Rather than a paypal fraud report, I would expect some apologies!

    I want to work with you to fix this bug, my business totally relies on your plugin to operate…

    You are exposing me, a paying member of this site, to serious fraud by anyone with firebug installed.

    Please let me know if you can solve this quickly or if I have to do it myself, getting someone involved to help me… which would cost me extra money!

    Thanks,

    Paolo

  • Barry
    • DEV MAN’s Mascot

    Unfortunately they have an alert system on Staypress. As they didn’t know you were “helping us out”, they did what they do with all hack / fraud attempts and report them to the authorities.

    Sorry, but it’s something you should consider when hitting live sites.

    To see if that security issue had really been overlooked, I had to go all the way through with paypal, as normally paypal IPN script should check that the price for the subscription matches the price paid.

    You should have set up your own sandbox / proof of concept site and ran local tests and reported them, as is I’m investigating because the membership plugin certainly shouldn’t be letting this in and will be getting a fix out asap.

  • poltaj
    • Site Builder, Child of Zeus

    Hello everyone,

    looks like we care about this plugin’s security more than anyone else.

    Our site (GeoTheme) is live since a couple of day and we couldn’t afford to wait much time.

    We fixed the issue:

    Basically we modified the IPN to check that amount paid, currency and email are correct.

    If check fails, subscription is not added to user and an email is sent to admin to report fraud attempt.

    (this is a fraud that came up almost 10 years ago and was big news back than and I’m still very surprised you overlooked it)

    However while fixing we found another bug: If you setup your paypal account to receive payments on a secondary email address, the IPN returns only main paypal account email so the check always fails.

    We added a fix for that too, but it is manually coded, so if anyone is interested in using our fix while receiving payments on a secondary email of it’s paypal account, he will have to manually edit the code for now…

    I’m going to leave it here for everyone, but especially for Staypress folks, hoping it will convince them I was acting for the good… and cancel the fraud report, which is something I should file against you guys… as you are charging me for being a beta tester of your plugins instead of actually getting what I’m paying for.

    Thanks a lot!

    Paolo

    What we did:

    open /membership/membershipincludes/addons/gateway.paypalexpress.php and replaced code from line 818 to line 824 :

    // create_subscription
    $member = new M_Membership($user_id);
    if($member) {
    $member->create_subscription($sub_id, $this->gateway);
    }

    do_action('membership_payment_subscr_signup', $user_id, $sub_id);

    With :

    ################################## THEMETAILORS.COM EDIT START ################################

    global $wpdb, $table_prefix, $M_options;

    // Get the true Currency code
    if(empty($M_options['paymentcurrency'])) {
    $M_options['paymentcurrency'] = 'USD';
    }
    // Get the returned currency code
    $currency_code_rtnd = $_POST['mc_currency'];
    // Set the db table name
    $sub_db_table = $table_prefix.'m_subscriptions_levels';
    // Find the actual package initail payment
    $true_price_sql = "SELECT level_price FROM $sub_db_table where sub_id='$sub_id' AND sub_type='finite'";
    $true_price = $wpdb->get_var($true_price_sql);
    // Find the actual package subscription payment
    $true_sub_price_sql = "SELECT level_price FROM $sub_db_table where sub_id='$sub_id' AND sub_type='serial'";
    $true_sub_price = $wpdb->get_var($true_sub_price_sql);
    // Find the amount paid.
    $amount = $_POST['mc_amount1'];
    if($amount==''){$amount = $_POST['mc_amount2'];}
    // Find the subscription amount.
    $sub_amount = $_POST['mc_amount3'];
    // Get all the post vars to email if fraud
    $post_out = print_r($_POST, true);
    // payer Email check
    $true_paypal_email = get_option('paypalexpress_paypal_email'); // this option is fine if you are using your paypal primary email as your membership payment email.
    //$true_paypal_email = 'yourprimarypaypaladdress@yourmail.com'; // We need this option as the IPN only returns the primary email address.
    $rtnd_paypal_email = $_POST['receiver_email']; // get the returned email.

    // Set the fail reason
    $validation_fail_note = '';
    if($true_price!=$amount){$validation_fail_note .= '+ Initail Payment amount';}
    if($true_sub_price!=$sub_amount){$validation_fail_note .= ' + Subscription amount';}
    if($currency_code_rtnd!=$M_options['paymentcurrency']){$validation_fail_note .= ' + Currency Code';}
    if($true_paypal_email!=$rtnd_paypal_email){$validation_fail_note .= ' + Reciver Email';}

    // Check the payment meets all our validation
    if($true_price==$amount && $true_sub_price==$sub_amount && $currency_code_rtnd==$M_options['paymentcurrency'] && $true_paypal_email==$rtnd_paypal_email ){

    // create_subscription
    $member = new M_Membership($user_id);
    if($member) {
    $member->create_subscription($sub_id, $this->gateway);
    }
    do_action('membership_payment_subscr_signup', $user_id, $sub_id);
    }
    else{
    // else send admin a fraud emial.
    $to = get_option('admin_email');
    $subject = "Fraud Detected: ".$validation_fail_note;
    $message = "Fraud Detected with user ID: ".$user_id.". All details are below: ".$post_out;
    $from = get_option('admin_email');
    $headers = "From:" . $from;
    mail($to,$subject,$message,$headers);
    }
    ################################## EDIT END ########################################################

    If you are not using your paypal account’s primary email address to receive payments, uncomment following code (remove // at the beginning) and set your primary address where it says : yourprimarypaypaladdress@yourmail.com (line 843 of the attached file)

    $true_paypal_email = 'yourprimarypaypaladdress@yourmail.com'; // We need this option as the IPN only returns the primary email address.

    For your convenience… you can just download the file and replace it and finally make sure nobody can steal your work!

    Best,

    Paolo

  • poltaj
    • Site Builder, Child of Zeus

    Don’t know why doesn’t let me attach the txt file.

    You can download it here : here

    And if you want to check it, our site’s URL is : http://www.geotheme.com.

    We created a buy now button following Jonathan tips to achieve multiple subscriptions and create a different approach for the upgrading feature.

    We also played around a little with registration form and redirections…

    Well hope you like it and any feedback is more than welcome!

    Paolo

  • Barry
    • DEV MAN’s Mascot

    looks like we care about this plugin’s security more than anyone else.

    Nice work, I see it will only work for sites that have an initial finite payment and then serial recurring payments though, but good attempt – we’ll have a fully working fix out today which I’ve been working on since my last post (above).

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.