使用Google网站管理员工具检查我的网站我发现了一件奇怪的事情:
有人尝试使用此链接到我的网站(出于明显的安全原因,我更改了我网站的真实姓名):
....://mysite.com/tarifs.php?annee=aaatoseihmt&mois=10&cours=1828
我尝试并理解它是一个带有结果的SQL注入:
警告:mktime()期望参数6为long,字符串为 /home/..../public_html/..../tarifs.php 在第72行
我的代码第72行是:
mktime (0, 0, 0, $mois, "01", $annee)
部分内容:
<?php
include ("include.php");
if (!$link = mysql_connect($host, $user, $pass)) {
echo "Could not connect to mysql";
exit;
}
if (!mysql_select_db($bdd, $link)) {
echo "Could not select database";
exit;
}
mysql_query("SET NAMES 'utf8'");
$annee = "";
$mois = "";
$stage = "";
if (isset($_GET['annee'])) {$annee=$_GET['annee'];}
if (isset($_GET['mois'])) {$mois=$_GET['mois'];}
if (isset($_GET['stage'])) {$stage=$_GET['stage'];}
if($annee == "")
{
$annee = date("Y");
}
if($mois == "")
{
$mois = date("m");
}
$date_du_jour = date("d")."-".date("m")."-".date("Y");
if($mois == "12")
{
$mois_precedent = "11";
$mois_suivant = "01";
$annee_mois_precedent = $annee;
$annee_mois_suivant = $annee + 1;
}
elseif($mois == "01")
{
$mois_precedent = "12";
$mois_suivant = "02";
$annee_mois_precedent = $annee - 1;
$annee_mois_suivant = $annee;
}
else
{
$mois_precedent = sprintf("%02s", $mois-1);
$mois_suivant = sprintf("%02s", $mois+1);
$annee_mois_precedent = $annee;
$annee_mois_suivant = $annee;
}
$jour_en_cours = date("d");
$mois_francais = array("Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre");
$dt_deb_genere = $annee."-".$mois."-01";
$dt_fin_genere = $annee_mois_suivant."-".$mois_suivant."-01";
$dt_date = mktime (0, 0, 0, $mois, "01", $annee);
$jour_de_la_semaine = date("w", $dt_date);
?>
我可以做些什么来保护我的网站免受此事?
我试图理解如何使用“类似问题”,但我认为我是新手到php和mysql才能理解。所以任何帮助都非常棒!
谢谢你能帮忙解决这个问题!我现在在我的网站上努力了好几个月,不想失去我的生意。
.blc。
然后!!!在Lucanos(感谢!!!!)提供的代码之后,我做了一些小改动:-):
<?php
include ("include.php");
if (!$link = mysql_connect($host, $user, $pass)) {
echo "Could not connect to mysql";
exit;
}
if (!mysql_select_db($bdd, $link)) {
echo "Could not select database";
exit;
}
mysql_query("SET NAMES 'utf8'");
$annee = '';
$mois = '';
$stage = '';
if( isset( $_GET['annee'] ) )
{
$annee = preg_replace( '/\D/' , '' , $_GET['annee'] );
if( !$annee || !( $annee<=2015 && $annee>=2013 ) )
// Allows you to set an expected range for this value
// code here expects a number between 2013 and 2015 inclusive
$annee = '';
}
if( isset( $_GET['mois'] ) )
{
$mois = preg_replace( '/\D/' , '' , $_GET['mois'] );
if( !$mois || !( $mois<=12 && $mois>=1 ) )
// I assume this is the Month, with a range of 1 to 12
$mois = '';
}
if (isset($_GET['stage'])) {$stage=$_GET['stage'];}
if($annee == '')
{
// Récupération de l'année en cours
$annee = date('Y');
}
if($mois == '')
{
// Récupération du mois en cours
$mois = date('m');
}
// Récupération de la date du jour
$date_du_jour = date( 'd-m-Y' );
if($mois == '12')
{
$mois_precedent = '11';
$mois_suivant = '01';
$annee_mois_precedent = $annee;
$annee_mois_suivant = $annee + 1;
}
elseif($mois == '01')
{
$mois_precedent = '12';
$mois_suivant = '02';
$annee_mois_precedent = $annee - 1;
$annee_mois_suivant = $annee;
}
else
{
$mois_precedent = sprintf('%02s', $mois-1);
$mois_suivant = sprintf('%02s', $mois+1);
$annee_mois_precedent = $annee;
$annee_mois_suivant = $annee;
}
// Récupération du jours en cours
$jour_en_cours = date('d');
$mois_francais = array(
'Janvier' , 'Février' , 'Mars' ,
'Avril' , 'Mai' , 'Juin' ,
'Juillet' , 'Août' , 'Septembre' ,
'Octobre' , 'Novembre' , 'Décembre'
);
$dt_deb_genere = "{$annee}-{$mois}-01";
$dt_fin_genere = "{$annee_mois_suivant}-{$mois_suivant}-01";
$dt_date = mktime( 0 , 0 , 0 , $mois*1 , 1 , $annee*1 );
$jour_de_la_semaine = date( 'w' , $dt_date );
?>
尝试(直到现在没有成功)添加条件测试,如果数据库中存在“stage”以避免不存在的stage = 200之类的调用,则在页面中显示空日历。但是在决赛中我错过了一些东西(我在过去的代码中没有包含它)
$sql_stage = "select * from data where type_data = 'STAGE' and ind_valide = 1 and ind_etat = 1 order by sous_titre, id_type_1, ordre";
$result_stage = mysql_query($sql_stage, $link);
$existingstage = '';
while ($row_stage = mysql_fetch_array($result_stage))
{
$existingstage = $row_stage["id_data"];
if( isset( $_GET['stage'] ) )
{
$stage = preg_replace( '/\D/' , '' , $_GET['stage'] );
if( !$stage || !( $stage= $existingstage ) )
$stage = '';
}
}
答案 0 :(得分:1)
永远不要相信用户输入
无论何时使用表单中的值或从URL中提取值,请确保在使用之前对其进行测试,清理和/或将其转义。任何地方。
因此,例如,使用您的代码,我会按如下方式对其进行编辑:
<?php
include ("include.php");
// Might be worth putting this into the "include.php" file, or a function
// to do the same thing. Especially if you connect to the DB regularly.
if (!$link = mysql_connect($host, $user, $pass)) {
echo "Could not connect to mysql";
exit;
}
// Same as above...
if (!mysql_select_db($bdd, $link)) {
echo "Could not select database";
exit;
}
// And again...
mysql_query("SET NAMES 'utf8'");
$annee = '';
$mois = '';
$stage = '';
if( isset( $_GET['annee'] ) )
{
$annee = preg_replace( '/\D/' , '' , $_GET['annee'] );
if( !$annee || !( $annee<=2020 && $annee>=1970 ) )
// Allows you to set an expected range for this value
// My code here expects a number between 1970 and 2020 inclusive
$annee = '';
}
if( isset( $_GET['mois'] ) )
{
$mois = pre_replace( '/\D/' , '' , $_GET['mois'] );
if( !$mois || !( $mois<=12 && $mois>=1 ) )
// I assume this is the Month, with a range of 1 to 12
$mois = '';
}
if( isset( $_GET['stage'] ) )
{
$stage = pre_replace( '/\D/' , '' , $_GET['stage'] );
if( !$stage || !( $stage<=100 && $stage>=0 ) )
// Again, assuming 1-100
$stage = '';
}
if( $annee=='' )
$annee = date( 'Y' );
if( $mois=='' )
$mois = date( 'n' );
$date_du_jour = date( 'd-m-Y' );
if( $mois=='12' )
{
$mois_precedent = '11';
$mois_suivant = '01';
$annee_mois_precedent = $annee;
$annee_mois_suivant = $annee + 1;
}
elseif( $mois=='01' )
{
$mois_precedent = '12';
$mois_suivant = '02';
$annee_mois_precedent = $annee - 1;
$annee_mois_suivant = $annee;
}
else
{
$mois_precedent = sprintf( '%02s' , $mois-1 );
$mois_suivant = sprintf( '%02s' , $mois+1 );
$annee_mois_precedent = $annee;
$annee_mois_suivant = $annee;
}
$jour_en_cours = date( 'd' );
$mois_francais = array(
'Janvier' , 'Février' , 'Mars' ,
'Avril' , 'Mai' , 'Juin' ,
'Juillet' , 'Août' , 'Septembre' ,
'Octobre' , 'Novembre' , 'Décembre'
);
$dt_deb_genere = "{$annee}-{$mois}-01";
$dt_fin_genere = "{$annee_mois_suivant}-{$mois_suivant}-01";
$dt_date = mktime( 0 , 0 , 0 , $mois*1 , 1 , $annee*1 );
$jour_de_la_semaine = date( 'w' , $dt_date );
?>
答案 1 :(得分:0)
将来,请使用准备好的陈述。它们允许您先发送查询,然后发送值以防止注入。我更喜欢使用PDO。
无论如何,数据库中的第一条规则:验证或清理用户输入。
如果您确定输入应该是数字,只需将其强制为数字:
$number = intval($_GET['number']);
在这种情况下,如果用户将其更改为一些文本,intval()
将返回0.
对于mysql_
函数,如果输入是字符串,请使用mysql_real_ecsape_string()
:
$string = mysql_real_eascape_string($_GET['string']);
这将逃脱所有&#34;不需要的&#34;可能影响SQL查询的字符。但是,这个功能也受到了损害。
答案 2 :(得分:0)
答案 3 :(得分:0)
必填:
可选/懒惰:
答案 4 :(得分:0)
尝试:
if($annee == "" || intval($annee) == 0 ) {
$annee = date("Y");
}