相关疑难解决方法(0)

围绕mysql_real_escape_string()的SQL注入

即使使用mysql_real_escape_string()函数,是否存在SQL注入的可能性?

考虑这个示例情况.SQL是用PHP构造的,如下所示:

$login = mysql_real_escape_string(GetFromPost('login'));
$password = mysql_real_escape_string(GetFromPost('password'));

$sql = "SELECT * FROM table WHERE login='$login' AND password='$password'";
Run Code Online (Sandbox Code Playgroud)

我听过很多人对我说,这样的代码仍然很危险,即使使用了mysql_real_escape_string()函数也可以破解.但我想不出任何可能的漏洞?

像这样的经典注射:

aaa' OR 1=1 --
Run Code Online (Sandbox Code Playgroud)

不工作.

你知道任何可能通过上面的PHP代码注入的注入吗?

php mysql sql security sql-injection

596
推荐指数
4
解决办法
22万
查看次数

PHP + PDO + MySQL:我如何从PHP中返回整数和数字列作为整数和数字?

我已经在Stack Overflow上重复了几次这个问题,但是没有一个能够充分探索这个问题(或者至少以一种对我有帮助的方式)

问题是数据库查询应该在PHP中为整数列返回整数数据类型.相反,查询将每列作为字符串类型返回.

我确保"PDO :: ATTR_STRINGIFY_FETCHES"为false,以确保结果不会被转换为字符串.

我见过的答案:

  • 它无法完成
    • 不,它正在Mac OS X上安装PHP/MySQL
  • 在代码中输入所有值
    • 不,我不会这样做
  • 不要担心,PHP是松散的类型
    • 我的数据输出为JSON并被许多其他服务使用,有些需要正确格式的数据

根据我的研究,我了解这是一个驱动程序实现问题.

许多消息来源声称MySQL本机驱动程序不支持返回数字类型.这似乎不正确,因为它适用于Mac OS X.除非他们的意思是" Linux上的MySQL本机驱动程序不支持该功能".

这意味着我在Mac OS X上安装的驱动程序/环境有一些特殊之处.我一直在尝试识别差异以便应用修复,但我受限于我对如何检查这些内容的了解.

差异:

  • OS X上的PHP是通过Home Brew编译和安装的
  • Ubuntu上的PHP是通过"apt-get install php5-dev"安装的
  • OS X上的PHP连接到也在OS X上运行的MySQL服务器
    • 服务器版本:5.1.71-log源分发
  • Ubuntu上的PHP连接到Rackspace云数据库
    • 服务器版本:5.1.66-0 + squeeze1(Debian)

Ubuntu环境

  • 版本:10.04.1
  • PHP 5.4.21-1 + debphp.org~lucid + 1(cli)(内置:2013年10月21日08:14:37)
  • php -i

    PDO_MYSQL

    用于MySQL的PDO驱动程序=>已启用客户端API版本=> 5.1.72

Mac OS X环境

  • 10.7.5
  • PHP 5.4.16(cli)(内置:2013年8月22日09:05:58)
  • php -i

    PDO_MYSQL

    用于MySQL的PDO驱动程序=>启用客户端API版本=> mysqlnd 5.0.10 - 20111026 - $ Id:e707c415db32080b3752b232487a435ee0372157 $

使用PDO标志

PDO::ATTR_CASE => PDO::CASE_NATURAL,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_ORACLE_NULLS …
Run Code Online (Sandbox Code Playgroud)

php mysql macos ubuntu pdo

76
推荐指数
2
解决办法
2万
查看次数

SQLSTATE[HY000]:一般错误:1835 LARAVEL 上的格式错误的通信数据包

突然得到

SQLSTATE[HY000]:一般错误:1835 格式错误的通信数据包(SQL:select * from tb_userswhere ( username= 121211) limit 1)

在 Laravel 上。

我已经检查过这个:MySQL: ERROR 2027 (HY000): Malformed packet,但似乎是另一种情况。

  1. 之前使用 SSH(使用:mysql -u -p)登录后,我已成功登录到 MySQL。
  2. 我已经成功地直接从远程 PC 登录到 MySQL(使用:mysql -h [IP] -u -p)。

但是我的 Laravel 出现了我之前提到的错误。有这方面的经验吗?

mysql mariadb laravel mariadb-10.3

48
推荐指数
4
解决办法
2万
查看次数

PDO准备的陈述有多安全

