哈希密码的一部分被MySQL视为变量


Portion of Hashed password seen as variable by MySQL

使用phpass生成哈希,生成以下字符串:

$2a$08$KHiiru4yzYh141GUh2xIMew//bCc7rxMuY1rtDApwA66/czIiurLi

然后是标准查询:

"INSERT INTO su_auth ( 
                      AuthAlias, AuthUsername, 
                      AuthPass, 
                      AuthSessionID, AuthIP, AuthUserAgent
                    )
                    VALUES ( 
                      'Me', 'Myself',         
                      '$2a$08$KHiiru4yzYh141GUh2xIMew//bCc7rxMuY1rtDApwA66/czIiurLi', 
                       NULL, NULL, NULL
                    )"

当部分$KHiiru4yzYh141GUh2xIMew被视为空变量并作为空变量(即空值)提交时,会出现问题。因此存储的字符串是:$2a$08//bCc7rxMuY1rtDApwA66/czIiurLi。在$前面放一个反斜杠,但显然是不可行的。

为什么在带引号的字符串中会发生这种情况?为什么前面的$没有引发同样的反应?我能做些什么来预防呢?

您看到您所看到的原因是因为您使用了双引号字符串的查询。在PHP中,单引号字符串由PHP解释。因此,在您的情况下,PHP读取查询并看到一个变量$KHiiru4yzYh141GUh2xIMew

这个变量从来没有明显设置过,因此会出现一个通知:

注意:未定义变量:KHiiru4yzYh141GUh2xIMew in…

和将导致null(同样是因为从未设置该变量)。

要了解PHP如何读取字符串,请参阅这个解释页。

现在回答你的问题,为什么其他$不被解释为变量。这与PHP变量不以数字开头的事实有关。所以PHP知道$2永远不能是一个变量。

PHP中有效的变量名如下:

[a-zA-Z_'x7f-'xff][a-zA-Z0-9_'x7f-'xff]*

在PHP中有一种方法可以让变量以数字开头:${'2a'} = 'foo';

所以你有四个选择来修复你的代码:

使用单引号

'INSERT INTO su_auth ( 
     AuthAlias, AuthUsername, AuthPass, AuthSessionID, AuthIP, AuthUserAgent
 ) VALUES ( 
     ''Me'',
     ''Myself'',                                  
     ''$2a$08$KHiiru4yzYh141GUh2xIMew//bCc7rxMuY1rtDApwA66/czIiurLi'', 
     NULL, NULL, NULL
 )'

连接

"INSERT INTO su_auth ( 
     AuthAlias, AuthUsername, AuthPass, AuthSessionID, AuthIP, AuthUserAgent
 ) VALUES ( 
     'Me',
     'Myself',                                  
     '". '$2a$08$KHiiru4yzYh141GUh2xIMew//bCc7rxMuY1rtDApwA66/czIiurLi' . "', 
     NULL, NULL, NULL
 )"

sprintf

echo sprintf("INSERT INTO su_auth (AuthAlias, AuthUsername, AuthPass, AuthSessionID, AuthIP, AuthUserAgent) VALUES ('Me', 'Myself', '%s', null, null, null)", '$2a$08$KHiiru4yzYh141GUh2xIMew//bCc7rxMuY1rtDApwA66/czIiurLi');

为什么在查询中直接使用你的数据?使用带绑定参数的预处理语句

$stmt = $connection->prepare('INSERT INTO su_auth (AuthAlias, AuthUsername, AuthPass, AuthSessionID, AuthIP, AuthUserAgent) VALUES (:AuthAlias, :AuthUsername, :AuthPass, :AuthSessionID, :AuthIP, :AuthUserAgent)');
$stmt->execute([
    'AuthAlias'     => 'Me',
    'AuthUsername'  => 'Myself',
    'AuthPass'      => '$2a$08$KHiiru4yzYh141GUh2xIMew//bCc7rxMuY1rtDApwA66/czIiurLi',
    'AuthSessionID' => null,
    'AuthIP'        => null,
    'AuthUserAgent' => null,
]);