【问题标题】:php file_get_contents for post and consuming RESTphp file_get_contents 用于发布和使用 REST
【发布时间】:2014-06-09 15:10:44
【问题描述】:

在我为最近的一次采访提供的示例代码中,我使用 file_get_contents 来使用他们的 Web 服务(没有什么特别的,为 POST 请求发送一些自定义标头)。我发现 curl 等其他方法不必要地复杂和冗长,并在我使用 PHP 所做的大多数“客户端”内容中使用 file_get_contents。

一位面试官认为,除了获取请求之外,不建议将 file_get_contents 用于其他任何事情。我没有当场反对,而是回去用谷歌搜索了一下。对于他对这个“众所周知的事实”的断言,找不到任何可靠的答案

谁能指出在这种情况下使用 file_get_contents 的一些缺点?还有谁能给我指出一个他们消除 file_get_contents 的资源?

谢谢。

【问题讨论】:

    标签: php web-services rest


    【解决方案1】:

    从安全角度来看,使用file_get_contents() 通常不是一个好主意。

    allow_url_fopen

    要使file_get_contents() 能够使用远程源,必须启用设置allow_url_fopen。但是当启用此设置时,PHP 中所有其他与流相关的函数(如includerequire)也可以使用远程源。这可能允许像Remote File Execution 这样的攻击。

    使用其他工具时,例如 cURL,您可以禁用 allow_url_fopen(默认启用)。

    SSL/TLS

    默认情况下,PHP 流在 SSL/TLS 上是不安全的。幸运的是,这可以得到纠正,但在您可以安全地使用 HTTPS/FTPS 源之前确实需要注意。

    还有一个问题是 PHP 无法匹配证书中的主题备用名称(许多证书都使用该名称)。这意味着(在安全配置时)PHP 可以拒绝有效的证书。为了避免这种情况,您需要禁用 CN 匹配,这会打开您到 Man In The Middle attacks

    另一方面,cURL 默认是完全安全的,并且支持 SAN 匹配。

    生存深渊:PHP 安全

    Pádraic Brady 正在撰写一本关于 PHP 安全性的书,其中包含您可能想阅读的 this chapter

    狂饮

    你可能想看看Guzzle

    Guzzle 是一个 PHP HTTP 客户端,可以轻松使用 HTTP/1.1 并消除使用 Web 服务的痛苦。它默认使用 cURL。

    【讨论】:

    • 嗨 Jasper,关于 SSL/TLS 的坚定观点我不知道这一点。但是,如果我错了,请纠正我 allow_url_fopen 仅在您的代码库容易被注入时才构成安全威胁。如果您是提供共享主机的盒子的所有者,请务必禁用 allow_url_fopen。
    • 确实,allow_url_fopen 在您正确过滤用户输入时不会构成风险。但是过滤用户输入很困难,或者说很容易忘记一个案例,因为您根本没有想到这种可能性。所以我的座右铭是:如果您不需要它,请禁用它;)
    【解决方案2】:

    通过传递stream_context,您可以将file_get_contents() 用于简单的GET 请求之外。但很快它就会变得像 cURL 或其他一样复杂,同时(恕我直言)不那么直观。

    确实,正如 Jasper 所指出的,file_get_contents() 需要 allow_url_fopen=1,这又可能是一个安全威胁。但是,无论如何,allow_url_fopen 在大多数主机上都是有效的,而且我个人认为 PHP 中存在更严重的安全隐患。

    我的结论是:如果您只为自己构建应用程序,请使用file_get_contents() 或 cURL。如果您需要可移植性,请使用在原始套接字上实现 HTTP 客户端的库之一,例如 Snoopy。

    【讨论】:

    • Monte Ohrt 的“Snoopy”。哇 - 它仍然存在并得到维护。为此+1。它使用stream_socket_client()fsockopen()stream_context_create()。与 Guzzle 等类怪物相比,它相当轻量级。好吧,没有 PSR 编码风格.. 但是,嘿,它有效!
    • 是的,在推荐它之前,我必须检查它是否仍在维护。 ;)
    【解决方案3】:

    最适合这个用途 Curl。 Curl 有很多设置的事实:

    • 能够指定超时请求
    • 能够选择 GET 或 POST
    • 传递 cookie 的能力
    • 使用 BASIC AUTH 的能力

    对于所有这些和其他类似的事情很难使用 file_get_contents。使用 curl 并不难,我建议编写一个包装类。

    【讨论】:

    • 你提到的一切都是可能的,而且更容易——如果不一样的话——使用 file_get_contents
    • @kali 我无法想象如何为 file_get_contents 配置所有这些选项。 PHP手册对此似乎无动于衷。能详细点吗?
    • 你需要哪一个 Lorenz?我可以写一个快速示例
    猜你喜欢
    • 1970-01-01
    • 2011-01-27
    • 2012-07-04
    • 2016-02-10
    • 1970-01-01
    • 2018-06-08
    • 1970-01-01
    • 2019-12-23
    相关资源
    最近更新 更多