不久前开始使用PDO准备好的语句,据我所知,它可以为您完成所有的转义/安全性.

例如,假设$ _POST ['title']是一个表单字段.

$title = $_POST['title'];
$query = "insert into blog(userID, title) values (?, ?)"
$st = $sql->prepare($query);
$st->bindParam(1, $_SESSION['user']['userID'], PDO::PARAM_INT);
$st->bindParam(2, $title);
$st->execute();
Run Code Online (Sandbox Code Playgroud)

这真的很安全吗?我还要做别的吗?还有什么需要考虑的?

谢谢.

php mysql security pdo sql-injection

42
推荐指数
2
解决办法
2万
查看次数

多次使用绑定参数

我正在尝试为我的数据库实现一个非常基本的搜索引擎,其中用户可能包含不同类型的信息.搜索本身由几个联合选择组成,其中结果总是合并为3列.

然而,返回的数据是从不同的表中获取的.

每个查询使用$ term进行匹配,我将它作为准备参数绑定到":term".

现在,手册说:

调用PDOStatement :: execute()时,必须为要传递给语句的每个值包含唯一的参数标记.您不能在预准备语句中两次使用同名的命名参数标记.

我想,不是用termex替换每个:term参数:termX(x为term = n ++),必须有一个更好的解决方案吗?

或者我只需绑定X号:termX?

编辑发布我的解决方案:

$query = "SELECT ... FROM table WHERE name LIKE :term OR number LIKE :term";

$term = "hello world";
$termX = 0;
$query = preg_replace_callback("/\:term/", function ($matches) use (&$termX) { $termX++; return $matches[0] . ($termX - 1); }, $query);

$pdo->prepare($query);

for ($i = 0; $i < $termX; $i++)
    $pdo->bindValue(":term$i", "%$term%", PDO::PARAM_STR);
Run Code Online (Sandbox Code Playgroud)

好的,这是一个样本.我没有时间使用sqlfiddle,但如果有必要,我会稍后添加一个.

(
    SELECT
        t1.`name` AS resultText
    FROM table1 AS t1
    WHERE
        t1.parent = :userID
        AND …
Run Code Online (Sandbox Code Playgroud)

php mysql sql pdo

31
推荐指数
3
解决办法
2万
查看次数

如何传递PDO参数数组但仍指定其类型?

$sql = "SELECT * FROM table WHERE id LIKE CONCAT('%', :id, '%')
LIMIT :limit1, :limit2";
Run Code Online (Sandbox Code Playgroud)

我想仍然像这样使用数组输入:

$stmt->execute($array);
Run Code Online (Sandbox Code Playgroud)

否则我不能重复使用相同的方法来执行我的查询.

同时,:limit1和:limit2不起作用,除非它像这样输入:

$stmt->bindParam(':limit1', $limit1, PDO::PARAM_INT);
Run Code Online (Sandbox Code Playgroud)

我试图做两个但它不使用bindParams执行:

$stmt->bindParam(':limit2', $limit2, PDO::PARAM_INT);
$stmt->execute($array);
Run Code Online (Sandbox Code Playgroud)

它的方法是什么?

我以为我可以扩展PDOStatement并添加一个新方法"bindLimit"或其他东西,但我无法弄清楚PDO使用什么内部方法将参数绑定到变量.

php mysql pdo

18
推荐指数
2
解决办法
1万
查看次数

PHP MySQL PDO:如何保留zerofill int列的前导零

在从旧mysql_*()函数迁移到新PDO类的过程中,我又遇到了一个问题:我有一个下表:

CREATE TABLE `test` (
  `Id` tinyint(4) unsigned zerofill NOT NULL,
  `UserName` varchar(4) NOT NULL,
  `TestDecimal` decimal(6,0) unsigned zerofill DEFAULT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)

注意zerofill'ed IdTestDecimal字段.

如果我运行以下代码,使用旧mysql_*()函数:

$SqlQuery = "SELECT * FROM test";
$Sql_Result = mysql_query($SqlQuery);
var_dump(mysql_fetch_array($Sql_Result));
Run Code Online (Sandbox Code Playgroud)

我得到以下输出,正确的zerofilled Id:

array (size=6)
  0 => string '0001' (length=4)
  'Id' => string '0001' (length=4)
  1 => string 'alex' (length=4)
  'UserName' => string 'alex' (length=4)
  2 => string '000002' (length=6) …
Run Code Online (Sandbox Code Playgroud)

php mysql pdo

15
推荐指数
1
解决办法
2243
查看次数

PDO参数化查询的工作方式

请仔细阅读问题.这通常不是愚蠢的"我的代码不起作用!!!" 题.

当我使用预期的错误运行此代码时

try {
  $sth = $dbh->prepare("SELECT id FROM users WHERE name INN(?,?) ");
  $sth->execute(array("I'm","d'Artagnan"));
} catch (PDOException $e) {
    echo $e->getMessage();
}
Run Code Online (Sandbox Code Playgroud)

我收到此错误消息

您的SQL语法中有错误...在第1行'INN('我'','d \'Artagnan')'附近

