b2bcenter / safecurl
作为 'curl_exec' 的替代品,旨在防止 SSRF 攻击。
This package is not auto-updated.
Last update: 2024-09-15 03:18:58 UTC
README
SafeCurl旨在替代PHP中的curl_exec函数。SafeCurl会对URL的每一部分与白名单或黑名单进行验证,以帮助防止服务器端请求伪造攻击。
有关项目的更多信息,请参阅博客文章'SafeCurl: SSRF Protection, and a "Capture the Bitcoins"'。
保护措施
将URL的每一部分分解并验证其对白名单或黑名单。这包括将域名解析为其IP地址。
如果您选择启用 "FOLLOWLOCATION",则任何重定向都将被捕获并重新验证。
安装
SafeCurl可以通过Composer包含在任何PHP项目中。在composer.json
文件中的require
部分包含以下内容。
"require": {
"fin1te\safecurl": "~1"
}
然后更新Composer。
composer update
用法
只需将curl_exec
替换为SafeCurl::execute
,并用try {} catch {}
块包装即可。
use fin1te\SafeCurl\SafeCurl; use fin1te\SafeCurl\Exception; try { $url = 'http://www.google.com'; $curlHandle = curl_init(); //Your usual cURL options curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (SafeCurl)'); //Execute using SafeCurl $response = SafeCurl::execute($url, $curlHandle); } catch (Exception $e) { //URL wasn't safe }
选项
默认选项是不允许访问任何私有IP地址,并且只允许HTTP(S)连接。
如果您希望添加自己的选项(例如,将任何请求到您控制的域名的请求列入黑名单),只需获取一个新的SimpleCurl\Options对象,将其添加到白名单或黑名单中,并随方法调用传递。
域名使用正则表达式语法表示,而IP、方案和端口是标准字符串(IP可以指定为CIDR表示法)。
use fin1te\SafeCurl\Options; $options = new Options(); $options->addToList('blacklist', 'domain', '(.*)\.fin1te\.net'); $options->addToList('whitelist', 'scheme', 'ftp'); //This will now throw an InvalidDomainException $response = SafeCurl::execute('http://safecurl.fin1te.net', $curlHandle, $options); //Whilst this will be allowed, and return the response $response = SafeCurl::execute('ftp://fin1te.net', $curlHandle, $options);
由于我们无法访问已设置的任何cURL选项(请参阅注意事项部分),要启用CURL_FOLLOWREDIRECTS
,必须调用enableFollowRedirects()
方法。如果您希望指定重定向限制,需要调用setMaxRedirects()
。传入0
将允许无限重定向。
$options = new Options(); $options->enableFollowLocation(); //Abort after 10 redirects $options->setFollowLocationLimit(10);
URL检查
URL检查方法也是公共的,这意味着您可以在应用程序的其他地方使用它之前验证URL,尽管您可能希望捕获任何重定向。
use fin1te\SafeCurl\Url; try { $url = 'http://www.google.com'; $validatedUrl = Url::validateUrl($url); $fullUrl = $validatedUrl['url']; } catch (Exception $e) { // URL wasn't safe }
可选保护措施
除了标准检查之外,还有两个可用。
第一个是防止DNS重绑定攻击。这可以通过在Options对象上调用enablePinDns
方法来启用。这个问题有一个主要问题 - SSL证书不能被验证。这是由于在Host
头中发送了真实的主机名,并且URL使用了IP地址。
$options = new Options(); $options->enablePinDns();
第二个是禁用URL中的凭证使用,因为PHP的parse_url
返回的值与cURL使用的值不同。这是一个临时修复。
$options = new Options(); $options->disableSendCredentials(); //This will throw an InvalidURLException $response = SafeCurl::execute('http://user:pass@google.com', $curlHandle, $options);
注意事项
由于SafeCurl使用getaddrbyhostl
来解析域名,这不是IPv6兼容的,所以目前该类只能使用IPv4。请参阅问题#1。
如上所述,我们无法获取对提供的cURL句柄设置的任何cURL选项的值。因为SafeCurl会自动处理重定向,它会关闭CURLOPT_FOLLOWLOCATION
并使用Options
对象中的值。这也适用于CURLOPT_MAXREDIRECTS
。
演示
您可以在http://safecurl.fin1te.net/#demo找到实时演示。如果您对网站源代码感兴趣(如果您好奇),它托管在fin1te/safecurl.fin1te.net。
悬赏
为了帮助使SafeCurl更安全并准备好投入生产使用,已设置比特币悬赏。
在文档根目录中有一个比特币钱包,它只能通过127.0.0.1访问。如果您能够绕过保护并抓取该文件,您就可以自由地拿走比特币。