【问题标题】:Dynamic PayPal button generation - isn't it very insecure?动态 PayPal 按钮生成 - 不是很不安全吗?
【发布时间】:2011-09-13 09:57:48
【问题描述】:

我只是在这里想知道.. PayPal 按钮不是动态创建的、非常不安全且容易“破解”的吗?

像这样:

<form name="_xclick" target="paypal" action="https://www.paypal.com" method="post">
<input type="hidden" name="cmd" value="_cart">
<input type="hidden" name="business" value="me@mybusiness.com">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="item_name" value="HTML book">
<input type="hidden" name="amount" value="24.99">
<input type="image" src="http://www.paypal.com/en_US/i/btn/btn_cart_LG.gif" border="0" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
<input type="hidden" name="add" value="1">
</form> 

当您可以使用 FireBug 等修改代码时,更改产品价格就很简单了。

我问的原因是因为我可能/将开始开发一个电子商务系统,可以在该系统中添加产品,而无需在 PayPal 中进行。

【问题讨论】:

  • 您需要在服务器上验证价格。我不知道你会如何使用 Paypal。
  • 您能否提供一个参考,说明您在 PayPal 开发者网站中看到该技术的位置?
  • 他们肯定会在服务器上验证它,这样就可以了。
  • 使用我在下面添加的答案,在将选项更改为您需要的(即产品或服务、邮资等)后,它允许您从数据库或任何其他来源中提取成本并创建动态按钮
  • @Kev - 当然,给你:paypal.com/cgi-bin/webscr?cmd=p/pdn/…

标签: php dynamic paypal


【解决方案1】:

您应该使用以下 PayPal 按钮 API:

$sendPayData = array(
    "METHOD" => "BMCreateButton",
    "VERSION" => "65.2",
    "USER" => "username",
    "PWD" => "password",
    "SIGNATURE" => "abcdefg",
    "BUTTONCODE" => "ENCRYPTED",
    "BUTTONTYPE" => "BUYNOW",
    "BUTTONSUBTYPE" => "SERVICES",
    "BUTTONCOUNTRY" => "GB",
    "BUTTONIMAGE" => "reg",
    "BUYNOWTEXT" => "BUYNOW",
    "L_BUTTONVAR1" => "item_number=$invoiceNumber",
    "L_BUTTONVAR2" => "item_name=$invoiceType",
    "L_BUTTONVAR3" => "amount=$invoiceTotal",
    "L_BUTTONVAR4" => "currency_code=GBP",
    "L_BUTTONVAR5" => "no_shipping=1",
    "L_BUTTONVAR6" => "no_note=1",
    "L_BUTTONVAR7" => "notify_url=http://www.abc.co.uk/paypal/ipn.php",
    "L_BUTTONVAR8" => "cancel_return=http://www.abc.co.uk/paypal/thanks",
    "L_BUTTONVAR9" => "return=http://www.abc.co.uk/paypal/return.php"
);

然后您可以使用 cURL 将其发送到他们的 API

$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_URL, 'https://api-3t.paypal.com/nvp?'.http_build_query($sendPayData));
$nvpPayReturn = curl_exec($curl);
curl_close($curl);

然后生成一个无法编辑的加密 HTML 按钮

