2

我对正确验证我的 URL 感到非常困惑。我已经尝试了几个选项,但我无法做到正确。有人可以查看我的代码并告诉我我做错了什么吗?

$url=filter_input(INPUT_GET, 'url', FILTER_VALIDATE_URL); 
if (!$url) {
    echo The url address is not valid
}

if(strpos($url,'http://')===false)
    $url='http://'.$url;
$query="INSERT INTO `aa_aa`.`article` VALUES ('', '".$url."', '".$_POST['description']."', '".$_POST['type']."',NOW());";
$result=mysql_query($query);
if(!$result)
    // echo 'Error While Inserting Article!';
    echo $query;
else
    header('Location: http://aa.aa');

编辑 对不起埃里克在这里。@Brad 我的朋友帮助我编写了所有脚本,所以我不太了解我使用它的风险。

 SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
 SET time_zone = "+00:00";


 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
 /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
 /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
 /*!40101 SET NAMES utf8 */;

 --
 -- Database: 
 --

 -- --------------------------------------------------------


 -- Table structure for table `article`
 --

 CREATE TABLE IF NOT EXISTS `article` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `url` varchar(100) NOT NULL,
   `description` text NOT NULL,
   `type` varchar(40) NOT NULL,
   `title` varchar(80) NOT NULL,
   `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   PRIMARY KEY (`id`),
   UNIQUE KEY `id` (`id`)
 ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=137 ;

 /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
 /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
 /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
4

2 回答 2

1

几件事:

$url=filter_input(INPUT_GET, 'url', FILTER_VALIDATE_URL); 

这是极好的。使用filter_input()是最佳实践。

if (!$url) {
    echo The url address is not valid
}

这个位有几个问题:

  1. 养成使用$foo === FALSE而不是!$foo专门检查 value的习惯FALSE,除非要检查的值保证是布尔值。在这种特殊情况下,我不相信有任何有效的 URL 可以被强制转换为 boolean FALSE,所以你可能是安全的,但养成这个习惯仍然是件好事。
  2. 您要回显的字符串缺少引号和终止分号,因此这些会产生语法错误。
  3. 没有什么能阻止脚本继续。这意味着无效的 URL 仍在进入您的数据库。您应该在exit;之后使用echo,或者重组您的逻辑,以便您的错误条件实际上可以防止添加无效 URL 并继续执行脚本。

    if(strpos($url,'http://')===false) $url='http://'.$url;

这里还有几件事:

  1. {}始终在代码块周围使用花括号。
  2. FILTER_VALIDATE_URL不会验证没有方案的 URL。这意味着这段代码是多余的,应该被删除,因为任何通过filter_input()调用的 URL 都保证有一个方案(例如http://)。
  3. 通过仅检查http://,您没有考虑使用其他方案的 URL,例如https://. 不过,这没什么大不了的,因为正如我在上面指出的那样,无论如何都应该删除这个代码块,这要感谢FILTER_VALIDATE_URL您为您处理这一切。

    $query="INSERT INTO aa_aa. articleVALUES ('', '".$url."', '".$_POST['description']."', '".$_POST['type']."',NOW ());";

这对 SQL 注入很开放。永远不要将用户输入直接嵌入到您的查询字符串中。尽可能使用参数绑定和准备好的语句。由于您使用的是Mysql扩展程序,因此这是不可能的,您最好的选择是使用mysql_real_escape_string().

$result=mysql_query($query);

Mysql扩展已弃用。您应该使用PDOorMysqli代替。

if(!$result)
    // echo 'Error While Inserting Article!';
    echo $query;
else
    header('Location: http://aa.aa');

{}同样,始终在代码块周围使用花括号。

于 2012-09-25T03:18:17.607 回答
0

我不知道这是否完全是您的错误,但根据您的表格布局,您需要更改 sql 查询

"INSERT INTO `aa_aa`.`article` VALUES ('', '".$url."', '".$_POST['description']."', '".$_POST['type']."',NOW());"

"INSERT INTO aa_aa.article 
  (url,description,type,title,time) 
VALUES 
  ('". mysql_real_escape_string($url). "', 
   '". mysql_real_escape_string($_POST['description']). "', 
   '". mysql_real_escape_string($_POST['type']). "', 
   '". mysql_real_escape_string($_POST['title']). "',
   NOW())"

请注意,我弥补了它,$_POST['title']因为它在原始查询中丢失但出现在表创建脚本中。此外,您确实必须使用mysql_real_escape_string才能获得一定程度的安全性。理想情况下,您会想要使用 PDO。

于 2012-09-25T00:32:04.223 回答