保护 PHP 个由 AJAX 调用的端点
Protect PHP endpoints called by AJAX
我的应用包含多个 PHP 端点,可通过 AJAX 访问。问题是它们也可以通过向同一端点发出 HTTP 请求的任何人访问。我可以按照 this answer 中指定的方式添加 HTTP_X_REQUESTED_WITH
和 HTTP_REFERER
的检查,但这些可能会被欺骗。我可以添加一个需要随请求一起发布的密钥,但任何查看 javascript and/or 控制台的人都可以看到此密钥。这里的解决方案是什么?
没有一个。如果你给某人一些数据,那么他们可以用任何他们喜欢的方式处理它。您无法控制它离开您的服务器后会发生什么。
同样,您无法控制他们向端点发送的数据。
人们经常认为,因为他们正在使用 Ajax 请求,所以常规 sessions
不起作用。他们是这样。
如果您有一个端点可以从源代码中可见的数据库中删除某些内容,例如:
example.com/user/1/delete
您可以像在浏览器中使用非 Ajax HTTP 请求时一样保护此请求免受未经身份验证的用户的访问。使用 sessions。如果用户有删除用户的权限,这个路由会起作用,否则return一个错误(或者什么也不做)。
您还可以使用 OAuth 保护 API。这里有一个很好的文档解释了它是如何工作的:http://tatiyants.com/using-oauth-to-protect-internal-rest-api/
开发人员为 API 或 Web 服务设置身份验证非常重要。 dchacke 和 BugHunterUK 已经给出了完美的答案,我只是想向您展示我用来制作非常简单易用的身份验证的简单代码。
添加会话进行身份验证
您可以为您的 API 添加会话和会话超时,因此只有您的应用可以使用它,您可以在应用首页加载时启动会话,您可以设置超时并限制根据会话为不同的用户提供不同的服务。
总体思路如何做到这一点
<?php
if(!empty($_SESSION['api_session']) && $_SESSION['api_session'] == 'usertype'){
//usertype comprise of what access you want to give
//guest, registered user, stack holder, admin etc.
...
header('Content-Type:application/json;');
echo json_encode($output);
}
如果您的应用程序和 api 在不同的域(例如 app.example.com
和 api.example.com
上,大多数答案都没有帮助 - 在这种情况下,会话将无法工作并且你将不得不求助于 OAuth,对于这样一个简单的问题,它是一个相当大的锤子。
这是我会做的:
我假设您在数据库中有用户和一个像 user_id=12345
这样的唯一标识符。我还假设您的工作在数据库中,并且它们也有唯一的 ID,例如 job_id=6789
.
首先,在 app.example.com
上,您使用 Blowfish 等快速简便的方法对两个 ID 进行加密:
$secret_uid = mcrypt_encrypt(MCRYPT_BLOWFISH, "your_secret", strval($user_id));
$secret_jid = mcrypt_encrypt(MCRYPT_BLOWFISH, "your_secret", strval($job_id));
我假设您的端点会像这样工作:
api.example.com/jobs/delete/<job_id>/<user_id>
所以现在从 Ajax 调用该端点,而不是使用普通 ID
api.example.com/jobs/delete/6789/12345
你用加密的 ID 调用它:
api.example.com/jobs/delete/6A73D5B557C622B3/57F064C07F83644F
在软件的 API 端解密参数:
$jid = mcrypt_decrypt(MCRYPT_BLOWFISH, "your_secret", <param_1>);
$uid = mcrypt_decrypt(MCRYPT_BLOWFISH, "your_secret", <param_2>);
现在您可以在数据库中搜索 uid
和 jid
并执行您计划执行的任何任务。当然要确保用户只能删除他自己的工作。
我承认这不是 100% 的解决方案,但它给攻击者留下了很多猜测工作——他将不得不猜测 user_id 和匹配的 job_id,加密算法和你的秘密。它不能防止 运行 数百万次猜测匹配对的暴力尝试,但它会为您提供有利的机会(无论如何您都应该对端点进行某种配额限制保护)。
祝你好运!
我的应用包含多个 PHP 端点,可通过 AJAX 访问。问题是它们也可以通过向同一端点发出 HTTP 请求的任何人访问。我可以按照 this answer 中指定的方式添加 HTTP_X_REQUESTED_WITH
和 HTTP_REFERER
的检查,但这些可能会被欺骗。我可以添加一个需要随请求一起发布的密钥,但任何查看 javascript and/or 控制台的人都可以看到此密钥。这里的解决方案是什么?
没有一个。如果你给某人一些数据,那么他们可以用任何他们喜欢的方式处理它。您无法控制它离开您的服务器后会发生什么。
同样,您无法控制他们向端点发送的数据。
人们经常认为,因为他们正在使用 Ajax 请求,所以常规 sessions
不起作用。他们是这样。
如果您有一个端点可以从源代码中可见的数据库中删除某些内容,例如:
example.com/user/1/delete
您可以像在浏览器中使用非 Ajax HTTP 请求时一样保护此请求免受未经身份验证的用户的访问。使用 sessions。如果用户有删除用户的权限,这个路由会起作用,否则return一个错误(或者什么也不做)。
您还可以使用 OAuth 保护 API。这里有一个很好的文档解释了它是如何工作的:http://tatiyants.com/using-oauth-to-protect-internal-rest-api/
开发人员为 API 或 Web 服务设置身份验证非常重要。 dchacke 和 BugHunterUK 已经给出了完美的答案,我只是想向您展示我用来制作非常简单易用的身份验证的简单代码。
添加会话进行身份验证
您可以为您的 API 添加会话和会话超时,因此只有您的应用可以使用它,您可以在应用首页加载时启动会话,您可以设置超时并限制根据会话为不同的用户提供不同的服务。
总体思路如何做到这一点
<?php
if(!empty($_SESSION['api_session']) && $_SESSION['api_session'] == 'usertype'){
//usertype comprise of what access you want to give
//guest, registered user, stack holder, admin etc.
...
header('Content-Type:application/json;');
echo json_encode($output);
}
如果您的应用程序和 api 在不同的域(例如 app.example.com
和 api.example.com
上,大多数答案都没有帮助 - 在这种情况下,会话将无法工作并且你将不得不求助于 OAuth,对于这样一个简单的问题,它是一个相当大的锤子。
这是我会做的:
我假设您在数据库中有用户和一个像 user_id=12345
这样的唯一标识符。我还假设您的工作在数据库中,并且它们也有唯一的 ID,例如 job_id=6789
.
首先,在 app.example.com
上,您使用 Blowfish 等快速简便的方法对两个 ID 进行加密:
$secret_uid = mcrypt_encrypt(MCRYPT_BLOWFISH, "your_secret", strval($user_id));
$secret_jid = mcrypt_encrypt(MCRYPT_BLOWFISH, "your_secret", strval($job_id));
我假设您的端点会像这样工作:
api.example.com/jobs/delete/<job_id>/<user_id>
所以现在从 Ajax 调用该端点,而不是使用普通 ID
api.example.com/jobs/delete/6789/12345
你用加密的 ID 调用它:
api.example.com/jobs/delete/6A73D5B557C622B3/57F064C07F83644F
在软件的 API 端解密参数:
$jid = mcrypt_decrypt(MCRYPT_BLOWFISH, "your_secret", <param_1>);
$uid = mcrypt_decrypt(MCRYPT_BLOWFISH, "your_secret", <param_2>);
现在您可以在数据库中搜索 uid
和 jid
并执行您计划执行的任何任务。当然要确保用户只能删除他自己的工作。
我承认这不是 100% 的解决方案,但它给攻击者留下了很多猜测工作——他将不得不猜测 user_id 和匹配的 job_id,加密算法和你的秘密。它不能防止 运行 数百万次猜测匹配对的暴力尝试,但它会为您提供有利的机会(无论如何您都应该对端点进行某种配额限制保护)。
祝你好运!