首页 » Web前端 » php5calenda技巧_PHP应用轨范安然设计指北

php5calenda技巧_PHP应用轨范安然设计指北

访客 2024-12-13 0

扫一扫用手机浏览

文章目录 [+]

2018 年将至,一样平常程序员(特殊是 Web 开拓程序员)应该抛弃过去开拓PHP程序的很多不好的习气和不雅观念了。
虽然部分人不以为意,但是这确实是事实。

这个指南该当以重点部分作为 PHP: The Right Way 安全章节的补充,而不因此一样平常的 PHP 编程话题。

php5calenda技巧_PHP应用轨范安然设计指北

正文

php5calenda技巧_PHP应用轨范安然设计指北
(图片来自网络侵删)

PHP 版本

请在 2018 年利用 PHP 7.2, 并且操持 2019 年初切换到 PHP 7.3。

PHP 7.2 已于 2017 年 11 月 30 日发布。

写这篇文章的时候,只有 7.1 和 7.2 版本还在被 PHP 官方积极掩护,而 5.6 和 7.0 只在大概1年内供应安全补丁更新。

对付其他官方不掩护的 PHP 版本,虽然某些操作系统会供应长期支持和掩护,但这实在常日是有害的。
尤其是他们供应安全支持补丁却没有版本号,这使得很难阐明系统的安全性(仅仅知道 PHP 版本)。

因此,无论其他供应商提出了什么承诺,如果可以,你就该当在任何时候都武断地利用官方供应支持的 PHP 版本。
这样,只管终极是一个短暂的安全版本,但一个不断致力于升级的版本,总会让你收成一些意外的惊喜。

依赖管理

人生苦短,我用 Composer

在 PHP 生态中,Composer 是最前辈的依赖管理方案。
我们推举 PHP: The Right Way 中关于依赖管理的完全章节。

如果你没有利用 Composer 来管理运用的依赖,终极(hopefully later but most likely sooner)会导致运用里某个依赖会严重过期,然后老旧版本中的漏洞会被利用于打算机犯罪。

主要: 开拓软件时,时常记得保持依赖的更新。
幸运地,这只需一行命令:

composer update

如果你正在利用某些专业的,须要利用 PHP 扩展(C 措辞编写),那你不能利用 Composer 管理,而须要 PECL 。

推举扩展

不管你正在编写什么,你总会受益于这些依赖。
这是除了大多数 PHP 程序员的推举(PHPUnit, PHP-CS-Fixer, ...)外的补充。

roave/security-advisories

Roave's security-advisories 利用 Friends of PHP repository 确保你的项目没有依赖一些已知易受攻击的依赖。

composer require roave/security-advisories:dev-master

或者,你可以上传你的composer.lock文件到 Sensio Labs ,作为例行自动化漏洞评估事情流的一部分,以提醒创造任何过期的软件包。

vimeo/psalm

Psalm 是一个帮助你识别代码里可能存在 bugs 的静态剖析工具。
还有其他很好的静态剖析工具(例如 Phan 和 PHPStan 都很棒),但当你创造你须要支持 PHP 5,Psalm 将是 PHP 5.4+ 的首选。

利用 Psalm 挺大略:

# Version 1 doesn't exist yet, but it will one day:composer require --dev vimeo/psalm:^0# Only do this once:vendor/bin/psalm --init# Do this as often as you need:vendor/bin/psalm

如果你是第一次在现有代码库运行,可能会看到很多赤色缺点。
但除非你在构建像 WordPress 那么大的程序,否则努力通过所有测试绝不是艰巨的。

无论利用哪种静态剖析工具,我们都推举你能将他加入到持续集成事情流(Continuous Integration workflow)中,以便在每次变动代码中运行。

HTTPS 和浏览器安全

HTTPS, which should be tested, and security headers .

2018 年,不屈安的 HTTP 网站将不再被接管。
幸运的是,由于 ACME 协议 和 Let's Encrypt certificate authority,免费的 TLS 证书成为了可能。

将 ACME 集成到你的做事器,小菜一碟。

Caddy: 自动加入。
Apache: 很快作为mod_md可用。
在此之前,网上很多高质量教程。
Nginx: 相对大略。

你大概会想,“好,我已经有 TLS 证书了,为了网站变得安全和快速,得花些韶光折腾配置信息。

不!
Mozilla做了件好事情!

你可以根据网站的目标受众,利用配置天生器天生推举套件。

如果你希望网站安全,HTTPS ( HTTP over TLS ) 是绝对不能妥协的。
利用 HTTPS 急速就能肃清多种攻击(中间人攻击、窃听、重放攻击以及多少许可用户模拟的会话形式的攻击)。

安全头

在做事器利用 HTTPS 确实为用户供应了许多安全性和性能方面的好处,但也还能通过利用某些浏览器的安全功能来进一步提升安全性。
而这大部分会涉及到相应内容的安全头。

Content-Security-Policy你须要该 Header ,由于它供应了对付浏览器是否许可加载内部和外部资源的细化掌握,从而为跨域脚本攻击漏洞供应了有效防御层。
参阅 CSP-Builder,以便快速简便地支配/管理内容安全策略(Content Security Policies)。
为了更加深入的剖析, Scott Helme's introduction to Content-Security-Policy headers,会是一个很好的勾引。
Expect-CT你须要该 Header ,由于它能通过逼迫某些不良行为者将其缺点证书的证据颁发到可公开验证的仅可追加的数据构造,从而针对泼皮/受损的证书颁发机构增加一层防护。
优先设置为enforce,max-age=30。
只要你有足够的自傲该 Header 不会造成做事中断,增加max-age吧。
Referrer-Policy你须要该 Header ,由于它许可你掌握用户的行为信息是否透露给第三方。
同样地,Scott Helme 供应了一篇关于Referrer-Policy Header 先容好文。
除非有情由许可更加宽松的设置,否则请设置为same-origin或no-referrer。
Strict-Transport-Security你须要该 Header ,由于它见告浏览器通过 HTTPS 而不是不屈安的 HTTP ,将 future requests 设为同源。
在第一次支配时,将其设置为max-age = 30,然后当你确信没有任何内容会中断时,将此值增加到某个较大的值(例如 31536000)。
X-Content-Type-Options你须要该 Header ,由于 MIME 类型的稠浊可能会导致不可预知的结果,包括奇怪的许可 XSS 漏洞的边缘情形。
这最好伴随着一个标准的 Content-Type Header 。
除非须要默认的行为(例如文件的下载),否则请设置为nosniff。
X-Frame-Options你须要该 Header ,由于它许可你防止点击挟制。
设置为DENY (或者SAMEORIGIN, 但仅仅当你利用<frame>元素的时候)。
X-XSS-Protection你须要该 Header ,由于它启用了一些默认情形下未启用的浏览器反 XSS 功能。
设置为1; mode=block。

同样,如果你利用 PHP 的内置会话管理功能(建议利用),则可能须要这样调用session_start():

<?phpsession_start([ 'cookie_httponly' => true, 'cookie_secure' => true]);

这会逼迫你的运用在发送会话标识符时利用 HTTP-Only 和 Secure 标志,从而防止 XSS 攻击盗取用户的 Cookie ,并逼迫它们分别通过 HTTPS 发送。
我们之前在 2015 年的博客文章中先容了安全的 PHP 会话。

子资源完全性

在将来的某个时候,你大概会利用 CDN 来加载网站的公共 JavaScript/CSS 库。
安全工程师已经遇见了这存在一个明显的风险,如果很多网站利用 CDN 供应内容,Hack 和更换 CDN(得到了 CDN 的掌握权)就可以注入(恶意)代码到成千上万的网站。

查阅子资源完全性吧。

子资源完全性(SRI,Subresource integrity)许可你将希望 CDN 做事的文件的内容进行哈希处理。
目前实施的 SRI 只许可利用安全的密码散列函数,这意味着攻击者不可能天生与原始文件哈希相同的恶意版本资源。

一个真实例子: Bootstrap v4-alpha uses SRI in their CDN example snippet

<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 =\"大众_ blank\"大众在新窗口中打开链接)。
但是,如果你没有通报rel =\公众noopener\"大众标签,则可以许可目标页面掌握当前页面。

不要这样做:

<a href=\"大众http://example.com\公众 target=\公众_blank\"大众>Click here</a>

这会让http://example.com页面能掌握当前页面。

而该当这样做:

<a href=\公众https://example.com\"大众 target=\"大众_blank\"大众 rel=\"大众noopener noreferrer\"大众>Click here</a>

