> 헤드라인 > 본문

2019 PHP 보안 가이드

步履不停
풀어 주다: 2019-08-23 17:58:16
원래의
5787명이 탐색했습니다.

2019년에는 대부분의 기술 근로자, 특히 웹 개발자는 안전한 PHP 애플리케이션을 개발하는 기존 방식을 포기해야 할 것입니다. 보안이 아닌 보안을 강조하는

PHP: The Right Way

전자책의 보충 자료로 사용해야 합니다. as code 같은 스타일의 일반 테마입니다.2019 PHP 보안 가이드

PHP 버전

长话短说::除非你没有办法, 2018 年你在最好使用 PHP 7.2 , 同时在 2019 年早些时候计划切换到 7.3。
로그인 후 복사
PHP 7.2가 2017년 11월 30일에 출시되었습니다.

이 글을 쓰는 시점에서는 PHP 7.1과 7.2만 PHP 언어에서 적극적으로 지원됩니다. 개발자와 PHP 5.6 및 7.0은 약 1년 동안만 보안 패치를 받게 됩니다.

일부 운영 체제에서는 지원되지 않는 PHP 버전에 대한 장기적인 지원을 제공하지만 이러한 관행은 일반적으로 해로운 것으로 간주됩니다. 특히, 버전 번호를 업그레이드하지 않고 보안 패치를 제공하고 있기 때문에 PHP 버전만으로 시스템의 보안을 판단하기가 매우 어렵습니다.

요약하자면, 다른 공급업체가 약속하는 것과 관계없이, 그렇게 할 수 있는 한 항상

PHP 버전만

적극적으로

지원되는

버전만 실행해야 합니다. 이렇게 하면 한동안 보안 버전을 사용해 왔더라도 지속적인 업그레이드 노력으로 인해 불쾌한 일이 발생하지 않을 것입니다.

종속성 관리

Composer

는 PHP 생태계를 위한 가장 진보된 종속성 관리 솔루션입니다. 강력히 추천합니다

PHP: 올바른 방법시작하는 방법을 전담하는 섹션이 있습니다. . Composer. Composer를 사용하여 종속성을 관리하지 않으면 결국(지연되길 바라지만 곧 일어날 수도 있음) 의존하는 라이브러리가 더 이상 사용되지 않고 이전 버전이 해커에 의해 악용되는 상황이 발생하게 됩니다. 핵심 사항: 소프트웨어를 개발할 때 항상 종속성 업데이트

를 기억하세요. 운 좋게도 다음 명령이 있습니다.

composer update
로그인 후 복사

특별히 PHP 확장(C로 작성)을 사용해야 하는 작업을 수행하는 경우 해당 확장을 설치할 수 없습니다. 작곡가를 사용하여. PECL도 필요합니다.

권장 패키지

무엇을 빌드하든 이러한 종속성의 이점을 거의 확실히 누릴 수 있습니다. 이는 대부분의 PHP 개발자(예: PHPUnit, PHP-CS-fixer)가 권장합니다.

roave/security-advisories

Roave의 보안 권고

Friends of PHP

라는 패키지를 사용하여 프로젝트가 알려진 견고하지 않은 패키지에 의존하지 않도록 합니다.

composer require roave/security-advisories:dev-master
로그인 후 복사
또는 정기적인 자동 취약성 평가의 일환으로 Sensio Labs파일을

업로드할 수 있으며 사용된 모든 오래된 패키지에 대해 알려드립니다. vimeo/psalmcomposer.lock

Psalm 是一个静态分析工具,可以帮助识别你代码中的 bug。虽然还有其他很好的静态分析工具(例如: Phan and PHPStan ,它们都很好),如果您发现自己需要支持 php 5,没问题,psalm 是支持 php 5.4 + 的。

Psalm 是很容易上手的:

# 目前还没有Version 1 ,但是让我们拭目以待:
composer require --dev vimeo/psalm:^0# 
仅需这样操作:
vendor/bin/psalm --init# 
一如惯例的操作:
vendor/bin/psalm
로그인 후 복사

如果你是第一次在现有的代码库上运行,可能会看到很多红色提示。这是正常的,除非你创造了一个如同 Wordpress 一样强大的应用程序,否则不太可能使全部测试通过以满足符合 Herculean 的要求。

无论您使用哪种静态分析工具,我们建议您将运用到持续集成工作流(如果适用),以便在每次代码更改后运行它。

HTTPS 和浏览器安全

简而言之: HTTPS, which should be tested, and security headers.
로그인 후 복사

在 2018 年,通过不安全的 HTTP 访问网站将不再被接受。幸运的是,得益于 ACME 协议和 Let's Encrypt certificate authority 的存在,我们可以免费获取 TLS 证书并自动更新它们。

