6

我通常在自己查找信息方面非常足智多谋,但是当涉及到这个主题时,确实令人生畏,那里有大量的东西。我有点信息过载。

我找到了几十篇关于个别安全主题的文章,但我无法了解全局以及它们在实践中是如何结合在一起的。

我需要查看鸟瞰路线图。举这个假设的例子:

一个简单的假设“评论”部分:

  • 注册:创建要安全存储在 MySQL 表中的密码/用户名组合。

  • 登录。

  • 发表评论。

在这个最基本的案例中要遵循的“安全路线图”是什么?

地球上的每本教程和 PHP 书籍都使用 MySQL 扩展并没有帮助,如果我理解正确,这是一个坏主意吗?

4

3 回答 3

9

A. 一般来说……</h2>
  1. 我在这里假设程序员不是服务器管理员,并且服务器管理员或多或少知道如何在默认情况下正确安全地配置 LAMP。

    当然,如有必要,程序员可以在php.ini位于 web 根目录的自定义文件中覆盖大多数 PHP 设置。

  2. 使用 MVC 框架。

    我使用 CakePHP。该框架本身在确保基本健全和安全的编码实践方面大有帮助。

B. 传入数据……</h2>
  1. 在以编程方式操作数据之前$_GET, $_POST, $_COOKIE,和之前清理和验证包含的所有数据。$_REQUEST

  2. SQL 注入

    定义:利用应用程序数据库层中出现的安全漏洞的代码注入技术。当用户输入被错误地过滤为嵌入在 SQL 语句中的字符串文字转义字符或用户输入不是强类型并因此意外执行时,就会出现此漏洞。

    预防:使用诸如mysqli或之类的库的参数化查询PDO。请参阅OWASP SQL 注入备忘单mysql_real_escape_string(不推荐使用字符串转义函数)

  3. 跨站脚本 (XSS)

    定义:安全漏洞通常存在于 Web 应用程序中,允许恶意 Web 用户将代码注入到其他用户查看的网页中。此类代码的示例包括客户端脚本(即 JavaScript)。

    预防: 上下文相关的输出转义和编码。请参阅OWASP XSS 预防备忘单

C. 浏览器请求……</h2>
  1. 跨站请求伪造 (CSRF)

    定义:恶意利用网站的类型,其中未经授权的命令从网站信任的用户传输。与利用用户对特定站点的信任的跨站点脚本 (XSS) 不同,CSRF 利用站点在用户浏览器中的信任。

    预防:生成一个唯一的“令牌”,通常是在浏览器会话开始时。POST在所有和GET请求中传递令牌。在POST/GET操作之后,检查会话中是否存在令牌,然后确认POST/发送GET的令牌与会话中存储的令牌相同。(像 CakePHP 这样的 MVC 框架使得在整个应用程序中统一实现这一点相对容易。)

D. 会议……</h2>
  1. 终止会话时销毁会话数据

    会话完成(“注销”)后,销毁其数据,不要只清除 cookie(否则恶意用户可能只是重新启用 cookie 并再次使用会话)。$_SESSION通过将其分配给空数组来取消设置所有索引。

  2. 将会话存储为 Web 根目录或数据库中的文件

    在服务器上保存会话的默认路径可能会被劫持——尤其是在共享主机环境中。

E. 密码……</h2>
  1. 强制选择强密码

    • 密码中需要数字、符号、大小写字母

    • 密码长度应在 12 到 14 个字符左右

  2. 哈希和加盐所有密码

    不要使用或sha1()散列密码md5()hash()。它们不是为此而设计的。您将需要使用bcrypt或 PBDFK2 之类的函数。关于这个问题有一些非常好的建议。您的盐值应该是完全随机的,并存储在数据库中(这不是真正的秘密)。一个额外的秘密值(通常称为“pepper”)可以存储在您的应用程序中,并在使用 bcrypt 之前附加到密码中,但目前尚不清楚这真正增加了多少安全性。

