Moodle
  1. Moodle
  2. MDL-35456

PayPal discarding use of HTTP 1.0 protocol and requires HOST, Sandbox already set to refuse IPN without

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.9.19, 2.2.3, 2.3, 2.3.2
    • Fix Version/s: 2.2.7, 2.3.4, 2.4.1
    • Component/s: Enrolments
    • Labels:
    • Testing Instructions:
      Hide

      0/ make sure your moodle install may be accessed from internet
      1/ add $CFG->usepaypalsandbox = true; to your config.php
      2/ apply for sandbox account at http://developer.paypal.com
      3/ create a test business account and a test personal account
      4/ setup up paypal enrol plugin to use the business email
      5/ create a course and set up paypal enrolments
      6/ create user with the test personal email
      7/ login as the test user and try to enrol
      8/ verify user was enrolledproperly

      Show
      0/ make sure your moodle install may be accessed from internet 1/ add $CFG->usepaypalsandbox = true; to your config.php 2/ apply for sandbox account at http://developer.paypal.com 3/ create a test business account and a test personal account 4/ setup up paypal enrol plugin to use the business email 5/ create a course and set up paypal enrolments 6/ create user with the test personal email 7/ login as the test user and try to enrol 8/ verify user was enrolledproperly
    • Affected Branches:
      MOODLE_19_STABLE, MOODLE_22_STABLE, MOODLE_23_STABLE
    • Fixed Branches:
      MOODLE_22_STABLE, MOODLE_23_STABLE, MOODLE_24_STABLE
    • Pull from Repository:
    • Pull 2.4 Branch:
      w49_MDL-35456_m24_paypal
    • Pull Master Branch:
      w49_MDL-35456_m25_paypal
    • Rank:
      44147

      Description

      Provided as a point of information.

      I note there are several bugs listed saying M2.2 / 2.3 are not working in PayPal Sandbox; the Sandbox has been set to refuse IPN / PDT whose formats don't match the following announcement, sent last week:

      ------ Forwarded Message Follows -------

      In a bulletin dated October 18, 2011, we announced
      that we were going to expand the number of IP addresses for www.paypal.com to
      improve our site's performance, scalability and availability. As part of this
      transition, we planned to discontinue support for HTTP 1.0 protocol starting
      February 1, 2013.

      We have recently identified that this change may
      impact the ability of some of our merchants to perform IPN (Instant Payment
      Notification) post-back validation or PDT (Payment Data Transfer) posts to
      www.paypal.com. This happens when the IPN or PDT scripts use HTTP 1.0 protocol
      and do not include the "Host: www.paypal.com" header in the HTTP request.

      Additional Details
      Starting February 1, 2013, we
      will require all incoming requests to have a "Host" header which complies with
      HTTP 1.1 Specifications. This header was not required under HTTP 1.0. IPN and
      PDT scripts using HTTP 1.0 may start failing with "HTTP/1.0 400 Bad Request"
      errors after February 1, 2013, which will result in IPN messages not being
      validated successfully, or PDT scripts not being able to retrieve transaction
      information.

      Action Required before February 1, 2013

      Merchants need to update their IPN and/or PDT scripts to use HTTP 1.1, and
      include the "Host" header in the IPN postback script.

      Example:

      ASP
      //Set values for the request back
      req.Method="POST";

      req.Host="'www.paypal.com'";

      req.ContentType="application/x-www-form-urlencoded";

      Perl

      $req=HTTP::Request->new('POST', 'https://www.paypal.com/cgi-bin/webscr');

      $req->content_type('application/x-www-form-urlencoded');

      $req->header(Host=> 'www.paypal.com');

      PHP

      // post back to PayPal system to validate
      $header .="POST
      /cgi-bin/webscr HTTP/1.1\r\n";
      $header .="Content-Type:
      application/x-www-form-urlencoded\r\n";
      $header .="Host:
      'www.paypal.com\r\n';;

      Java
      HttpsURLConnection
      uc=(HttpsURLConnection) u.openConnection(); uc.setDoOutput(true);

      uc.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
      uc.setRequestProperty("Host",;'www.paypal.com';

      The
      PayPal Sandbox
      has been configured to reject any HTTP requests without the "Host" header with
      HTTP 400 error. Merchants can use the Sandbox environment to certify the changes
      to their IPN and PDT scripts.

      For more information on PDT and IPN,
      please refer to http://www.paypal.com/pdt and http://www.paypal.com/ipn. For additional
      information or questions about this change, please contact PayPal's Merchant
      Technical Support team via https://www.paypal.com/mts.

      Sincerely,

      PayPal

        Issue Links

          Activity

          Hide
          Petr Škoda added a comment -

          Thanks for the report.

          Show
          Petr Škoda added a comment - Thanks for the report.
          Hide
          Randy McCall added a comment -

          FYI, on Sept. 18, PayPal broadcast additional information and/or clarifications, including a change in the header requirements listed in their previous statment:

          ---- Forwarded Information Follows ----

          Action Required before February 1, 2013
          Merchants need to update their IPN and/or PDT scripts to use HTTP 1.1, and include the "Host: www.paypal.com" and "Connection: close" HTTP headers in the IPN and PDT scripts.
          For examples, please refer to https://www.x.com/node/320404

          FULL COPY OF ANNOUNCEMENT

          Bulletin: IPN and PDT scripts and HTTP 1.1

          Site or Service Name: PayPal Live Site | Last Update: Sep 18, 4:16 PM CDT

          PayPal MTS Bulletin
          In an October 18, 2011 bulletin found at https://www.x.com/node/217895 we announced that we were going to expand the number of IP addresses for www.paypal.com to improve our site’s performance, scalability and availability. As part of this transition, we planned to discontinue support for the HTTP 1.0 protocol starting February 1, 2013.

          We have recently identified that this change may impact the ability of some of our merchants to perform IPN (Instant Payment Notification) post-back validation or PDT (Payment Data Transfer) posts to www.paypal.com. This happens when the IPN or PDT scripts use the HTTP 1.0 protocol and do not include the “Host: www.paypal.com” header in the HTTP request.

          Additional Details
          Starting February 1, 2013, we will require all incoming requests to have a “Host” header which complies with the HTTP 1.1 specification.
          This header was not required under HTTP 1.0 IPN and PDT scripts using HTTP 1.0 may start failing with “HTTP/1.0 400 Bad Request” errors after February 1, 2013, which will result in IPN messages not being validated successfully, or PDT scripts not being able to retrieve transaction information.

          Action Required before February 1, 2013
          Merchants need to update their IPN and/or PDT scripts to use HTTP 1.1, and include the “Host” and “Connection” headers in the IPN postback script. In addition to this bulletin, these merchants will be notified via a direct email.

          Example:

          ASP
          //Set values for the request back
          req.Method="POST";
          req.Host="www.paypal.com";
          req.setRequestHeader "Connection", "close";
          req.ContentType="application/x-www-form-urlencoded";

          Perl
          $req=HTTP::Request->new('POST', 'https://www.paypal.com/cgi-bin/webscr');
          $req->content_type('application/x-www-form-urlencoded');
          $req->header(Host=> 'www.paypal.com');
          $req->header(Connection => 'close');

          PHP
          // post back to PayPal system to validate
          $header .="POST /cgi-bin/webscr HTTP/1.1\r\n";
          $header .="Content-Type: application/x-www-form-urlencoded\r\n";
          $header .="Host: www.paypal.com\r\n";
          $header .="Connection: close\r\n";

          Java
          HttpsURLConnection uc=(HttpsURLConnection) u.openConnection();
          uc.setDoOutput(true);
          uc.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
          uc.setRequestProperty("Host", "www.paypal.com");
          uc.setRequestProperty("Connection", "Close");

          The PayPal Sandbox has been configured to reject any HTTP requests without the “Host” header with HTTP 400 error. Merchants can use the Sandbox environment to certify the changes to their IPN and PDT scripts.

          For more information on PDT and IPN, please refer to http://www.paypal.com/pdt and http://www.paypal.com/ipn.
          For additional information or questions about this change, please contact PayPal's Merchant Technical Support team via https://www.paypal.com/mts.

          If you have questions, contact PayPal Merchant Technical Services by filing a ticket; refer to PP-LIVE-2891

          Show
          Randy McCall added a comment - FYI, on Sept. 18, PayPal broadcast additional information and/or clarifications, including a change in the header requirements listed in their previous statment: ---- Forwarded Information Follows ---- Action Required before February 1, 2013 Merchants need to update their IPN and/or PDT scripts to use HTTP 1.1, and include the "Host: www.paypal.com" and "Connection: close" HTTP headers in the IPN and PDT scripts. For examples, please refer to https://www.x.com/node/320404 FULL COPY OF ANNOUNCEMENT Bulletin: IPN and PDT scripts and HTTP 1.1 Site or Service Name: PayPal Live Site | Last Update: Sep 18, 4:16 PM CDT PayPal MTS Bulletin In an October 18, 2011 bulletin found at https://www.x.com/node/217895 we announced that we were going to expand the number of IP addresses for www.paypal.com to improve our site’s performance, scalability and availability. As part of this transition, we planned to discontinue support for the HTTP 1.0 protocol starting February 1, 2013. We have recently identified that this change may impact the ability of some of our merchants to perform IPN (Instant Payment Notification) post-back validation or PDT (Payment Data Transfer) posts to www.paypal.com. This happens when the IPN or PDT scripts use the HTTP 1.0 protocol and do not include the “Host: www.paypal.com” header in the HTTP request. Additional Details Starting February 1, 2013, we will require all incoming requests to have a “Host” header which complies with the HTTP 1.1 specification. This header was not required under HTTP 1.0 IPN and PDT scripts using HTTP 1.0 may start failing with “HTTP/1.0 400 Bad Request” errors after February 1, 2013, which will result in IPN messages not being validated successfully, or PDT scripts not being able to retrieve transaction information. Action Required before February 1, 2013 Merchants need to update their IPN and/or PDT scripts to use HTTP 1.1, and include the “Host” and “Connection” headers in the IPN postback script. In addition to this bulletin, these merchants will be notified via a direct email. Example: ASP //Set values for the request back req.Method="POST"; req.Host="www.paypal.com"; req.setRequestHeader "Connection", "close"; req.ContentType="application/x-www-form-urlencoded"; Perl $req=HTTP::Request->new('POST', 'https://www.paypal.com/cgi-bin/webscr'); $req->content_type('application/x-www-form-urlencoded'); $req->header(Host=> 'www.paypal.com'); $req->header(Connection => 'close'); PHP // post back to PayPal system to validate $header .="POST /cgi-bin/webscr HTTP/1.1\r\n"; $header .="Content-Type: application/x-www-form-urlencoded\r\n"; $header .="Host: www.paypal.com\r\n"; $header .="Connection: close\r\n"; Java HttpsURLConnection uc=(HttpsURLConnection) u.openConnection(); uc.setDoOutput(true); uc.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); uc.setRequestProperty("Host", "www.paypal.com"); uc.setRequestProperty("Connection", "Close"); The PayPal Sandbox has been configured to reject any HTTP requests without the “Host” header with HTTP 400 error. Merchants can use the Sandbox environment to certify the changes to their IPN and PDT scripts. For more information on PDT and IPN, please refer to http://www.paypal.com/pdt and http://www.paypal.com/ipn . For additional information or questions about this change, please contact PayPal's Merchant Technical Support team via https://www.paypal.com/mts . If you have questions, contact PayPal Merchant Technical Services by filing a ticket; refer to PP-LIVE-2891
          Hide
          Diane Villemure added a comment -

          RE: Sandbox: Not only is the issue that "The PayPal Sandbox has been configured to reject any HTTP requests without the “Host” header with a HTTP 400 error." but as Phu Hoang Xuan reported in http://moodle.org/mod/forum/discuss.php?d=172052: "The problem I found was that ipn.php tries to access the non-ssl version of Paypal, so it gets a redirect from Paypal." He uploaded a patch (for version 2.2 of ipn.php) that reads as follows:

          diff --git a/enrol/paypal/ipn.php b/enrol/paypal/ipn.php
          index b4a6bf4..9081601 100644
          — a/enrol/paypal/ipn.php
          +++ b/enrol/paypal/ipn.php
          @@ -93,8 +93,8 @@ $header = '';
          $header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
          $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
          $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
          $paypaladdr = empty($CFG>usepaypalsandbox) ? 'www.paypal.com' : 'www.sandbox.paypal.com';
          -$fp = fsockopen ($paypaladdr, 80, $errno, $errstr, 30);
          +$paypaladdr = empty($CFG->usepaypalsandbox) ? 'ssl://www.paypal.com' : 'ssl://www.sandbox.paypal.com';
          +$fp = fsockopen ($paypaladdr, 443, $errno, $errstr, 30);

          In the 2.2 version of ipn.php, I can see how to fix the $header myself. The issue is that the 2.3 version of ipn.php doesn't have the same code (lines 92-101):

          /// Open a connection back to PayPal to validate the data
          $c = new curl();
          $options = array(
          'returntransfer' => true,
          'httpheader' => array('application/x-www-form-urlencoded'),
          'timeout' => 30,
          );
          $paypaladdr = empty($CFG->usepaypalsandbox) ? 'www.paypal.com' : 'www.sandbox.paypal.com';
          $location = "https://$paypaladdr/cgi-bin/webscr";
          $result = $c->post($location, $req, $options);

          The 2.3 version of ipn.php is further suspicious in that the line 110 is empty:

          line 109 /// Connection is OK, so now we post the data to validate it
          line 110
          line 111 /// Now read the response and check if everything is OK.

          In 2.2 version, the "empty" line use to have this code: fputs ($fp, $header.$req);

          Show
          Diane Villemure added a comment - RE: Sandbox: Not only is the issue that "The PayPal Sandbox has been configured to reject any HTTP requests without the “Host” header with a HTTP 400 error." but as Phu Hoang Xuan reported in http://moodle.org/mod/forum/discuss.php?d=172052: "The problem I found was that ipn.php tries to access the non-ssl version of Paypal, so it gets a redirect from Paypal." He uploaded a patch (for version 2.2 of ipn.php) that reads as follows: diff --git a/enrol/paypal/ipn.php b/enrol/paypal/ipn.php index b4a6bf4..9081601 100644 — a/enrol/paypal/ipn.php +++ b/enrol/paypal/ipn.php @@ -93,8 +93,8 @@ $header = ''; $header .= "POST /cgi-bin/webscr HTTP/1.0\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: " . strlen($req) . "\r\n\r\n"; $paypaladdr = empty($CFG >usepaypalsandbox) ? 'www.paypal.com' : 'www.sandbox.paypal.com'; -$fp = fsockopen ($paypaladdr, 80, $errno, $errstr, 30); +$paypaladdr = empty($CFG->usepaypalsandbox) ? 'ssl://www.paypal.com' : 'ssl://www.sandbox.paypal.com'; +$fp = fsockopen ($paypaladdr, 443, $errno, $errstr, 30); In the 2.2 version of ipn.php, I can see how to fix the $header myself. The issue is that the 2.3 version of ipn.php doesn't have the same code (lines 92-101): /// Open a connection back to PayPal to validate the data $c = new curl(); $options = array( 'returntransfer' => true, 'httpheader' => array('application/x-www-form-urlencoded'), 'timeout' => 30, ); $paypaladdr = empty($CFG->usepaypalsandbox) ? 'www.paypal.com' : 'www.sandbox.paypal.com'; $location = "https://$paypaladdr/cgi-bin/webscr"; $result = $c->post($location, $req, $options); The 2.3 version of ipn.php is further suspicious in that the line 110 is empty: line 109 /// Connection is OK, so now we post the data to validate it line 110 line 111 /// Now read the response and check if everything is OK. In 2.2 version, the "empty" line use to have this code: fputs ($fp, $header.$req);
          Hide
          Diane Villemure added a comment -

          Just a heads up that the drop-dead date is February 1st, 2013. If no patch is created to address this change in PayPal access, all Moodle sites relying on PayPal as an enrolment method will stop functioning.

          Show
          Diane Villemure added a comment - Just a heads up that the drop-dead date is February 1st, 2013. If no patch is created to address this change in PayPal access, all Moodle sites relying on PayPal as an enrolment method will stop functioning.
          Hide
          Doug added a comment -

          Hello,

          This is going ot become a major critical issue for folks using PayPal and many od not even know it. Is anyone working on this? Can i pay some integrator or someone to help resolve this?

          Thanks

          Doug

          Show
          Doug added a comment - Hello, This is going ot become a major critical issue for folks using PayPal and many od not even know it. Is anyone working on this? Can i pay some integrator or someone to help resolve this? Thanks Doug
          Hide
          Doug added a comment -

          How do we elevate this to Critical Level?

          Doug

          Show
          Doug added a comment - How do we elevate this to Critical Level? Doug
          Hide
          Dan Poltawski added a comment -

          Integrated, thanks Everyone!

          Show
          Dan Poltawski added a comment - Integrated, thanks Everyone!
          Hide
          Doug added a comment -

          What do you mean inegrated? If this is integrated, should this not be closed then?

          Doug

          Show
          Doug added a comment - What do you mean inegrated? If this is integrated, should this not be closed then? Doug
          Hide
          Damyon Wiese added a comment -

          Test passed - works as expected.

          Thanks!

          Show
          Damyon Wiese added a comment - Test passed - works as expected. Thanks!
          Hide
          Damyon Wiese added a comment -

          (Tested on 22, 23 and master).

          Show
          Damyon Wiese added a comment - (Tested on 22, 23 and master).
          Hide
          Eloy Lafuente (stronk7) added a comment -

          Many thanks for your effort, the whole Moodle Community will be enjoying your great solutions starting now!

          Closing, ciao

          Show
          Eloy Lafuente (stronk7) added a comment - Many thanks for your effort, the whole Moodle Community will be enjoying your great solutions starting now! Closing, ciao

            People

            • Votes:
              3 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: