【问题标题】:Protect PostgreSQL database connection保护 PostgreSQL 数据库连接
【发布时间】:2012-02-22 13:25:14
【问题描述】:

我目前正在从事一个 php/PostgreSQL/JQuery 项目,并且我是所有这些领域的绝对初学者。在 PHP 中,要连接到我的数据库,我发现最好的方法是包含一个 php 在所有需要它的 php 脚本中使用用户名和密码编写脚本,就像这样。 include('../scripts/pgconnect.php');

使用 pgconnect.php :

$conn_string = "dbname=mydb user=myuser password=mypass";

$db = pg_connect($conn_string);

if(!$db){ die("Connection à la base impossible -> " . pg_errormessage($db));}

我相信你们所有的安全专家都会对此一笑置之,那么你能告诉我什么是让用户远离窥探的最佳方法吗? 我在堆栈溢出中发现了使用 env 变量的建议,但我觉得它并不安全。

【问题讨论】:

  • 您可以通过单击答案左侧的 V 来接受一个 (!) 答案。它会让人们有动力回答你未来的问题。所以,请选择最佳答案。

标签: php security postgresql


【解决方案1】:

PHP 是一种服务器端语言。这意味着当请求的页面被发送回客户端时,所有 PHP 代码都被解析并“删除”。只要您是唯一能够查看您的文件的人,就没有恐惧。

是否将其存储在 (env) 变量中不会有任何区别。

这段代码绝对没有错;)


编辑:

但是,当您执行 SQL 查询时,您需要小心。通常,您使用用户输入(URL 或 POST 数据)来设置查询中的某些值。例如:

$sql = 'SELECT * FROM `table` WHERE `id`=' . $_GET['id'];

$_GET['id'] 变量在 URL (index.php?id=4) 中设置。

如果他们将值 4 更改为一些 SQL 查询,他们几乎可以对您的数据库执行任何操作。这称为SQL injection。这确实是使用数据库的 Web 应用程序的最大威胁。

有多个修复。

  • 清理输入(确保输入不包含 SQL 语法)
  • 准备报表

现在,我不熟悉 PostgreSQL,但显然 PHP 模块有能力发送准备好的语句。这使您可以将带有未知值的查询作为问号发送,然后再发送这些值。

$sql = 'SELECT * FROM `table` WHERE `id`=?';
// send prepared statement

$value = $_GET['id'];
// send the value

这样数据库可以判断该值是没有查询。

就像我说的,我对 PostgreSQL 并不熟悉,但我相信有一些教程可以指导你一路走好!


另一个编辑:

因为我是个好人,所以我找到了方法!您需要使用函数pg_prepare()pg_execute()。像这样:

// This is a name to allow the database to identify the prepared statement
$queryname = 'my_query';

// Setting up our query with "empty" values
$sql = "SELECT * FROM `table` WHERE `column`='$1' AND `column`='$2'";

// Setting our values to send afterwards
$values = array(
    $_GET['first_value'], // The first value that will replace $1
    $_GET['second_value'] // The second value that will replace $2
);

$result = pg_prepare($connection, $queryname, $sql); // Send the query to the database
$result = pg_execute($connection, $queryname, array($value)); // Send the values

最后一次编辑(我发誓):

如果您决定将配置变量放在外部文件中,比如说 configuration.php,请确保该文件以 .php 扩展名结尾。如果您使用不同的扩展程序,人们可能能够找到它并以纯文本形式查看它。如果使用 PHP 扩展,他们将无法看到任何内容,因为就像我说的,PHP 已被解析并删除。

【讨论】:

  • 抱歉,这是个糟糕的建议。您应该从不将数据库密码保存为纯文本,尤其是不要保存在 PHP 文件中。
  • 当然不会发送给客户端。除非有错误。或者一些脆弱性。或内部人员访问文件。或者... 为什么世界领先的 CMS 会将文件保存为纯文本 PHP 文件?我没有线索。显然他们也没有。您的其余评论毫无意义,完全误解了加密、保护和安全性。我建议你在称自己为专业开发人员之前对这些主题做一些功课。
  • 很抱歉,我的措辞如此苛刻,但您确实需要醒悟到不安全开发的现实以及这给您带来的真正风险。我们不断听到一些大公司的这些重大成就,这一切都始于这样的事情。当然,不仅仅是你。
  • 大多数现实世界的漏洞利用都是关于密码如何存储在 Web 应用程序中的。几乎每一个大规模的利用都是正是。您所说的浏览源代码不是答案,而是问题所在-代码中不应包含凭据。你没听说过 Kerckhoff 原理吗?不幸的是,我并不精通 PHP,这就是为什么我一直在寻找特定于 PHP 的解决方案 - 有解决方案,从不以纯文本形式保存密码开始。
  • 我也不知道您为什么认为在 PHP 文件中存储用户的硬编码密码是个好主意。如果它是共享产品,则称为后门,并且将肯定归类为安全漏洞。我还建议您查看OWASP Top 10,以获取 webapps 中主要漏洞的不错列表。请注意,A7 表示存储安全性不足。这已在 2013 年候选发布版中提升为 A6
【解决方案2】:

我使用环境变量来存储db认证信息:即db的主机/用户/密码在Apache配置的SetEnv命令中,出现在$_SERVER中。

为什么要这样做?

  1. 开发和生产环境需要不同的值,因此有必要让应用程序读取某种环境配置。
  2. 应用程序代码位于源代码存储库中,可轻松浏览...将身份验证秘密嵌入其中将使它们同样广泛可用。

环境变量不是唯一的解决方案:例如,包含一个设置某种配置对象的文件也可以。但大多数人似乎都在进化一些系统,以便将配置设置(并且只是设置)放在一个可更改的点上,与使用这些设置的代码分开,后者会按照完全不同的时间表进行更改。

【讨论】:

  • 谢谢大家的建议。我会仔细阅读 pg_prepare 文档(不知道那个)再考虑一下用于用户/传递信息的环境变量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-26
  • 1970-01-01
  • 2016-10-08
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多