我通常非常有资源自己寻找信息,但是当谈到这个问题时,那里的东西确实令人生畏。我收到了一些信息超载。
我发现了很多关于个人安全主题的文章,但是我无法理解大局以及它们在实践中如何相互结合。
我需要看一个鸟瞰路线图。拿这个假设的例子:
一个简单的假设“评论”部分:
注册:创建一个密码/用户名组合,安全地存储在MySQL表中。
登录。
发表评论。
这个最基本的案例会有什么“安全路线图”?
这个星球上的每本教程和PHP书都使用了MySQL扩展,这是没有用的,如果我理解的话,这是一个坏主意吗?
答案 0 :(得分:9)
我假设程序员不是服务器管理员,并且服务器管理员或多或少知道默认情况下如何正确安全地配置LAMP。
当然,如果有必要,程序员可以覆盖位于Web根目录中的自定义php.ini
文件中的大多数PHP设置。
使用MVC框架。
我使用CakePHP。该框架本身在很大程度上确保了从根本上健全和安全的编码实践。
在以编程方式操作数据之前,清除并验证$_GET, $_POST, $_COOKIE,
和$_REQUEST
中包含的所有数据。
SQL注入
定义:代码注入技术,利用应用程序数据库层中发生的安全漏洞。如果对SQL语句中嵌入的字符串文字转义字符的用户输入进行了错误的过滤,或者用户输入没有强类型,从而意外执行,则会出现此漏洞。
预防:使用mysqli
或PDO
等库进行参数化查询。请参阅OWASP SQL Injection cheat sheet(字符串转义函数,如mysql_real_escape_string
不推荐)
跨站点脚本(XSS)
定义:通常在Web应用程序中发现的安全漏洞,允许恶意Web用户将代码注入其他用户查看的网页。此类代码的示例包括客户端脚本(即JavaScript)。
预防: 依赖于上下文的输出转义和编码。请参阅OWASP XSS prevention cheat sheet。
跨站点请求伪造(CSRF)
定义:网站的恶意利用类型,通过该网站从网站信任的用户传输未经授权的命令。与利用用户对特定站点的信任的跨站点脚本(XSS)不同,CSRF利用站点在用户浏览器中的信任。
预防:通常在浏览器会话启动时生成唯一的“令牌”。在所有POST
和GET
请求中传递令牌。在POST
/ GET
操作之后,检查会话中是否存在令牌,然后确认POST
/ GET
发送的令牌与存储在中的令牌相同会议。 (像CakePHP这样的MVC框架使得在整个应用程序中统一实现相对容易。)
杀死会话时销毁会话数据
会话完成后(“注销”),销毁其数据,不要只清除cookie(恶意用户只能重新启动cookie并再次使用会话)。通过将其分配给空数组来取消设置$_SESSION
中的所有索引。
将会话存储为Web根目录或数据库上的文件
可以劫持在服务器上保存会话的默认路径 - 尤其是在共享托管环境中。
强制选择强密码
要求密码中的数字,符号,大写和小写字母
密码长度应为12到14个字符
哈希和盐所有密码
请勿使用sha1()
,md5()
或hash()
来散列密码。它们不是为此而设计的。您将需要使用bcrypt或PBDFK2之类的函数。那里有some really good suggestions on this question。你的盐值应该是完全随机的,并存储在数据库中(它不是真正的秘密)。一个额外的秘密值(通常称为" pepper")可以存储在您的应用程序中,并在使用bcrypt之前添加到密码中,但是不清楚它真正增加了多少安全性。
php.ini
... 禁用register_globals
预防: register_globals = Off
禁用魔法引号
预防: magic_quotes_gpc = Off
禁用错误报告
预防: display_errors = Off
启用错误记录并将日志文件保存到Web根目录
上方的目录中<强>预防:强>
log_errors = On;
ignore_repeated_errors = On;
html_errors = Off;
error_log = /path/above/webroot/logs/php_error_log
将会话数据存储在Web根目录
上方的目录中 预防: session.save_path = /path/above/webroot/sessions
.htaccess
文件中...... 在网站范围内禁用目录列表
预防: Options -Indexes
通过在Web根目录上存储此类文件来防止未经授权的访问/下载
这包括站点管理/仅限成员的部分和站点/数据库配置文件!!
使用中间脚本来内联或作为附件提供文件
更新脚本(WordPress,PHPMyAdmin等)。
仅允许在使用PHPMyAdmin时访问它。这可以防止人们在您的安装中使用零日攻击。
验证存储在$_FILES
中的文件名,然后再将其用于任何类型的数据操作
请注意提供的mime类型可能会被欺骗或出错
将所有用户上传的文件移至web root上面的目录!!!
不要使用include()
尝试不提供内容类型为“application / octet-stream”,“application / unknown”或“plain / text”的文件
开发人员在开发站点/应用程序期间创建和使用Web根目录中的所有“实用程序”文件/程序,这些文件/程序不是未来或将要由未来的站点用户访问,或以其他方式构成一些当网站上线时,应该删除那种安全风险。
例如,这包括phpinfo.php
文件(打印phpinfo()
结果的文件),数据库实用程序脚本等。
答案 1 :(得分:1)
好吧,为了安全起见,首先从构建mysql端开始,然后再转到服务器端编程(例如php)。或许创建存储过程,视图,预处理语句。他们是他们使应用程序更安全..坏的PHP程序员不经常使用它们。
然后当你来到服务器端编程时,使用pdo(我比mysqli更喜欢它),它使你能够绑定参数(这也是asp.net中使用的安全策略)。
你也可以使用验证策略..看看输入是否是一封电子邮件,一张信用卡..等等,它会给你一个白色的预期列表(建立黑名单是一个不太安全的想法......我记得从一些黑客书中读到这一点。)
根据您的需要,可以使用转义和过滤,您可能想要删除标签的密码,但您可能不会使用评论..
祝你好运!答案 2 :(得分:0)
通常的建议是清理来自客户端的所有输入。通常,您希望在输入中清除任何形式的代码。这些是目标。以下是可用的防线。
首先,如果程序的设计很紧,问题可以得到缓解 - 例如,通过适当的表单验证来清除不需要的符号会阻止SQL注入或跨站点脚本编写。一个相当开放的输入,如评论,虽然很苛刻。
其次,你必须清理输入。通常有几道防线。您可以剥离标签或将其转义,但这对于更复杂的注射无效。您可以在显示时转义输出。
第三,您还可以确保如何使用参数化查询存储输入。这主要是为了防止SQL注入。
有一些开源库可以帮助您清理输入,例如HTML Purifier
总结一下:
正确建模您的输入。什么输入是可接受的,什么不是
保存到DB时剥离或转义输入标记,或在清除时清除它们 显示。
使用参数化查询,MySQL支持