但我多年来一直认为查询和数据是分开发送给服务器的,而且绝不干涉.因此我有一些问题(虽然我怀疑有人得到答案......)

  1. 它在哪里获得如此熟悉的字符串表示 - 引用和转义?它是否特别报告错误或是否是实际查询的一部分?
  2. 它是如何在真实中起作用的?它是否用占位符代替数据?
  3. 有没有办法获得整个查询,而不仅仅是一点点,用于调试目的?

更新

mysqli 是按预期做的:它会抛出一个错误说 near 'INN(?,?)'

php pdo parameterized-query

8
推荐指数
2
解决办法
780
查看次数

禁用PDO :: ATTR_EMULATE_PREPARES导致"未知"问题

只是一个关于PDO的ATTR_EMULATE_PREPARES属性的简单问题 - 简单地说,当保持默认值(true)时,一切正常,花花公子.然而,禁用它,好吧,我甚至没有得到PHP错误消息,只是浏览器警告告诉我"连接已重置".

这里参考的是我正在使用的代码示例

<?php
include_once("config.php");

try {
  $dbh = new PDO
  (
    "mysql:host=". DB_SERVER .";dbname=" . DB_NAME,
    DB_USER,
    DB_PASS,
    array
    (
      PDO::ATTR_PERSISTENT => true,
      PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
      PDO::ATTR_EMULATE_PREPARES => true
    )
  );
} catch(PDOException $e) {
  echo "<pre>";
  print_r("Error: " . $e);
  echo "</pre>";
  die();
}

$idNum = "1";

$sth = $dbh->prepare("SELECT * FROM `table` WHERE `id` = ?;");
$sth->bindParam(1,$idNum);
$sth->execute();
$res = $sth->fetch();
?>

<pre>
<?=print_r($res); ?>
</pre>
Run Code Online (Sandbox Code Playgroud)

从我可爱的测试表中很好地返回查询...

Array
(
    [id] => 1
    [field1] => q12w3e4r5t6y7u8i9
    [field2] …
Run Code Online (Sandbox Code Playgroud)

php mysql pdo

7
推荐指数
1
解决办法
5268
查看次数

用PDO支持服务器端预备语句?

给出类似的东西

DB()->prepare("SELECT * FROM mysql.general_log WHERE user_host LIKE ?");

$statement->execute( array('%console%') );

foreach($statement as $record){
    var_dump($record);
}
Run Code Online (Sandbox Code Playgroud)

general_log的内容是

*************************** 1. row ***************************
event_time: 2011-04-20 14:27:59
user_host: REDACTED[REDACTED] @ REDACTED [192.168.56.101]
thread_id: 30
server_id: 0
command_type: Connect
argument: REDACTED@REDACTED on REDACTED
*************************** 2. row ***************************
event_time: 2011-04-20 14:27:59
user_host: REDACTED[REDACTED] @ REDACTED [192.168.56.101]
thread_id: 30
server_id: 0
command_type: Query
argument: SELECT * FROM mysql.general_log WHERE user_host LIKE '%console%'
Run Code Online (Sandbox Code Playgroud)

我在一个令人厌恶的框架内工作(没有单元测试,没有文档,没有ryhme或原因)所以有可能在某个地方有人明确地禁用了MySQL准备语句,迫使PDO使用模拟模式......或者这是预期的行为?

PHP是PHP Version 5.2.10-2ubuntu6 MySQL的PDO驱动程序,客户端库版本5.1.41

更新:PDO()使用以下属性构造

PDO::ATTR_PERSISTENT => false
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION …
Run Code Online (Sandbox Code Playgroud)

php mysql pdo prepared-statement

6
推荐指数
2
解决办法
2259
查看次数