将 Acme 集成到 Web 服务器中简直就是小菜一碟。

  • Caddy: 自动生成.

  • Apache: 不久将以 mod_-md. 的形式提供, 这里有高质量的教程 在互联网上提供。

  • Nginx: 相对简单.

你也许会想,“好吧,我有一个 TLS 证书。现在,我必须花几个小时来处理配置,然后才能保证它的安全和快速。”

Nope! Mozilla 支持. 您可以使用配置生成器根据预期的访问群体构建推荐的密码套件

HTTPS (HTTP over TLS) 是绝对不可协商如果您希望您的网站是安全的。使用 HTTPS 可以立即消除对用户的几类攻击(中间建注入、窃听、重复攻击和多种形式的会话操作,否则将允许用户模拟)。

安全 Headers

虽然将 HTTPS 连接到服务器上确实为用户增加了安全性和性能优势,但你可以通过利用其他浏览器安全功能更进一步的扩大这些优势。其中大多数都涉及在内容里发送 HTTP 响应头。

  • Content-Security-Policy

    • 你需要这个 header,因为它可以对浏览器允许加载的内部和外部资源进行精度控制,从而为跨站点脚本漏洞提供强大的防御层。

    • 请参阅 CSP-Builder,以便快速轻松地部署 / 管理内容安全策略。

    • 要进行更深入的分析,Scott Helme 的 Content-Security-Policy 标题简介是一个很好的起点。

  • Expect-CT

    • 你需要这个 header,因为它通过强制将不良居心的人的证书的证据发布到可公开验证的数据结构,从而为恶意 / 受损的证书颁发机构添加了一层保护。 了解更多关于 “Expect-CT” 的信息

    • 首先将这个 header 设置为 enforce,max-age = 30,并增加 max-age,如此操作让服务更稳定。

  • Referrer-Policy

    • 你需要这个 header,因为它允许您控制是否将有关用户行为的信息泄露给第三方。

    • 再次深入了解 Scott Helme 深入探讨Referrer-Policy headers

    • 将 header 设置为 “same-origin” 或 “no-referrer”,除非您有理由允许更宽松的设置。

  • Strict-Transport-Security

    • 你需要这个 header,因为它告诉浏览器通过 HTTPS 强制所有将来的请求到同一个来源而不是不安全的 HTTP。

    • 首次部署时将其设置为 “max-age = 30”,然后当您确信没有任何内容会中断时,将此值增加到某个较大的值(例如 “31536000”)。

  • X-Content-Type-Options

    • 你需要这个 header,因为 MIME 类型混淆可能导致不可预测的结果,包括允许 XSS 漏洞的奇怪边缘情况。最好伴随标准的 Content-Type 标题。

    • 设置为 nosniff,除非您需要默认行为(例如,用于文件下载)。

  • X-Frame-Options

    • 你需要这个 header,因为它可以防止点击劫持

    • 设置为 DENY(或 SAMEORIGIN,但仅当你使用 <frame> 元素时)

    • X-XSS-Protection
      - 你需要这个 header,因为它启用了默认情况下未启用的某些浏览器 Anti-XSS 功能。
      - 设为 1; mode=block

同样,如果你使用 PHP 的内置会话管理功能(推荐使用),你可能想要调用 session_start(),如下所示:

