保护接收PayPal IPN通知的PHP脚本

6
在我的网站中,我集成了一个php脚本,接收IPN通知并向客户发送许可证密钥。该脚本位于一个文件夹中,该文件夹还有其他两个php文件是php脚本所需的...我该如何保护这个文件夹?如果我在其中放置一个.htaccess文件,并加上以下内容:
order allow,deny
deny from all

我也会屏蔽 PayPal 的通知。

我该如何保护它?需要吗?


我不确定每个人都理解你所说的“保护此文件夹”的含义。你是想拒绝列出此文件夹的内容吗?还是拒绝公众执行其他两个PHP文件?或者是其他什么意思? - sjstrutt
7个回答

7
您可以安全地将对IPN脚本的访问限制为以下IP地址列表:
216.113.188.202
216.113.188.203
216.113.188.204
66.211.170.66

这可以通过以下方式完成:
if (!in_array($_SERVER['REMOTE_ADDR'],array('216.113.188.202','216.113.188.203','216.113.188.204','66.211.170.66')) {
header("HTTP/1.0 404 Not Found");
exit();
}

只有Paypal才能访问IPN脚本,这样做可以保证安全。

这个IP地址列表多年来一直比较稳定。如果Paypal添加了新的地址,您可以通过电子邮件进行报告,并手动审查此类情况。


谢谢!!!有没有办法使用域名做相同的事情?换句话说… $_SERVER['REMOTE_ADDR']返回发送服务器的IP地址…那么如何获取远程域名? - BitDrink
沙盒的IP地址是否相同?如果添加了IP地址,您能否详细说明应该怎么做?提前致谢! - user1382306
2
答案发布于2009年,因此该列表可能已过时。请访问https://ppmts.custhelp.com/app/answers/detail/a_id/92进行核实。 - Andriy B

3

你为什么要这样做呢?

在IPN系统中,你首先需要使用cURL或fshock等工具将传递到你的ipn脚本的变量反弹回paypal...通过检查响应,你可以确定它是否是有效的交易...某人无法伪造一个在paypal本身不存在的交易变量...他们所能做的就是重新使用旧的交易信息来欺骗你的脚本...由于它存在于paypal上,你的脚本会认为它是一笔成功的付款...

因此,你可以通过将txn_id与你的数据库进行比较来防止这种情况,如果已经存在于你的数据库中,这意味着有人正在尝试使用已记录的交易信息来欺骗你...

既然你进行了这些检查,谁还关心调用这个ipn脚本的人呢...对他们来说,它不起作用,因为你检查变量是否与paypal和你的数据库匹配...

在任何异常情况下,打印出一个好的句子告诉他们“这个脚本很强大!别想愚弄我们!”


没错。如果你不知道如何进行错误处理或按照规范实现协议,那么最好不要处理支付。 - MattBianco
为什么要添加安全性?这只是钱而已。 - user1382306

3

有很多事情你可以做:

  1. 给你的脚本起一个不容易被猜出来的名字。
  2. 禁用文件夹中的目录列表。
  3. 检查调用网站是否为paypal.com(或相关的IP地址等)。

我从来没有做过这个...要禁用文件夹中所有文件的目录列表,我需要在该文件夹中放置一个名为".htaccess"的文件,并添加 "IndexIgnore *" ...是这样吗? - BitDrink
我已经尝试过这个,但是如果我尝试浏览PHP脚本,我会收到500错误! - BitDrink

2
如果您知道PayPal将使用脚本的IP,请尝试以下操作:
order deny, allow
deny from all
allow from [Paypal-IP]

有没有办法过滤域名而不是 IP 地址? - BitDrink
1
找到了!.. order deny, allow - deny from all - allow from .paypal.com. - BitDrink
您可以在此链接中找到与PayPal相关的IP列表:https://ppmts.custhelp.com/app/answers/detail/a_id/92 - R T

2

这应该得到检查!非常感谢你!因为你收藏了这篇文章。 - user1382306

2
我不建议屏蔽所有IP,因为您不能确定Paypal的请求是否始终来自同一IP。如果他们决定更改其IP范围,则您的设置将会中断,可能没有通知您。
我认为处理Paypal请求的脚本是处理此问题的地方-在该脚本中,您需要确保请求实际来自Paypal。您可以通过使用某些不容易猜测的URL来完成此操作。
如果可能的话,请查看IPN的共享密钥设置-这样您就有了更好的检查请求是否真正来自Paypal的方法,尽管设置有点困难。
希望这可以帮到您!

我还没有设置共享密钥...现在我要检查货币、金额和业务电子邮件是否正确...然后我想检查交易ID是否唯一...但是为了做到这一点!我必须设置一个数据库来存储所有交易的信息...但我从未使用过数据库,也不知道如何使用! - BitDrink
请“未知(谷歌)”,不要生我的气,但您是否认为在发布涉及真实货币的事物之前,先获得一些PHP、Web和数据库编程方面的经验不会有害呢? - Stefan Gehrig
你说得对!事实上,我还没有发布和发布任何东西!我的网站是离线的! - BitDrink

1

现在我已经这样做了:

在存储 PHP 脚本和 2 个配置文件的文件夹中,我创建了另一个文件夹,将这两个配置文件移动到其中,并放置了一个 .htaccess 文件,其中包含以下代码:

order allow,deny
deny from all

现在两个配置文件都有很好的保护!...但是接收通知的脚本没有!如果我尝试使用以下方式阻止目录列表(对于包含php脚本和config文件夹的文件夹):

IndexIgnore *

Paypal沙盒给我返回了500错误!

所以,为了保护脚本,我唯一能做的就是在脚本头部放置一个条件来验证通知是否来自paypal.com?

最后,我在php脚本头部添加了一个基于远程主机名的if语句:

 $remote_host = gethostbyaddr($_SERVER['REMOTE_ADDR']);

如果有人感兴趣,也可以查询$_SERVER['REMOTE_HOST'],但必须在服务器上配置httpd.conf文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接