通过这样在新窗口打开https://example.com,当前窗口的掌握权也不会付与可能的恶意第三方。

可以更加深入研究。

开拓安全的 PHP 程序

如果运用程序安全性对你来说是一个新话题,请从运用程序安全性简介开始吧。

大多数安全专家指出,开拓者可以利用 OWASP Top 10 等资源开始动手。

但是,大多数常见的漏洞也可以是相同高档级的安全问题(例如代码和数据没有完备分离、逻辑不严谨和健全、操作环境不屈安或是可破译的密码协议等)。

我们的假设是,该当付与安全新手知道一些更大略、根本的安全知识和问题,并如何办理这些问题,该当是一个更好的、长远的安全工程。

因此,我们避免推举十大或二十大安全清单。

数据库注入

避免 PHP 程序存在 SQL 注入。

如果你是自己编写 SQL 代码,请确保利用prepared语句,并且从网络或文件系统供应的信息都作为参数通报,而不是字符串拼接的形式。
此外,确保你没有利用仿照的prepared语句。

为了达到好的效果,可以利用 EasyDB 。

不要这样做:

<?php/ Insecure code: /$query = $pdo->query(\公众SELECT FROM users WHERE username = '\"大众 . $_GET['username'] . \公众'\公众);

该当这样做:

<?php/ Secure against SQL injection: /$results = $easydb->row(\公众SELECT FROM users WHERE username = ?\"大众, $_GET['username']);

还有其他数据库抽象层供应了相同的安全性(EasyDB实际上是在利用 PDO ,但在实际的prepare语句前避免了prepared语句仿照)。
只要用户输入不会影响查询的构造,就很安全(包括存储过程)。

文件上传

深入:如何安全地许可用户上传文件?

接管文件上传是一个冒险的发起,但只要采纳一些基本的预防方法,是能担保安全的。
也便是说,许可文件直接上传的话,这些文件可能会被意外的许可实行或阐明。
上传的文件该当是只读(read-only)或读写(read-write)的,永久不应该可实行(executable)。

如果你的网站根目录是/var/www/example.com,请不要保存上传文件在/var/www/example.com/uploaded_files。

而该当保存到一个不能直接访问的目录(例如:/var/www/example.com-uploaded/),以免意外地将其作为做事器端脚本实行,并得到实行远程代码的后门。

一个更加简洁的方法是将网站根目录往下移动一个层级(即:/var/www/example.com/public)。

如何安全地下载这些上传文件也是一个问题。

直接访问 SVG 图像类型时,将在用户浏览器实行 JavaScript 代码。
只管它的MIME类型中的image/前缀具有误导性,但是这是精确的。
正如前面提及的,MIME 类型嗅探可能导致类型稠浊攻击。
请参阅X-Content-Type-Options。
如果你放弃前面关于如何安全地存储上传文件的建议,攻击者就会通过上传 .php 或 .phtml 文件,直接在浏览器中访问文件来实行任意代码,从而完备掌握做事器。

跨站脚本

关于 PHP 中的跨站脚本攻击,你想知道的都在这里

同样地,预防 XSS 和 SQL 注入是一样大略的。
我们有大略而易用的 API 来分离文档构造(structure of a document)和添补的数据。

然而,实际上还有很多 Web 开拓程序员仍是通过天生一大串 HTML 代码作为相应的形式开拓。
并且,这不是 PHP 独占的现实,这是所有 Web 开拓程序员都该当重视的。

减少 XSS 漏洞不失落为一个好方法。
总之,前面谈及的浏览器安全的章节就显得十分干系了。
简言之:

只管即便避免输出和输入(Always escape on output, never on input)。
如果你把已洗濯的数据(sanitized data)保存在数据库,然后在其它地方被创造了 SQL 注入漏洞,攻击者将通过恶意程序污染这些受信赖的已洗濯数据(trusted-to-be-sanitized record),从而绕开 XSS 保护。
如果你的框架有一个供应自动高下文过滤的模板引擎,那就利用它吧。
这些事情可由框架安全地做到。
echo htmlentities($ string,ENT_QUOTES | ENT_HTML5,'UTF-8') 是一种安全、有效的方法阻挡UTF-8编码的网页上的所有 XSS 攻击,但不是任何 HTML 都有效。
如果你的环境哀求你利用 Markdown 而不是 HTML ,那就不要利用 HTML 了。
如果你须要利用原生 HTML(没有利用模板引擎),参阅第一点,并且利用 HTML Purifier 吧。
HTML Purifier 不适宜转义为 HTML 属性高下文(HTML attribute context)。

跨站要求假造

跨站要求假造(CSRF)是一种稠浊的代理攻击,通过勾引用户的浏览器代表攻击者实行恶意的 HTTP 要求(利用的是该用户的权限)。

这在一样平常情形下是很随意马虎办理的,只需两步:

利用 HTTPS 。
这是先决条件。
没有 HTTPS 的话,任何保护方法都是薄弱的,虽然 HTTPS 本身并不防御 CSRF 。
增加基本的 Challenge-response authentication。
为每个表单添加一个隐蔽的表单属性。
添补一个密码安全的随机值(称为令牌)。
验证是否供应了隐蔽的表单属性,以及是否匹配上期望值。

我们写了一个名为 Anti-CSRF 的库,并且:

你可以使每个令牌只能利用一次,以防止重放攻击。
多个令牌存储在后端。
一旦令牌获取完,令牌会循环利用。
每个令牌可以绑定特定的 URL 。
如果某个令牌透露了,它不能在不同的高下文利用。
令牌可以绑定特定的 IP 地址。
v2.1 后,令牌可以重复利用(例如供 Ajax 利用)。

如果你没有利用防止 CSRF 漏洞的框架,请将 Anti-CSRF 放在一边。
在不久的将来,SameSite cookies将许可我们更大略地避免CSRF攻击。

XML 攻击 (XXE, XPath Injection)

在处理大量 XML 的运用程序中存在两个紧张的漏洞:

XML External Entities (XXE)XPath 注入

除此之外, XXE 攻击可用作包含攻击代码确当地/远程文件的启动器。

早期版本的 Google Docs 被着名于 XXE ,但除了在很大程度上利用 XML 的商业运用程序之外,基本闻所未闻。

针对 XXE 打击的紧张缓解方法:

<?phplibxml_disable_entity_loader(true);

除 XML 文档外,XPath注入与 SQL 注入非常相似。

幸运的是,将用户输入通报给 XPath 查询的情形在 PHP 生态中非常罕见。

而不幸的是,这也意味着 PHP 生态中不存在可用的最佳避免方法(预编译和参数化 XPath 查询)。
最好的办法是在任何涉及 XPath 查询的数据上设置许可利用的字符白名单。

<?phpdeclare(strict_types=1);class SafeXPathEscaper{ / @param string $input @return string / public static function allowAlphaNumeric(string $input): string { return \preg_replace('#[^A-Za-z0-9]#', '', $input); } / @param string $input @return string / public static function allowNumeric(string $input): string { return \preg_replace('#[^0-9]#', '', $input); }}// Usage:$selected = $xml->xpath( \公众/user/username/\"大众 . SafeXPathEscaper::allowAlphaNumeric( $_GET['username'] ));

白名单总会比黑名单更安全。

反序列化和 PHP 工具注入

深入: 在PHP中安全地实现(反)序列化

如果你将不可信的数据通报给unserialize(),则常日是这两个结果之一:

PHP 工具注入,它能用于启动 POP 链(POP chain)并触发其他误用工具的漏洞。
PHP 阐明器本身的内存破坏。

大多数开拓职员更喜好利用JSON序列化,这是对其软件安全状况的显著改进。
但请记住,json_decode()随意马虎受到散列冲突谢绝做事(Hash-DoS)攻击。
不幸的是,PHP的Hash-DOS问题还没有得到彻底办理。

从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 地址,以减轻重复的违规者。

密码散列

深入:2016 年,如何安全地保存用户密码

安全的密码存储曾经是一个激烈辩论的话题,但现在实现起来相称微不足道,特殊是在 PHP 中:

<?php$hash = \password_hash($password, PASSWORD_DEFAULT);if (\password_verify($password, $hash)) { // Authenticated. if (\password_needs_rehash($hash, PASSWORD_DEFAULT)) { // Rehash, update database. }}

你乃至不须要知道在后台利用什么算法,由于如果你利用最新版本的 PHP ,你也将利用当前最新的技能,用户的密码将会自动进行升级(只要有新的默认算法可用)。

无论你做什么,都不要做 WordPress 所做的事情。

从 PHP 5.5 到 7.2 ,默认算法都是 Bcrypt 。
在未来,它可能会切换到得到密码哈希大赛冠军的 Argon2 。

如果你以前没有利用password_ API ,那须要迁移遗留哈希,请确保以这种办法进行。
很多公司搞错了, 最有名的是雅虎。
最近,缺点地履行传统哈希升级彷佛导致了苹果的iamroot缺点。

通用加密

这是一些我们详细写了的话题:

Using Encryption and Authentication Correctly (2015)Recommended: Choosing the Right Cryptography Library for your PHP Project: A Guide (2015)Recommended: You Wouldn't Base64 a Password - Cryptography Decoded (2015)Cryptographically Secure PHP Development (2017)Recommended: Libsodium Quick Reference: Similarly-Named Functions and Their Use-Cases (2017)

一样平常来说,你总是希望利用 Sodium cryptography library(libsodium)进行运用层加密。
如果你须要支持早于 7.2 的 PHP 版本(像 5.2.4),你可以利用sodium_compat,基本上可以假设你的用户也是 7.2 。

在特定情形下,由于严格的算法选择和互操作性,你可能须要不同的库。
如有疑问,请咨询密码专家和密码工程师,理解密码选择是否安全(这是我们供应的做事之一)。

随机性

深入:如何在 PHP 中天生安全的整数和字符串?

如果你须要随机数字,请利用random_int()。
如果你须要随机字节字符串,请利用random_bytes()。
不要利用mt_rand(),rand()或uniqid()。

如果你须要从秘密种子(secret seed)天生伪随机数(pseudorandom),请利用SeedSpring,而不是srand()或mt_srand()。

<?phpuse 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 。

无论你终极利用什么,请确保利用的确定性,以确保始终可以拥有最新的 CACert 软件包,从而许可启用最严格的 TLS 证书验证设置并保护做事器的出站 HTTPS 要求。

安装 Certainty 很大略:

composer require paragonie/certainty:^1

利用 Certainty 也很大略:

<?php use ParagonIE\Certainty\RemoteFetch; $latestCACertBundle = (new RemoteFetch())->getLatestBundle(); # cURL users: $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 users: / @var \GuzzleHttp\Client $http / $repsonse = $http->get( 'https://example.com', [ 'verify' => $latestCACertBundle->getFilePath() ] );

这样可以保护你免受网络做事器与集成的任何第三方 API 之间的中间人攻击。

我们真的须要 Certainty 吗?

保护你的系统, Certainty 并不是严格的哀求。
短缺它并不是什么漏洞。
但如果没有 Certainty ,开源软件必须预测操作系统的 CACert 软件包的存在位置,如果预测缺点,它每每会失落败并导致可用性问题。
从历史上看,这勉励了许多开拓职员只是禁用证书验证,以便他们的代码“正常事情”,却没故意识到他们只是将运用程序变成主动攻击。
Certainty 通过将 CACert 捆绑在最新的可预测位置来肃清这种勉励。
Certainty 还为希望运行自己的内部 CA 为企业供应大量的工具。

谁禁用了证书验证?

盛行的内容管理系统(WordPress,Magento 等 CMS)的插件/扩展开拓者!
这是我们试图在生态系统层面上办理的一个巨大的问题。
它不是伶仃的任何特定的 CMS ,你会创造这些不屈安的插件等都是类似的。

如果利用了类似的 CMS ,请在插件中搜索CURLOPT_SSL_VERIFYPEER和CURLOPT_SSL_VERIFYHOST,你可能会创造有几个将这些值设置为FALSE。

避免的事情

不要利用mcrypt。
这是一个十多年来没有开拓出来的密码学库。
如果你遵照我们的 PHP 版本建议,这该当是一个随意马虎避免的缺点,由于mcrypt不再被 PHP 7.2 和更新的版本支持。
配置驱动的安全建议该当大部分地忽略。
如果你正在阅读 PHP 安全性指南,并见告你变动 php.ini 设置而不是编写更好的代码,那么你可能正在阅读过期的建议。
关闭窗口并转到一些和register_globals无关的文章上吧。
不要利用 JOSE(JWT,JWS,JWE),这是一套互联网标准,它编纂了一系列随意马虎出错的密码设计。
只管由于某种缘故原由,被写入了标准,也吸引了很多传道人。
加密 URL 参数是公司常用来模糊元数据的反模式(例如,我们有多少用户?)。
它带来了履行缺点的高风险,也造成了缺点的安全感。
我们在链接的文章中提出了一个更安全的选择。
除非迫不得已,否则不要供应“我忘却了我的密码”的功能。
不要讳言:密码重置功能是一个后门。
有一些方法可以履行以抵御合理的威胁模型,但高风险用户该当不被考虑。
避免利用 RSA,改用 libsodium 。
如果你必须利用 RSA ,请确保指定 OAEP 添补。

<?php openssl_private_decrypt( $ciphertext, $decrypted, // Plaintext gets written to this variable upon success, $privateKey, OPENSSL_PKCS1_OAEP_PADDING // Important: DO NOT OMIT THIS!);

如果你不得不该用 PKCS#1 v1.5 添补,那么无论你与哪个集成在一起,险些肯定会受到 ROBOT 的影响,请以许可明文透露和署名假造的漏洞将其报告给相应的供应商(或 US-CERT )。

专业用法

现在你已经节制了在 2018 年及往后构建安全 PHP 运用程序的根本知识,接下来我们来看一些更专业的用法。

可搜索的加密

深入:利用PHP和SQL构建可搜索的加密数据库

可搜索的加密数据库是可取的,但被广泛认为是不太可能实现的。
上面链接的博客文章试图通过改进我们办理方案来实现,但实质上是这样的:

设计你的架构,以便数据库(database compromise)不会让攻击者访问你的加密密钥。
用一个密钥加密数据。
基于 HMAC 或具有静态盐的安全 KDF (secure KDF with a static salt)创建多个索引(具有自己独特的密钥)可选:截断步骤3的输出,将其用作布隆过滤器(Bloom filter)在 SELECT 查询中利用步骤3或4的输出解密结果。

在这个过程中的任何一步,你都可以根据实际利用情形进行不同的权衡。

没有 Side-Channels 的基于令牌的身份验证

深入: Split Tokens: Token-Based Authentication Protocols without Side-Channels

说到数据库(上一节),你是否知道 SELECT 查询理论上可能是定时信息泄露的来源?

大略的缓解方法:

把你的认证令牌分为两半一半在 SELECT 查询中利用后一半在恒定的韶光(constant-time)验证可以选择将后半部分的散列存储在数据库中。
这对付只能利用一次的令牌是故意义的,例如 密码重置或“在此打算机上记住我”的令牌

纵然可以利用定时泄露来盗取一半的令牌,剩下的也须要暴力破解才能成功。

开拓安全的API

深入: Hardening Your PHP-Powered APIs with Sapient

我们写了 SAPIENT (the Secure API ENgineering Toolkit),让做事器到做事器验证的通报变得大略易行。
除了 HTTPS 供应的安全性之外,Sapient许可你利用共享密钥或公钥来加密和验证。
这使得纵然存在中间攻击者,并设有泼皮证书颁发机构,你也可以利用Ed25519对 API 要乞降相应进行身份验证,或者将加密到只能由吸收方做事器的密钥解密的目标做事器。
由于每个 HTTP 体都通过安全密码进行身份验证,以是可以安全地利用它来代替stateful token juggling protocols(例如 OAuth)。
但是,在密码学方面,在做任何不规范的事情之前,总要确保他们的实现是由专家研究的。

所有Sapient利用的密码算法都由Sodium cryptography library供应。

进一步阅读:

Sapient DocumentationSapient TutorialSapient Specification

Paragon Initiative Enterprises已经在其许多产品(包括许多开源软件项目)中利用了Sapient,

并将连续添加软件项目到Sapient用户群中。

利用Chronicle记录安全事宜

深入: Chronicle Will Make You Question the Need for Blockchain Technology

Chronicle是一个基于散列链数据构造的仅追加密码分类账(append-only cryptographic ledger),具有很多吸引公司“区块链”技能的属性,而不会过分矫枉过正。

除了仅追加密码分类账(append-only cryptographic ledger)这个具有创造性的用例之外,Chronicle集成到SIEM中时,也可以十分有亮点,由于你可以将安全关键事宜发送到私人Chronicle中,并且它们是不能被改变的。

如果你的Chronicle设置为将其择要散列交叉署名到其他Chronicle实例,或者如果有其他实例配置为复制你的Chronicle内容,攻击者就很难修改你的安全事宜日志。

在Chronicle的帮助下,你可以得到区块链所承诺的弹性特性(resilience),而没有任何隐私,性能或可伸缩性问题。

要将数据发布到本地Chronicle,你可以利用任何与Sapient-compatible API,但最大略的办理方案称为Quill。

作者的一些话

一些聪明的读者可能把稳到我们引用了很多我们自己的事情,包括博客文章和开源软件。
(当然也不仅仅引用了我们自己的事情)

这绝不是有时的。

自从我们在 2015 年初成立以来,一贯在编写安全库并参与提高 PHP 生态系统安全性的事情。
我们已经涉足了很多领域,而且我们的安全工程师(他们最近推动了更安全的加密技能加入 PHP 核心,就在最近的 PHP 7.2 中)自我包管地说,并不善于自我炒作,或是对已经做过的事情持续激情亲切。
但你很可能没有听说我们多年来开拓的工具或库。
对付这个,深感抱歉。

不论如何,我们也不可能成为各方面的先行者,以是我们尽可能地选择与重视公共利益而不是梦想小利的行业专家事情。

这也是为什么浏览器安全的许多章节都参考了 Scott Helme 和他公司的事情,他们在为开拓职员供应这些新的安全功能方面具有可访问性和可理解性。

本指南当然不会是详尽的。
编写不屈安代码的方法险些和编写代码的方法一样多。
安全是一种心态,而不是目的地。
随着上面所写的统统,以及后面涉及的资源,我们希望这将有助于全天下的开拓职员,从本日开始用 PHP 编写安全的软件。

资源

如果你已经按照本页上的所有内容进行了操作,并且须要更多内容,则可能会对我们策划的阅读列表感兴趣,以便学习运用程序安全性。

如果你认为自己编写的代码足够安全,并希望我们从安全工程师的角度对其进行评判,这也是我们为客户供应的做事。

你如果为一家要进行合规性测试(PCI-DSS,ISO 27001等)的公司事情,可能还想聘请我们公司来审核你的源代码。
我们的流程比其他安全咨询公司更适宜开拓者。

接下来是 PHP 和信息安全社区供应的资源列表,这些资源帮助互联网更加安全。

PHP: The Right Way:当代 PHP 开拓的实用指南,免费在线。
Mozilla's SSL Config GeneratorLet's Encrypt:证书颁发机构,通过供应免费 TLS 证书,为创建更安全的 Internet 做了很多。
Qualys SSL Labs:为 TLS 配置供应了一个快速而大略的测试套件。
险些每个人都利用这个来办理他们的密码组和证书问题,情由很充分:It does its job well.Security Headers:可以考验你的网站在利用浏览器安全功能来保护用户方面的表现如何。
Report-URI:一个很好的免费资源,供应监控 CSP/HPKP 等安全策略的实时安全报告做事。
他们给你一个 Report-URI,你可以通报给你的用户的浏览器,如果有什么事情发生或有人创造 XSS 攻击媒介,他们会投诉Report-URI。
Report-URI 会汇总这些缺点,并许可你更好地对这些报告进行疑难解答和分类。
PHP Security Advent Calenda:RIPSTech旗下的团队卖力。
Snuffleupagus:一个面向安全的 PHP 模块(Suhosin的精神继续者,彷佛在很大程度上会被放弃)PHP Delusions:一个致力于更好地利用 PHP 的网站。
大部分的口吻是非常有见地的,作者对技能的准确性和清晰度的奉献使得值得一读,特殊是对付那些不太喜好 PDO 功能的人来说。
Have I Been Pwned?:帮助用户创造他们的数据是否属于过期数据透露。

结尾

原文地址:The 2018 Guide to Building Secure PHP Software - P.I.E. Staff

转载地址原文地址请点击下方链接

标签:

相关文章

大数据拓扑,介绍现代信息社会的神经网络

在信息技术飞速发展的今天,大数据已成为推动社会进步的重要力量。而大数据拓扑,作为大数据领域的关键技术之一,正逐渐成为现代信息社会的...

Web前端 2024-12-15 阅读0 评论0