session_start([
    &#39;cookie_httponly&#39; => true,
    &#39;cookie_secure&#39; => true]);
로그인 후 복사

这会强制你的应用在发送会话标识符 cookie 时使用仅 HTTP 和安全标记,阻止成功的 XSS 攻击窃取用户的 cookie 并强制它们分别仅通过 HTTPS 发送。我们之前已经在 2015 年的博文中介绍了安全 PHP 会话

子资源一致性攻击(Subresource Integrity)

在将来的某个时候,你可能会使用 CDN 将常用的 Javascript / CSS 框架和库放到一个集中的地方。

负责安全的工程师对这种操作表示有很明显的安全隐患:那就是,许多网站使用 CDN 来提供内容,那么攻击 CDN 并替换内容注入这些代码到成千上万数千的网站。

输入 subresource integrity.

Subresource integrity (SRI) 允许你固定你希望 CDN 提供的文件内容的哈希值。当前实现的 SRI 仅允许使用安全加密散列函数,这意味着攻击者生成与原始文件产生相同散列的相同资源的恶意版本是不可行的。

真实的案例: Bootstrap v4-alpha 在他们的 CDN 示例片段中使用 SRI.

<link
    rel="stylesheet"
    href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css"
    integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ"
    crossorigin="anonymous"/><script
    src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"
    integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn"
    crossorigin="anonymous"></script>
로그인 후 복사

文档关联

Web 开发人员经常在超链接上设置 target 属性(例如:target="_blank")实现在新窗口中打开链接。但是,如果您没有传递 ' rel="noopener" 标记,则可能允许目标页面控制原始页面

不要这样做

<a href="http://example.com" target="_blank">Click here</a>
로그인 후 복사

这让example.com 可以控制当前的网页。

替换成这样

<a href="https://example.com" target="_blank" rel="noopener noreferrer">Click here</a>
로그인 후 복사

这将在一个新窗口中打开 example.com,但不会将当前窗口的控制权交给可能怀有恶意的第三方。

延伸阅读

开发安全的 PHP 软件

如果应用程序安全性是一个新主题,请从应用安全性详解开始.

许多安全领域的专家都会向开发人员提供诸如 OWASP Top 10 之类的资源.

但是,大多数常见漏洞可以归类为同一类的安全问题(代码 / 数据没有完全分离,逻辑不健全,操作环境不安全或加密协议缺陷)。

给新手们说明安全问题是一个很简单的,容易实现的事情,但是如何解决这些安全问题将是更长远的安全工程。

因此, 我们只推荐类前 10 名或前 25 名安全检查清单.

数据库交互

深入了解: PHP 防止 SQL 注入 https://paragonie.com/blog/2015/05/preventing-sql-injection-in-php-applications-easy-and-definitive-guide
로그인 후 복사

如果您自己编写 SQL 查询,请确保您使用的是预备表达式,并且将网络或文件系统提供的任何信息都作为参数传递,而不是拼接查询字符串。此外,确保你没有使用模拟的预备表达式.

为达到最佳效果,使用 EasyDB.

* 不要这样做:

/* 不安全代码: 
*/$query = $pdo->query("SELECT * FROM users WHERE username = &#39;" . $_GET[&#39;username&#39;] . "&#39;");
로그인 후 복사

替换成这样:

/* 防止SQL注入: */
$results = $easydb->row("SELECT * FROM users WHERE username = ?", $_GET[&#39;username&#39;]);
로그인 후 복사

还有其他一些数据库抽象层提供了同等的安全性(EasyDB 实际上在底层使用 PDO,但是为了防止安全隐患,它特意禁用准备好的语句模拟,而使用实际的准备好的语句)。只要用户输入不能影响查询的结构,您就是安全的。(这包括存储过程。)

文件上传

深入了解: 如何安全地允许用户上传文件 https://paragonie.com/blog/2015/10/how-securely-allow-users-upload-files
로그인 후 복사

接受文件上传是一个冒险的主张,但只要采取一些基本的预防措施,就可以安全地执行此操作。也就是说,应当阻止意外地允许执行或解释上传文件的方式直接访问上传文件.

上传的文件应该是只读的或读写的,永远不能被执行.

如果你的站点根目录是 /var/www/example.com, 你不应该存贮上传文件在 /var/www/example.com/uploaded_files.

相反,你应该将上传文件存储在无法通过浏览器直接访问的单独目录中 (例如, /var/www/example.com-uploaded/), 以免它们意外地作为服务器端脚本执行,打开远程代码执行的漏洞。

更简单的解决方案是将站点根目录向下移动一级 (例如,移动到:/var/www/example.com/public)。

文件上传的另一个问题是安全地 下载文件 。

直接访问 SVG 图像将在用户的浏览器中执行 JavaScript 代码。 这是真的,尽管 SVG 图像的 MIME 类型是以image\ 为前缀.

MIME 类型嗅探可能导致类型混淆攻击。详情见前文安全 HeadersX-Content-Type-Options 响应头的介绍。

如果你不采纳前面关于如何安全存贮上传文件的建议,攻击者可能设法上传.php 或者.phtml 的文件, 通过直接在浏览器中访问上传文件执行任意代码,从而获得对服务器的完全控制。请安全地玩你的服务器。

跨站脚本 (XSS)

深入阅读: 关于防止 PHP 中的跨站点脚本漏洞,您需要了解的所有内容 https://paragonie.com/blog/2015/06/preventing-xss-vulnerabilities-in-php-everything-you-need-know
로그인 후 복사

在理想的情况下, XSS 和 SQL 注入一样容易预防。我们有简单易用的 API ,用于将查询语句和数据进行分离。

不幸的是,大多数 web 开发人员的实际工作会涉及到将生成的一长串 HTML 文本并通过 HTTP 协议响应。这不是 PHP 独有的功能,它只是 web 开发的基本工作方式。

减少 XSS 漏洞并不是那么难做。但是,浏览器安全 的所有内容是至关重要。简而言之:

  1. 经常对输出转义,而不是对输入转义。 如果你在数据库中存储已过滤的数据,然后在一些地方发现 SQL 注入漏洞,那么攻击者可以通过恶意代码篡改可信的数据记录,从而完全绕过 XSS 保护。

  2. 如果你的框架中有一个提供自动上下文过滤的模板引擎,那可以使用它。它将会给你的框架的功能的安全性提供保障。

  3. echo htmlentities($string, ENT_QUOTES | ENT_HTML5, &#39;UTF-8&#39;); 是一种安全有效的方式,它可以阻止对 UTF-8 编码的 web 页面的 XSS 攻击,但它不允许任何 HTML 标签内容输出。

  4. 如果你的需求是允许你使用 Markdown 替代 HTML,不要使用 HTML

  5. 如果你需要允许一些 HTML 并且没有使用模板引擎(请参见 #1),那么就使用 HTML 净化器。 HTML 净化器不适用于将内容转义成 HTML 标签属性的场景。

  6. 对于用户提供的 URLs ,你应该只允许使用 http:https: 协议模式;不要用 javascript: 。此外,使用 URL 编码方式编码用户的所有输入。

跨站请求伪造 (CSRF)

跨站请求伪造是一种混乱的代理攻击,通过这种攻击,你可以利用用户的权限,欺骗用户的浏览器执行恶意的 HTTP 请求来实现攻击者的目的。

这在一般情况下可通过两个简单步骤解决:

  1. 使用 HTTPS,这是前置条件。没有 HTTPS,任何防御都会变得脆弱,然而单纯的 HTTPS 并不能阻止 CSRF。

  2. 添加基本的请求 - 响应的身份验证。

    • 在所有表单中添加一个隐藏的表单值。

    • 用安全的随机加密字符串来填充这个值(称为令牌)。

    • 验证表单中是否含有这个隐藏的值,并且校验是否与设置的一致。

我们编写了一个名为 Anti-CSRF 的库来更进一步了解如何防范 CSRF。

  • 为了防止重复攻击,每个令牌只能使用一次。

    • 多个令牌都存储在后端。

    • 令牌轮换一旦达到上限,优先使用最老的。

  • 每个令牌都可以绑定到指定的资源地址(URI)。

    • 一旦令牌泄露,那么它也不能用于其他资源请求。

  • 令牌可以选择绑定到指定的 IP 地址。

  • 从 v2.1 版本开始,令牌可以重复使用(即 AJAX 调用)。

如果你没有使用一个能够帮你解决 CSRF 的框架,那么 Anti-CSRF 能够帮到你。

在将来,使用 cookie 的 SameSite 属性能够更加简单地防范 CSRF

译者注:截至 2016 年 4 月,Chrome 51、Opera 39、火狐 60 已实现了 cookie 的 Same-Site 属性。
로그인 후 복사

XML 攻击 (XML 外部实体注入,XPath 注入)

对于那些过多依赖 XML 数据结构来处理繁重的业务逻辑的程序而言,这里有两个比较容易被攻击的点。

  1. XML 外部实体注入 (XXE)XPath 注入

  2. XXE 攻击会利用服务器执行本地或远端的的恶意外部文件, 或者执行其他恶意的行为.

在早期版本的谷歌安全文档中就有显著的提及 XXE 攻击,但对于大多数的大量执行 XML 操作的非商业应用来说对 XXE 的防范意识是薄弱的。

其实最简单的减轻 XXE 攻击影响的方式就是:

libxml_disable_entity_loader(true);
로그인 후 복사

XPath 注入 和 SQL 注入的原理一样,只不过是把攻击对象换成了 XML 文档。

比较幸运的是,PHP 对 XPath 操作方法的查询参数是很比较特殊和形式固定的。

另一方面呢,PHP 对于 XPath 注入没有提供简单有效的防御手段(参数过滤)。

对于 XPath 查询参数过滤,你的最佳方案就是使用白名单策略匹配过滤。

<?phpdeclare(strict_types=1);class SafeXPathEscaper{
    /**
     * @param string $input
     * @return string
     */
    public static function allowAlphaNumeric(string $input): string    {
        return \preg_replace(&#39;#[^A-Za-z0-9]#&#39;, &#39;&#39;, $input);
    }
    /**
     * @param string $input
     * @return string
     */
    public static function allowNumeric(string $input): string    {
        return \preg_replace(&#39;#[^0-9]#&#39;, &#39;&#39;, $input);
    }}// 用法示例:$selected = $xml->xpath(
    "/user/username/" . SafeXPathEscaper::allowAlphaNumeric(
        $_GET[&#39;username&#39;]
    ));
로그인 후 복사

这里我们采用白名单的策略比黑名单策略安全。

反序列化和 PHP 对象注入

深度阅读: php 反序列化安全的实现 https://paragonie.com/blog/2016/04/securely-implementing-de-serialization-in-php
로그인 후 복사

如果你将不可信的数据传递给 unserialize(),你将不得不面对以下两个窘境:

  1. PHP 对象注入风险,一种利用 POP 链(POP chain)来触发其他误用对象的漏洞。php 反序列化 POP 链的构造与理解异常语法

  2. 带来的 PHP 解析器本身的内存奔溃。

对于大多数开发者来讲他们更倾向于用 JSON 来替代对对象的序列化操作,这样的话确实规避了很多安全风险,但又引发了另外一个安全问题不得不提:DoS 攻击 - Hash 碰撞攻击( json_decode () 容易遭受 DoS 攻击 - Hash 碰撞攻击 (Hash-DoS) )。 遗憾的是, PHP 的 Hash-DOS 问题还没有得到彻底解决

对于 Hash-DOS 利用的 php Hash 冲突的问题。从 djb33 迁移到 Siphash,对于字符串输入,哈希输出的最高位设置为 1 ,对于整数输入设置为 0 ,使用 CSPRNG 提供的请求密钥,将完全解决这些攻击。

遗憾的是, PHP 团队还没有准备好放弃他们已经在 PHP 7 系列中取得的性能提升,所以很难说服他们放弃 djb33 (这是非常快但不安全的) 采用 SipHash (这也是快速的,但不像 djb33 那么快,但更安全)。 如果性能受到重大影响,可能会阻碍未来版本的采用,但也影响了安全性。

因此我们当前能做的是:

  • 使用 JSON 的方式,因为它比 unserialize() 更安全。

    • 在任何可能的地方,在反序列化之前确保输入是经过安全过滤的。

    • 对于提供给用户的数据,通过一个只有服务器知道的秘钥使用 sodium_crypto_auth() sodium_crypto_auth_verify() 验证。

    • 对于第三方提供的数据,让他们使用 sodium_crypto_sign() 签名他们的 JSON 消息,然后使用 sodium_crypto_sign_open() 和第三方公钥验证消息。

  • 如果你需要对传输的签名进行十六进制或 Base64 位编码,也可以使用分离的签名 API 。

  • 如果你无法确保 参数中 JSON 字符串的安全性,请严格限制单个 IP 访问频率以避免高频的攻击。(laravel 框架可以采用 Throttle 配置)

密码哈希

深入了解: 在 2016 年如何安全存储用户密码 https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016
로그인 후 복사

密码安全的存储曾经是一个备受争议的话题,但现在实现起来相当简单,尤其是在 PHP 中:

$hash = \password_hash($password, PASSWORD_DEFAULT);if (\password_verify($password, $hash)) {
    // 已验证
    if (\password_needs_rehash($hash, PASSWORD_DEFAULT)) {
        // 刷新,更新数据库
    }}
로그인 후 복사

您甚至不需要知道后台使用的是什么算法,因为如果您使用的是最新版本的 PHP,那么您也将使用最新的最新版本,并且一旦有新的默认算法可用,用户的密码将自动升级。

不管你做什么, 在 WordPress 不要这样做.
如果你对此感到好奇:从 php 5.5 到 7.2,默认算法是 bcrypt。将来,它可能会切换到 Argon2,即 [密码散列类型]https://password-hashing.net/).

如果您以前没有在 API 中使用加密,同时需要迁移旧散列,请使用这种方法. 很多公司在这方面做了错误的操作,其中典型就的公司有,雅虎。, Yahoo. 最近,错误地实现旧哈希升级似乎已经导致了苹果最近的 iamroot bug caused Apple's recent iamroot bug.

一般用途的加密

这是我们之前已经详细讨论过的话题:

通常,你总希望使用 Sodium 加密库 (libsodium)对应用层加密。如果需要低于 7.2 版本(直到 5.2.4)你可以使用 sodium_compat 并假设你的用户也在使用 7.2 。

在特定的实例中,由于严格的算法选择和互操作性,你可能需要一个不同的库。如果有疑问,可以向加密专家咨询加密方式,并向密码工程师咨询这种实现是否安全。(这就是我们提供的服务之一 。)

如果你直接使用密码 / 模式, 请参考关于加密最佳实践的简要指南

随机数

深入了解: 如何在 PHP 中安全地生成随机字符串和整数 https://paragonie.com/blog/2015/07/how-safely-generate-random-strings-and-integers-in-php
로그인 후 복사

如果您需要随机数,请使用 random_int(). 如果需要随机字节字符串,请使用 random_bytes(). 所以不要使用 mt_rand(), rand(), 或 uniqid() .

如果你需要从一个密钥生成伪随机数,不要用 srand() 或者 mt_srand(), 请查看 SeedSpring .

<?php
use ParagonIE\SeedSpring\SeedSpring;
$seed = random_bytes(16);$rng = new SeedSpring($seed);
$data = $rng->getBytes(1024);
$int = $rng->getInt(1, 100);
로그인 후 복사

服务器端 HTTPS 请求

简而言之:确保没有禁用 TLS 证书验证。
로그인 후 복사

请随意使用你熟悉且兼容 PSR-7 规范的 HTTP 客户端,大多数人喜欢使用 Guzzle 库。也有一些人喜欢直接使用 cURL。

无论你用哪一种,你可以 使用 Certainty 库来确保你拥有最新的证书包 , 这进而允许你启用最严格的 TLS 证书验证设置,并保护服务器的出站 HTTPS 请求。

安装 Certainty 库非常简单:

composer require paragonie/certainty:^1
로그인 후 복사

使用 Certainty 库也很容易:

<?php
use ParagonIE\Certainty\RemoteFetch;
$latestCACertBundle = (new RemoteFetch())->getLatestBundle();
# 使用 cURL:
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($ch, CURLOPT_CAINFO, $latestCACertBundle->getFilePath());
# 使用 Guzzle:
    /** @var \GuzzleHttp\Client $http */
    $repsonse = $http->get(
        &#39;https://example.com&#39;, 
        [
            &#39;verify&#39; => $latestCACertBundle->getFilePath()
        ]
로그인 후 복사

这将保护你免受 Web 服务器与你集成的任何第三方 API 之间的中间人攻击 (man-in-the-middle attacks)。

我们真的 需要 Certainty 库吗?

严格来说,为了保护您的系统,Certainty 库不是必要的。缺少它并不是弱点。

但是没有 Certainty 库。 开源软件必须推测操作系统的 CACert 包是否存在,并且如果它推测错误,它会经常失败得很惨并导致可用性问题。

纵观历史,这激励了许多开发人员禁用证书验证,这样他们的代码就可以 “正常工作” 了,却没有意识到他们的应用程序在受到主动攻击时是多么不堪一击。

Certainty 库通过使 CACert 捆绑包位于最新的和可预测的位置来消除这种激励。Certainty 库还为许多希望运行他们自己内部 CA 的企业提供了许多工具。

谁来禁用证书验证?

常见的内容管理系统(WordPress,Magento 等)的插件 / 扩展开发人员可以做到! 这是我们在生态系统层面试图解决的一个巨大问题。 它不是孤立于任何特定的 CMS,你会发现插件等。 因为所有这些都是不安全的。

如果您正在使用这样的 CMS,请在插件中搜索 CURLOPT_SSL_VERIFYPEERCURLOPT_SSL_VERIFYHOST ,您可能会发现有几个将这些值设置为 FALSE

应该避免的事情

不要使用 mcrypt,一个已经十多年没有开发的密码学库。如果您正在关注 我们的 PHP 版本推荐,自从 PHP 7.2 及更新版本中没有提供 mcrypt,这应该是一个容易避开的陷阱。

配置驱动安全建议应该有大部分被忽视了。如果你正在阅读 PHP 安全指南并且他们告诉你修改 php.ini 配置,而不是编写更优秀的代码,那么你可能正在阅读非常过时的建议。 关掉当前窗口,并转移到那些不吹嘘 register_globals 的页面中。

不要使用 JOSE (JWT, JWS, JWE),尽管脚注表示已经写进了标准。但这是一套编纂成一系列容易出错的密码学设计,因为某些原因吸引了大量追崇者而形成的互联网标准 。

加密 URL 参数是一种很多公司用来混淆元数据采用的反面模式 (e.g. 我们有多少使用者呢?)。在产生安全感的错觉同时,它携带着实现错误的高风险。我们在相关文章中提出了一个更安全的替代方案。

除非你真的迫不得已,否则不要实现 "忘记密码" 功能。直言不讳地讲: 密码重置功能就是一个后门。 有一些方法可以实现它们,这些方法对合理的威胁模型是安全的,但是这应该也给了高风险用户一个让他们完全选择退出的机会。

如果可以,避免使用 RSA, 而使用 libsodium。如果你一定要 RSA,确保你指定了 OAEP 进行填补。

<?php
openssl_private_decrypt(
    $ciphertext,
    $decrypted, // 明文在成功时写入这个变量。
    $privateKey,
    OPENSSL_PKCS1_OAEP_PADDING // 重要:不要忽略这个!
);
로그인 후 복사

如果你专注于使用 PKCS#1 v1.5 进行填补,无论你集成了什么,几乎都会很容易被 机器人攻击,所以将其作为一个允许明文公开和伪造签名的漏洞报告给合适的供应商 (或 US-CERT)。

专业使用案例

既然你已经掌握了在 2018 年及以后构建安全 PHP 应用程序的基础知识,现在让我们来看一些更专业的使用案例。

可搜索的加密

深入阅读:使用 PHP 和 SQL 建立可搜索的加密数据库 https://paragonie.com/blog/2017/05/building-searchable-encrypted-databases-with-php-and-sql
로그인 후 복사

可搜索的加密数据库是可取的,但实现它被普遍认为不是非常重要。上面的博文试图让读者更深入地了解我们的解决方案,但实际上你只需:

  1. 设计您的架构,使数据库即使泄露也不会让攻击者获取到您的加密密钥。

  2. 使用密钥加密你的数据。

  3. 基于 HMAC 或带有静态盐的安全 KDF(例如:Argon2)创建多个索引(使用它们自己独特的密钥)。

  4. 可选:截断步骤 3 的输出,将其作为一个布隆过滤器(Bloom filter)。

  5. 在你的 SELECT 查询中使用第 3 或第 4 步的输出结果。

  6. 解密结果。

在这个过程中的任何步骤,你都可以根据你的实际情况来做调整。

无边信道的基于令牌的身份认证

深入阅读: 拆分令牌:无边信道的基于令牌的身份验证协议 https://paragonie.com/blog/2017/02/split-tokens-token-based-authentication-protocols-without-side-channels
로그인 후 복사

说到数据库(上一章节),你知道 SELECT 查询理论上可以成为定时信息泄漏的来源吗?

简单的防范措施:

  1. 切分你的认证令牌。

  2. 一半在 SELECT 查询中使用。

  3. 在一定的时间内使用后半部分进行验。

    • 您可以选择将后半部分的哈希存储在数据库中,而不是它本身。这对于只使用一次的令牌是有意义的,如用在 “密码重置” 或 “在这台计算机上记住我” 等地方的令牌。

这样即使你可能会因为定时泄漏被别人窃取到一半的令牌,剩下的一半也需要暴力破解才能成功。

开发安全的 API

深入阅读: 使用 Sapient 让 PHP 开发的 API 更为坚固 https://paragonie.com/blog/2017/06/hardening-your-php-powered-apis-with-sapient
로그인 후 복사

我们编写了 SAPIENT(the Secure API ENgineering Toolkit)使服务器到服务器之间传递身份验证信息变得更为简单。

除了具有 HTTPS 提供的安全性之外,Sapient 还允许你使用共享密钥或公钥来加密和验证信息。

即使有一个用恶意 / 受损的证书颁发机构武装自己的中间人攻击(man-in-the-middle)攻击者,也能让你可以对 API 请求进行身份验证 ,并使用 ED25519 或只能由接收服务器的密钥解密的加密信息对目标服务器响应。

由于每个 HTTP 消息体都通过安全加密进行了身份验证,因此可以安全地使用它来代替有状态令牌可能会被篡改的协议(例如 OAuth)。但当涉及到密码学时,在做任何非标准的事情之前,都应该始终确保专家对它们的实现进行了研究。

Sapient 所使用的所有密码学算法都由 Sodium cryptography library 提供。

拓展阅读:

Sapient 文档

Sapient 教程

Sapient 规范

Paragon Initiative Enterprises 已经在其许多产品(包括许多开源软件项目)中使用了 Sapient,并将继续将软件项目添加到 Sapient 产品组合中。

使用 Chronicle 记录安全事件日志

深入阅读: Chronicle 会让你质疑区块链技术的需求 https://paragonie.com/blog/2017/07/chronicle-will-make-you-question-need-for-blockchain-technology
로그인 후 복사

Chronicle  是一个基于哈希链(hash-chain)数据结构的仅追加的加密分类账(append-only cryptographic ledger),它具有许多吸引公司使用的 “区块链” 技术的属性,也不会有太多多余的功能。

除了仅追加加密分类账这样具有创造性的使用案例之外,当集成到 SIEM 中时,Chronicle 也是非常有亮点的,因为你可以将安全关键事件发送到私有的 Chronicle,使它们不可被改变。

如果你设置 Chronicle 将其摘要哈希交叉签名到其他 Chronicle 实例,或者配置了其他实例来复制 Chronicle 的内容,那么攻击者就很难篡改你的安全事件日志了。

使用 Chronicle,您可以获得区块链具有的所有弹性(resilience)特点,而不会出现任何隐私、性能和可扩展性问题。

要将数据发布到本地 Chronicle,您可以使用任何与 Sapient 兼容的 API,最简单的方式是 Quill

作者的一些话

很多聪明的读者应该注意到了我们参考了很多我们自己的工作内容(包括了一些之前发的博文和我们的开源项目),但其实我们并不仅仅参考我们自己的内容。

这并不意外。

本公司自从 2015 成立以来一直致力于编写安全库并参与改善 PHP 生态系统安全性。

我们已经涉及了很多领域,但我们的安全工程师(就在最近发布的 PHP 7.2 中,他们推动了 PHP 核心更安全的加密技术的发展)自己并不太擅长炒作,也不会拘泥于过去所做的工作。很可能您甚至没有听说过我们多年来开发的一个半个工具或库。对此我们深感抱歉。

그러나 우리가 모든 일에 선구자가 될 수는 없기 때문에 이기적이기보다는 공익을 추구하는 전문가들과 함께 최선을 다해 협력하겠습니다. 이것이 바로 브라우저 보안 섹션에서 개발자가 이러한 새로운 보안 기능에 액세스하고 이해할 수 있도록 만들기 위해 많은 노력을 기울인 Scott Helme 과 그의 회사의 작업을 인용하는 이유입니다.

이 가이드는 완전하지는 않습니다. 안전한 코드를 작성하는 방법만큼 안전하지 않은 코드를 작성하는 방법도 많습니다. 안전은 단순한 목표가 아니라 마음의 상태입니다. 위에서 작성한 내용과 다음 리소스를 통해 전 세계 개발자가 오늘 PHP로 보안 소프트웨어를 작성하는 데 도움이 되기를 바랍니다.

리소스

이 기사의 모든 내용을 읽고 더 자세히 알아보고 싶다면 애플리케이션 보안 학습을 위한 읽기 목록에 관심이 있을 수 있습니다.

당신이 작성한 코드가 충분히 안전하다고 생각하고 보안 엔지니어의 관점에서 평가해 주기를 원하신다면 저희에게 오십시오. 이것은 실제로 저희가 고객에게 제공하는 서비스 중 하나입니다.

귀사에서 규정 준수 테스트(예: PCI-DSS, ISO 27001 등)를 수행할 경우 저희 회사를 고용하여 소스 코드를 감사할 수 있습니다. 우리의 프로세스는 다른 보안 컨설팅 회사보다 개발자 친화적입니다.

다음은 자신만의 방식으로 네트워크 보안을 개선하는 데 도움이 되도록 PHP 및 정보 보안 커뮤니티에서 제공하는 리소스 목록입니다.

PHP Way, 현대 PHP 개발의 진정한 가이드.

Mozilla의 SSL Configuration Generator

TLS 인증서를 무료로 제공하는 인증 기관 웹사이트인 Let's Encrypt에서는 보다 안전한 네트워크 환경을 만들기 위해 최선을 다하고 있습니다.

Qualys SSL Library는 TLS 구성을 위한 빠르고 간단한 테스트 모음을 제공합니다. 실제로 모든 사람이 이를 사용하여 암호화 제품군 및 인증서 문제를 해결합니다. 그 이유는 바로 이 작업이 잘 수행된다는 것입니다.

보안 헤더를 사용하면 웹사이트가 브라우저 보안 기능으로 사용자를 얼마나 잘 보호하는지 확인할 수 있습니다.

Report-URI는 보안 헤더 구현을 위한 이니셔티브를 빠르게 시작하는 데 도움이 되는 훌륭한 무료 리소스입니다. 이는 사용자의 브라우저에 전달되는 Report-URI를 제공하며, 비정상적인 일이 발생하거나 XSS 공격 벡터가 발견되면 Report-URI에 보고서를 보냅니다. Report-URI는 오류를 더 잘 분류하고 문제를 해결할 수 있도록 이 오류 정보를 수집합니다.

PHP 보안 강림절 달력 , RIPSTech 팀에서 제작.

Snuffleupagus, 보안 지향 PHP 모듈(대부분 더 이상 사용되지 않는 것으로 보이는 Suhosin의 아이디어에서 상속됨).

PHP Delusions, PHP를 더 잘 활용하기 위한 웹사이트입니다. 저자의 어조 대부분은 매우 독선적이지만, 기술적인 정확성과 명확성에 대한 저자의 헌신은 특히 PDO의 많은 기능에 익숙하지 않은 사람들에게 읽을 가치가 있습니다.

내가 사기를 당했나요? 사용자가 과거에 데이터가 손상되었는지 확인할 수 있도록 도와줍니다.

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