<form action="https://www.paypal.com/cgi-bin/webscr" method="post"> 
<input type="hidden" name="cmd" value="_s-xclick"> 
<input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----MIIIUwYJKoZIhvcNAQcEoIIIRDCCCEACAQExggE6MIIBNgIBADCBnjCBmDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcTCFNhbiBKb3NlMRUwEwYDVQQKEwxQYXlQYWwsIEluYy4xFjAUBgNVBAsUDXNhbmRib3hfY2VydHMxFDASBgNVBAMUC3NhbmRib3hfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tAgEAMA0GCSqGSIb3DQEBAQUABIGAfqXycFvfW2NCSYDg0Gw80R85HLRk8CuBqaYasckuMJucw5I5osTTcUYJ7JWTBxaZfgz+SVAwj5QzNBdeBSHf9N+RMrjWLF8X9lDX9QXrns0RRUCBL46GfoXW8QMEo+lEnjMxtkycLTtBwJzzQrkR9cVk3hrbvZCputr0EXs5zhExCzAJBgUrDgMCGgUAMIIBnQYJKoZIhvcNAQcBMBQGCCqGSIb3DQMHBAhVGECT5w1q5YCCAXg4kqM0T3pJ9jfI1UjbvQGgfDHZpgYeWpCZcIv1t0PB5AryGz9ZfQhaoF5Y+pljStxEMt67HLJwbWcoIhoAoKTlO7aR7JOLxBT/jd4nkI0p3fDCU7trzy0uQLoFO7AGH2JFmMTUZlnaMKmmfCLcyOsLry0f2n8yhnXjeX2SznSgtvz9fIesEFTJpokKU70K4GqikqPz0aBVyalXnml4YAeqOgxwEON4KhDbfp/nb1SPg7AJ3wR7TJyitY+8J3KTg7XVBeHk7ch3fcJ4kBuHuBGvfcNNTQ2kMyFz0R9sLzH5thewxhxdFo3uiziEVhG/ofCVLjqjW6hgD2pTFdbrjwxcm4GQ/nXJXAm+sw7d15usFukxLCSiJQoXw3ovgGmCJI6F973TyggGFnjlTt1z/MSvcQzzNbl0WMhPaMlM5QvQ9YBEhBYh/fyiVOY37ZRHlWhLZHRE9Gdd1sscVcaV0zPhkefxxUz+Lo0RgGQ7tqWWFw+ql8uHpN/7oIIDpTCCA6EwggMKoAMCAQICAQAwDQYJKoZIhvcNAQEFBQAwgZgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQHEwhTYW4gSm9zZTEVMBMGA1UEChMMUGF5UGFsLCBJbmMuMRYwFAYDVQQLFA1zYW5kYm94X2NlcnRzMRQwEgYDVQQDFAtzYW5kYm94X2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbTAeFw0wNDA0MTkwNzAyNTRaFw0zNTA0MTkwNzAyNTRaMIGYMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMIU2FuIEpvc2UxFTATBgNVBAoTDFBheVBhbCwgSW5jLjEWMBQGA1UECxQNc2FuZGJveF9jZXJ0czEUMBIGA1UEAxQLc2FuZGJveF9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALeW47/9DdKjd04gS/tfi/xI6TtY3qj2iQtXw4vnAurerU20OeTneKaE/MY0szR+UuPIh3WYdAuxKnxNTDwnNnKCagkqQ6sZjqzvvUF7Ix1gJ8erG+n6Bx6bD5u1oEMlJg7DcE1k9zhkd/fBEZgc83KC+aMH98wUqUT9DZU1qJzzAgMBAAGjgfgwgfUwHQYDVR0OBBYEFIMuItmrKogta6eTLPNQ8fJ31anSMIHFBgNVHSMEgb0wgbqAFIMuItmrKogta6eTLPNQ8fJ31anSoYGepIGbMIGYMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMIU2FuIEpvc2UxFTATBgNVBAoTDFBheVBhbCwgSW5jLjEWMBQGA1UECxQNc2FuZGJveF9jZXJ0czEUMBIGA1UEAxQLc2FuZGJveF9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb22CAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQBXNvPA2Bl/hl9vlj/3cHV8H4nH/q5RvtFfRgTyWWCmSUNOvVv2UZFLlhUPjqXdsoT6Z3hns5sN2lNttghq3SoTqwSUUXKaDtxYxx5l1pKoG0Kg1nRu0vv5fJ9UHwz6fo6VCzq3JxhFGONSJo2SU8pWyUNW+TwQYxoj9D6SuPHHRTGCAaQwggGgAgEBMIGeMIGYMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMIU2FuIEpvc2UxFTATBgNVBAoTDFBheVBhbCwgSW5jLjEWMBQGA1UECxQNc2FuZGJveF9jZXJ0czEUMBIGA1UEAxQLc2FuZGJveF9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTExMDYxMjE0MDE0OFowIwYJKoZIhvcNAQkEMRYEFNu5UjQG2vaycSRYaiKfzYlhQv4cMA0GCSqGSIb3DQEBAQUABIGARpzYolvSZ2+oPziwSIeC+BjbdLrA9w6PhA2FPGcLYJFtkpGtlGazCviJbbnEBVpzGt1rmdPpzvhnOA6FKZ1nC668jADjqgF+LugFc1hIc0X9um6PQ7CXkSBAweLUGHp2xlKkIVUoRXWs2ppTLeVBz7JDjM4vpMr6mB5V494EEpM=-----END PKCS7-----
">
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_paynow_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online."> 
<img alt="" border="0" src="https://www.paypal.com/en_GB/i/scr/pixel.gif" width="1" height="1"> 

这些链接应该可以帮助您使用按钮选项:

https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_nvp_BMCreateButton

https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ButtonMgrAPIIntro