F. 在php.ini位于 Web 根目录的自定义中……</h2>
  1. 禁用 register_globals

    预防: register_globals = Off

  2. 禁用魔术引号

    预防: magic_quotes_gpc = Off

  3. 禁用错误报告

    预防: display_errors = Off

  4. 启用错误记录并将日志文件保存到 Web 根目录之上的目录

    预防:

    log_errors = On; 
    ignore_repeated_errors = On; 
    html_errors = Off; 
    error_log = /path/above/webroot/logs/php_error_log
    
  5. 将会话数据存储在 Web 根目录上方的目录中

    预防: session.save_path = /path/above/webroot/sessions

G. 在.htaccess位于 Web 根目录的文件中……</h2>
  1. 在站点范围内禁用目录列表

    预防: Options -Indexes

H. 有价值/敏感文件……</h2>
  1. 通过将此类文件存储在 Web 根目录之上来防止未经授权的访问/下载

    这包括站点管理/仅限成员部分和站点/数据库配置文件!

  2. 使用中间脚本内联或作为附件提供文件

  3. 更新您的脚本(WordPress、PHPMyAdmin 等)。

  4. 只有在使用 PHPMyAdmin 时才允许访问它。这可以防止人们在您的安装中使用零日漏洞。

一、上传的文件……</h2>
  1. $_FILES在将其用于任何类型的数据操作之前验证存储的文件名

  2. 请注意,提供的 mime 类型可能会被欺骗或以其他方式错误

  3. 将所有用户上传的文件移动到 web 根目录以上的目录!!!

  4. 不要使用 include() 执行/提供上传的文件

  5. 尽量不要提供内容类型为“application/octet-stream”、“application/unknown”或“plain/text”的文件</p>

J. 杂项…</h2>
  1. 开发人员在开发站点/应用程序期间创建和使用的 Web 根目录中的所有“实用程序”文件/程序,不打算或不要求将来的站点用户访问,或以其他方式构成某种安全风险,应网站上线时删除。

    例如,这包括一个phpinfo.php文件(打印结果的文件phpinfo())、数据库实用程序脚本等。

于 2012-09-04T05:48:16.383 回答
1

好吧,为了安全起见,首先从构建 mysql 端开始,然后再进行服务器端编程(例如 php)。创建存储过程、视图、准备好的语句……也许是事务。他们是他们使应用程序更安全..太糟糕的 php 程序员不经常使用它们。

然后当你来到服务器端编程时,使用 pdo(我比 mysqli 更喜欢它),它使你能够绑定参数(这也是 asp.net 中使用的一种安全策略)。

您还可以使用验证策略..查看输入是否是电子邮件、信用卡..等,这会给您一个期望的白名单(建立一个黑名单是一个不太安全的想法..我记得从一些黑客书籍)。

可以根据您的需要使用转义和过滤,您可能想要去除标签的密码,但您可能不会使用注释。

祝你好运!

于 2012-09-04T05:58:10.360 回答
0

通常的建议是清理来自客户端的所有输入。通常,您希望清除输入中的任何形式的代码。这些是目标。以下是可用的防线。

首先,如果程序的设计很紧凑,问题就可以得到缓解——例如,进行适当的表单验证以清除不需要的符号将防止 SQL 注入或跨站点脚本。一个相当开放的输入,比如评论,虽然更狡猾。

其次,你必须清理输入。通常有几道防线。您可以去除标签或逃避它们,尽管这对更复杂的注入没有帮助。您可以在显示它们时转义输出。

第三,您还可以使用参数化查询来保护您存储输入的方式。这主要是防止 SQL 注入。

有一些开源库可以帮助清理您的输入,例如HTML Purifier

所以总结一下:

  • 正确建模您的输入。什么输入可以接受,什么不可以

    保存到数据库时剥离或转义输入标签,或在显示时清理它们。

    使用 MySQL 支持的参数化查询

于 2012-09-04T05:52:05.327 回答