【讨论】:

  • 太棒了!不过,这需要任何 API 密钥吗?
  • SSL 由 paypal 通过将数据传递到安全位置 (https://api-3t.paypal.com) 来处理。设置所需要做的就是登录到您的贝宝帐户,转到个人资料,请求 API 签名(不是其他选项 - 我不记得它叫什么了),然后您就离开了。
  • 为最终用户简化工作相当容易。所有选项都是变量,即"BUTTONTYPE" =&gt; "BUYNOW" 可以是BUYNOW CART SUBSCRIBE 等。如果您向用户提供了一个带有从手册中获取的预定义选项的表单,那么您将有效地创建一个用户友好的 PayPal 付款用户部分不需要编码的系统。您将始终需要设置自己的贝宝帐户才能使用所有脚本(据我所知),否则会降低整体安全性。在 PayPal 上简单点击几下获取 API 密钥应该不是问题
  • 这比 Paypal 文档有用得多
  • @FiddlingAway 仍然安全,此后可能有 API 更新,但方法仍然有效。
【解决方案2】:

您是对的 - 如果您以明文形式传递产品价格等动态 PayPal 按钮,则很容易“破解”。

但是,PayPal 支持公钥按钮加密,因此相关细节不能轻易更改。这是它的工作方式:

  • 您使用适当的程序(例如 OpenSSL)生成公钥/私钥对。
  • 您登录到您的 PayPal 帐户并将公钥提交给 PayPal,然后将私钥安全地存储在您的 Web 服务器上。您还需要下载 PayPal 的证书并将其存储在您的服务器上。还强烈建议告诉 PayPal 不要接受未签名/未加密的交易(详情请参阅底部链接)。
  • 每次您需要生成 PayPal 按钮时,您使用 PayPal 的公钥加密数据并使用您的私钥对其进行签名,然后将结果显示在您的网页上。当用户单击该按钮时,PayPal 将解密详细信息并检查它们自在您的服务器上生成以来没有被篡改。

这样,只要您的私钥不被泄露,任何人都无法更改交易的详细信息。

更多信息和详细说明请访问https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_encryptedwebpayments#id08A3I0P017Q。 (虽然 PayPal 提供了生成加密按钮的软件,但我认为可以使用适当的函数“即时”创建它们,例如 PHP 中的openssl_*();我没有亲自测试过它们。

另一种方法是实施即时付款通知 (https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_admin_IPNIntro);您可以检查用户执行的交易金额是否等于订单总金额。

【讨论】:

  • 我为 Jekyll 创建了一个插件——一个流行的静态站点生成器——它使用了这种技术(paypal 在他们的文档中将其称为“加密网络支付”)。如果有人感兴趣,该插件是here(是的,我意识到这个问题最初是关于 PHP 的,只是希望能帮助人们在静态网站上寻找动态生成和安全的 paypal 按钮)
【解决方案3】:

我认为您也可以使用散列方法,其中所有重要值都经过散列处理,因此无法修改。

当前的方法确实可以破解,但是一旦您进入 PayPal 网站,您仍然可以看到您要支付的金额。由用户仔细检查金额。

【讨论】:

    【解决方案4】:

    你是对的。 &lt;input type="hidden" name="amount" value="24.99"&gt; 可以在客户端轻松操作。在您给出的示例中,这可能是客户实际上应该能够设置金额的表单,例如。一个贝宝捐赠按钮。否则在此表单提交后需要进行服务器端检查,以确保没有发生有趣的事情。

    【讨论】:

      【解决方案5】:

      您可以即时创建加密按钮,有关更多信息,您可以查看Dynamic Paypal button encryption

      【讨论】:

        【解决方案6】:

        我想我有解决这个问题的办法:
        首先,从安全页面提交到 PayPal - Public SSL。

        其次,您可以使用 Ajax 来防止用户通过“右键单击 - 查看源代码”或 Fire-Bug 等浏览器工具浏览您的 HTML 代码。

        这是 jQuery 中的一个示例:
        我通常使用 C#.NET 进行编程,所以这就是我使用 .ashx 通用处理程序进行通信的原因(但它可以与 PHP 一起使用好吧)

        $(函数 () {

        $.ajax({  
                   type: "POST",  
                   url: "myPage.ashx",  
                   data: {  
                       theProductsIdAndAmountsString: yourValue  
                   },
                   success: function (allHtmlCode) {
                       $("body").append(allHtmlCode);
                       $("form").submit();
                   }
               });
           });
        

        在服务器端,您可以通过汇集数据库中的数据来生成所有 HTML 表单,然后将其发送回页面。
        之后,将其附加到正文并将表单提交给 PayPal。

        现在没有人可以使用像 Fire-Bug 这样的浏览器工具来更改您的 HTML 值。

        【讨论】:

        • 我确实想过做表单提交的事情,但不是用 Ajax,所以 +1。我不认为可以使用 FireBug 之类的工具来编辑 Javascript,对吧? :)
        • Javascript 您可以使用 FireBug 进行编辑,但是您发送给 PayPal 的变量将在服务器中生成,您无法编辑,而且您也看不到源代码,我试过了.. 它是不可能。
          但是有一些工具允许您解码对服务器的请求,编辑变量值并使用新值重新向服务器请求。这就是为什么您应该使用 SSL (https://) 来加密对服务器的请求并防止这种情况发生。
        • @Shavit - 是否可以在不花钱的情况下使用 SSL? (我是否需要购买任何证书,或者它是如何工作的?)
        • 此方法不提供任何安全性。 ssl 没有区别,您仍然可以让浏览器向服务器提交您想要的任何内容。例如,尝试在浏览器中禁用 javascript。然后,您可以轻松打开 firebug,并提交表单。这就像把钥匙放在门垫下面一样。
        • 您还应该查看名为 Tamper Data 的 Firefox 扩展,每当您向服务器发出请求时,它都会停止浏览器,让您编辑值,然后继续提交。当然 SSL 可以防止 APR 攻击等,但用户仍然可以完全控制发送的内容。
        猜你喜欢
        • 2013-01-02
        • 2013-02-23
        • 2017-10-17
        • 2017-01-04
        • 2021-12-03
        • 1970-01-01
        • 2016-05-25
        • 1970-01-01
        • 2012-08-03
        相关资源
        最近更新 更多