您現(xiàn)在的位置是:教育
代碼安全之參數(shù)安全過(guò)濾
2018-09-12 09:38教育
簡(jiǎn)介所有對(duì)Web應(yīng)用的攻擊都要傳入有害的參數(shù),因此代碼安全的基礎(chǔ)就是對(duì)傳入的參數(shù)進(jìn)行有效的過(guò)濾,比如像SQL注入漏洞,只要過(guò)濾到單引號(hào),就能防御住大部分的string類(lèi)型的SQL注入,只要過(guò)濾掉尖括號(hào)和單雙引號(hào)也能過(guò)濾掉不少XSS漏洞,這種簡(jiǎn)單的過(guò)濾跟完全不過(guò)...
所有對(duì)Web應(yīng)用的攻擊都要傳入有害的參數(shù),因此代碼安全的基礎(chǔ)就是對(duì)傳入的參數(shù)進(jìn)行有效的過(guò)濾,比如像SQL注入漏洞,只要過(guò)濾到單引號(hào),就能防御住大部分的string類(lèi)型的SQL注入,只要過(guò)濾掉尖括號(hào)和單雙引號(hào)也能過(guò)濾掉不少XSS漏洞,這種簡(jiǎn)單的過(guò)濾跟完全不過(guò)濾帶來(lái)的效果是天壤之別,我們做的就是要細(xì)化這些過(guò)濾規(guī)則,通過(guò)橫向擴(kuò)展防御策略來(lái)攔截更多的攻擊,不少第三方提供了這樣的過(guò)濾函數(shù)和類(lèi),我們可以直接引用,另外PHP自身提供了不少過(guò)濾的函數(shù),好好使用這些內(nèi)置的函數(shù)也能達(dá)到非常好的效果。
一、第三方過(guò)濾函數(shù)與類(lèi)
在一些中小型的Web應(yīng)用程序中,由于大多數(shù)開(kāi)發(fā)者是不怎么懂安全的,所以都會(huì)選擇一些第三方的過(guò)濾函數(shù)或者類(lèi),直接拿過(guò)去套著用,并不知道效果到底怎么樣。在PHP安全過(guò)濾的類(lèi)里面,比較出名的有出自80sec團(tuán)隊(duì)給出的一個(gè)SQL注入過(guò)濾的類(lèi),在國(guó)內(nèi)大大小小的程序像discuz、dedecms、phpmywind等都使用過(guò)。
目前大多數(shù)應(yīng)用都有一個(gè)參數(shù)過(guò)濾的統(tǒng)一入口,類(lèi)似于dedecms的代碼,如下所示:
foreach(Array('_GET','_POST','_COOKIE')as $_request)
{
foreach($$_request as $_k => $_v)
{
if($_k == 'nvarname')${$_k} = $_v;
else ${$_k} = _RunMagicQuotes($_v);
}
}
跟進(jìn)_RunMagicQuotes()函數(shù)之后的代碼如下:
function _RunMagicQuotes(&$svar)
{
if(!get_magic_quotes_gpc())
{
if(is_array($svar))
{
foreach($svar as $_k => $_v)$svar[$_k] = _RunMagicQuotes($_v);
}
else
{
if(strlen($svar)>0&& preg_match('#^(cfg_|GLOBALS|_GET|_POST|_COOKIE)#',$svar))
{
exit('Request var not allow!');
}
$svar = addslashes($svar);
}
}
return $svar;
}
而這里僅僅是使用addslashes()函數(shù)過(guò)濾,確實(shí)能防御住一部分漏洞,但是對(duì)特定的場(chǎng)景和漏洞就不那么好使了。所以除了總?cè)肟,在具體的功能點(diǎn)也需要進(jìn)行一些過(guò)濾。
(一)discuz SQL安全過(guò)濾類(lèi)分析
discuz全稱(chēng)Crossday Discuz!Board,是一套開(kāi)源通用的社區(qū)論壇軟件系統(tǒng),使用PHP+MySQL開(kāi)發(fā),由于用戶(hù)量巨大,discuz一直是眾多安全愛(ài)好者重點(diǎn)研究的對(duì)象,所以也被公布過(guò)不少的安全漏洞。經(jīng)過(guò)數(shù)年的沉淀,如今的discuz主程序在代碼安全方面已經(jīng)做得比較成熟。
discuz在專(zhuān)門(mén)有一個(gè)SQL注入過(guò)濾類(lèi)來(lái)過(guò)濾SQL注入請(qǐng)求,不過(guò)也出現(xiàn)了多次繞過(guò)的情況,下面我們來(lái)分析它的這個(gè)SQL注入過(guò)濾的類(lèi)。
首先我們先看到discuz的配置文件/config/config_global.php中的“CONFIG SECURITY”部分內(nèi)容,如下:
// ------------------------- CONFIG SECURITY -------------------------- //
$_config['security']['authkey'] = '3ca530i1uCe7lRke';
$_config['security']['urlxssdefend'] = 1;
$_config['security']['attackevasive'] = '0';
$_config['security']['querysafe']['status'] = 1;
//是否開(kāi)啟SQL注入防御//
以下是過(guò)濾規(guī)則
$_config['security']['querysafe']['dfunction']['0'] = 'load_file';
$_config['security']['querysafe']['dfunction']['1'] = 'hex';
$_config['security']['querysafe']['dfunction']['2'] = 'substring';
$_config['security']['querysafe']['dfunction']['3'] = 'if';
$_config['security']['querysafe']['dfunction']['4'] = 'ord';
$_config['security']['querysafe']['dfunction']['5'] = 'char';
$_config['security']['querysafe']['daction']['0'] = '@';
$_config['security']['querysafe']['daction']['1'] = 'intooutfile';
$_config['security']['querysafe']['daction']['2'] = 'intodumpfile';
$_config['security']['querysafe']['daction']['3'] = 'unionselect';
$_config['security']['querysafe']['daction']['4'] = '(select';
$_config['security']['querysafe']['daction']['5'] = 'unionall';
$_config['security']['querysafe']['daction']['6'] = 'uniondistinct';
$_config['security']['querysafe']['dnote']['0'] = '/*';
$_config['security']['querysafe']['dnote']['1'] = '*/';
$_config['security']['querysafe']['dnote']['2'] = '#';
$_config['security']['querysafe']['dnote']['3'] = '--';
$_config['security']['querysafe']['dnote']['4'] = '"';
$_config['security']['querysafe']['dlikehex'] = 1;
$_config['security']['querysafe']['afullnote'] = '0';
我們可以看到discuz配置文件中可以設(shè)置是否開(kāi)啟SQL注入防御,這個(gè)選項(xiàng)默認(rèn)開(kāi)啟,一般不會(huì)有管理員去關(guān)閉,再往下的內(nèi)容:
$_config['security']['querysafe']['daction']
以及
$_config['security']['querysafe']['dnote']
都是SQL注入過(guò)濾類(lèi)的過(guò)濾規(guī)則,規(guī)則里包含了常見(jiàn)的注入關(guān)鍵字。
Discuz執(zhí)行SQL語(yǔ)句之前會(huì)調(diào)用\source\class\discuz\discuz_database.php文件discuz_database_safecheck類(lèi)下面的checkquery($sql)函數(shù)進(jìn)行過(guò)濾,我們來(lái)跟進(jìn)這個(gè)函數(shù)看看,代碼如下:
public static function checkquery($sql)
{
if(self::$config === null)
{
self::$config = getglobal('config/security/querysafe');
}
if(self::$config['status'])
{
$check = 1;
$cmd = strtoupper(substr(trim($sql),,3));
if(isset(self::$checkcmd[$cmd]))
{
$check = self::_do_query_safe($sql);
}
elseif(substr($cmd,,2)=== '/*')
{
$check = -1;
}
if($check < 1)
{
throw new DbException('It is not safe to do this query',,$sql);
}
}
return true;
}
從代碼中可以看到,程序首先加載配置文件中的config/security/querysafe,根據(jù)$config['status']判斷SQL注入防御是否開(kāi)啟,再到$check=self::_do_query_safe($sql);可以看到該函數(shù)又調(diào)用了同類(lèi)下的_do_query_safe()函數(shù)對(duì)SQL語(yǔ)句進(jìn)行過(guò)濾,我們繼續(xù)跟進(jìn)_do_query_safe()函數(shù),代碼如下:
private static function _do_query_safe($sql)
{
$sql = str_replace(array('\\\\','\\\'','\\"','\'\''),'',$sql);
$mark = $clean = '';
if(strpos($sql,'/')=== false && strpos($sql,'#')=== false && strpos($sql,'-- ')=== false && strpos($sql,'@')=== false && strpos($sql,'`')=== false)
{
$clean = preg_replace("/'(.+?)'/s",'',$sql);
}
else
{
$len = strlen($sql);
$mark = $clean = '';
for($i = 0;$i < $len;$i++)
{
$str = $sql[$i];
switch($str)
{
case '`':if(!$mark)
{
$mark = '`';
$clean .= $str;
}
elseif($mark == '`')
{
$mark = '';
}
break;
case '\'':
if(!$mark)
{
$mark = '\'';
$clean .= $str;
}
elseif($mark == '\'')
{
$mark = '';
}
break;
case '/':
if(empty($mark)&& $sql[$i + 1] == '*')
{
$mark = '/*';
$clean .= $mark;
$i++;
}
elseif($mark == '/*' && $sql[$i - 1] == '*')
{
$mark = '';
$clean .= '*';
}
break;
case '#':
if(empty($mark))
{
$mark = $str;
$clean .= $str;
}
break;
case "\n":
if($mark == '#' || $mark == '--')
{
$mark = '';
}
break;
case '-':
if(empty($mark)&& substr($sql,$i,3)== '-- ')
{
$mark = '-- ';
$clean .= $mark;
}
break;
default:
break;
}
$clean .= $mark?'':$str;
}
}
if(strpos($clean,'@')!== false)
{
return '-3';
}
$clean = preg_replace("/[^a-z0-9_\-\(\)#\*\/\"]+/is","",strtolower($clean));
if(self::$config['afullnote'])
{
$clean = str_replace('/**/','',$clean);
}
if(is_array(self::$config['dfunction']))
{
foreach(self::$config['dfunction'] as $fun)
{
if(strpos($clean,$fun . '(')!== false)
return '-1';
}
}
if(is_array(self::$config['daction']))
{
foreach(self::$config['daction'] as $action)
{
if(strpos($clean,$action)!== false)
return '-3';
}
}
if(self::$config['dlikehex'] && strpos($clean,'like0x'))
{
return '-2';
}
if(is_array(self::$config['dnote']))
{
foreach(self::$config['dnote'] as $note)
{
if(strpos($clean,$note)!== false)
return '-4';
}
}
return 1;
}
從如上代碼我們可以看到,該函數(shù)首先使用:
$sql = str_replace(array('\\\\','\\\'','\\"','\'\''),'',$sql);
將SQL語(yǔ)句中的\\、\'、\"以及''替換為空,緊接著是一個(gè)if else判斷邏輯來(lái)選擇過(guò)濾的方式:
if(strpos($sql,'/')=== false && strpos($sql,'#')=== false && strpos($sql,'-- ')=== false && strpos($sql,'@')=== false && strpos($sql,'`')=== false)
{
$clean = preg_replace("/'(.+?)'/s",'',$sql);
}
else
{
這段代碼表示當(dāng)SQL語(yǔ)句里存在'/'、#'、'--'、'@'、'`'這些字符時(shí),則直接調(diào)用preg_replace()函數(shù)將單引號(hào)(')中間的內(nèi)容替換為空,這里之前存在一個(gè)繞過(guò),只要把SQL注入的語(yǔ)句放到單引號(hào)中間,則會(huì)被替換為空,進(jìn)行下面再判斷的時(shí)候已經(jīng)檢測(cè)不到SQL注入的關(guān)鍵字,導(dǎo)致繞過(guò)的出現(xiàn),在MySQL中使用@`'`代表null,SQL語(yǔ)句可以正常執(zhí)行。
else條件中是對(duì)整段SQL語(yǔ)句進(jìn)行逐個(gè)字符進(jìn)行判斷,比如:
case '/':
if(empty($mark)&& $sql[$i + 1] == '*')
{
$mark = '/*';
$clean .= $mark;
$i++;
}
elseif($mark == '/*' && $sql[$i - 1] == '*')
{
$mark = '';
$clean .= '*';
}
break;
這段代碼的邏輯是,當(dāng)檢查到SQL語(yǔ)句中存在斜杠(/)時(shí),則去判斷下一個(gè)字符是不是星號(hào)(*),如果是星號(hào)(*)就把這兩個(gè)字符拼接起來(lái),即/*,然后繼續(xù)判斷下一個(gè)字符是不是星號(hào)(*),如果是星號(hào)則再繼續(xù)拼接起來(lái),得到/**,最后在如下代碼中判斷是否存在原來(lái)攔截規(guī)則里面定義的字符,如果存在則攔截SQL語(yǔ)句執(zhí)行:
if(is_array(self::$config['dnote']))
{
foreach(self::$config['dnote'] as $note)
{
if(strpos($clean,$note)!== false)
return '-4';
}
}
國(guó)內(nèi)知名的多款cms應(yīng)用如dedecms等,都有使用類(lèi)似這個(gè)過(guò)濾類(lèi),另外由于應(yīng)用的基礎(chǔ)架構(gòu)不一樣,這個(gè)過(guò)濾類(lèi)應(yīng)用起來(lái)的實(shí)際效果也各不太一樣,discuz目前做得相對(duì)較好。
(二)discuz XSS標(biāo)簽過(guò)濾函數(shù)分析
目前大多數(shù)XSS過(guò)濾都是基于黑名單的形式,編程語(yǔ)言和編碼結(jié)合起來(lái)千變?nèi)f化,基于黑名單的過(guò)濾總給人不靠譜的感覺(jué),事實(shí)確實(shí)是這樣,目前好像還沒(méi)有看到基于黑名單過(guò)濾的規(guī)則一直沒(méi)有被繞過(guò),其實(shí)在XSS的防御上,只要過(guò)濾掉尖括號(hào)以及單、雙引號(hào)就能干掉絕大部分的payload。下面我們來(lái)看看discuz的HTML標(biāo)簽過(guò)濾代碼,如下所示:
function checkhtml($html)
{
if(!checkperm('allowhtml'))
{
preg_match_all("/\<([^\<]+)\>/is",$html,$ms);
$searchs[] = '<';
$replaces[] = '<;';
$searchs[] = '>';
$replaces[] = '>;';
if($ms[1])
{
$allowtags = 'img|a|font|div|table|tbody|caption|tr|td|th|br|p|b|strong|i|u|em|span|ol|ul|li|blockquote|object|param';
$ms[1] = array_unique($ms[1]);
foreach($ms[1] as $value)
{
$searchs[] = "<;".$value.">;";
$value = str_replace('&','_uch_tmp_str_',$value);
$value = dhtmlspecialchars($value);
$value = str_replace('_uch_tmp_str_','&',$value);
$value = str_replace(array('\\','/*'),array('.','/.'),$value);
$skipkeys = array('onabort','onactivate','onafterprint','onafterupdate','onbeforeactivate','onbeforecopy','onbeforecut','onbeforedeactivate','onbeforeeditfocus','onbeforepaste','onbeforeprint','onbeforeunload','onbeforeupdate','onblur','onbounce','oncellchange','onchange','onclick','oncontextmenu','oncontrolselect','oncopy','oncut','ondataavailable','ondatasetchanged','ondatasetcomplete','ondblclick','ondeactivate','ondrag','ondragend','ondragenter','ondragleave','ondragover','ondragstart','ondrop','onerror','onerrorupdate','onfilterchange','onfinish','onfocus','onfocusin','onfocusout','onhelp','onkeydown','onkeypress','onkeyup','onlayoutcomplete','onload','onlosecapture','onmousedown','onmouseenter','onmouseleave','onmousemove','onmouseout','onmouseover','onmouseup','onmousewheel','onmove','onmoveend','onmovestart','onpaste','onpropertychange','onreadystatechange','onreset','onresize','onresizeend','onresizestart','onrowenter','onrowexit','onrowsdelete','onrowsinserted','onscroll','onselect','onselectionchange','onselectstart','onstart','onstop','onsubmit','onunload','javascript','script','eval','behaviour','expression','style','class');
$skipstr = implode('|',$skipkeys);
$value = preg_replace(array("/($skipstr)/i"),'.',$value);
if(!preg_match("/^[\/|\s]?($allowtags)(\s+|$)/is",$value))
{
$value = '';
}
$replaces[] = empty($value)?'':"<".str_replace('";','"',$value).">";
}
}
$html = str_replace($searchs,$replaces,$html);
}
return $html;
}
從代碼中可以看到,這里首先定義了一條正則取出來(lái)尖括號(hào)中間的內(nèi)容:
preg_match_all("/\<([^\<]+)\>/is",$html,$ms);
然后在if($ms[1])這個(gè)if條件里對(duì)這些標(biāo)簽中的關(guān)鍵字進(jìn)行篩選,$skipkeys變量定義了很多on事件的敏感字符,如下代碼中可以看到,最后拼接正則將這些字符串替換掉:
$skipstr = implode('|',$skipkeys);
value = preg_replace(array("/($skipstr)/i"),'.',$value);
二、內(nèi)置過(guò)濾函數(shù)
PHP本身內(nèi)置了很多參數(shù)過(guò)濾的函數(shù),以方便開(kāi)發(fā)者簡(jiǎn)單有效且統(tǒng)一地進(jìn)行安全防護(hù),而這些函數(shù)可以分為多種類(lèi)型,如SQL注入過(guò)濾函數(shù)、XSS過(guò)濾函數(shù)、命令執(zhí)行過(guò)濾函數(shù)、代碼執(zhí)行過(guò)濾函數(shù),等等,下面我們來(lái)看看這些函數(shù)的用法。
1、SQL注入過(guò)濾函數(shù)
SQL注入過(guò)濾函數(shù)有addslashes()、mysql_real_escape_string()以及mysql_escape_string(),它們的作用都是給字符串添加反斜杠(\)來(lái)轉(zhuǎn)義掉單引號(hào)(')、雙引號(hào)(")、反斜線(\)以及空字符NULL。addslashes()和mysql_escape_string()函數(shù)都是直接在敏感字符串前加反斜杠,這里可能會(huì)存在繞過(guò)寬字節(jié)注入繞過(guò)的問(wèn)題,而mysql_real_escape_string()函數(shù)會(huì)考慮當(dāng)前連接數(shù)據(jù)庫(kù)的字符集編碼,安全性更好,推薦使用。
2、XSS過(guò)濾函數(shù)
XSS過(guò)濾函數(shù)有htmlspecialchars()和strip_tags(),這兩個(gè)函數(shù)的功能大不一樣,htmlspecialchars()函數(shù)的作用是將字符串中的特殊字符轉(zhuǎn)換成HTML實(shí)體編碼,如&轉(zhuǎn)換成&;,"轉(zhuǎn)換成";,'轉(zhuǎn)換成';,<轉(zhuǎn)換成<;,>轉(zhuǎn)換成>;這個(gè)函數(shù)簡(jiǎn)單粗暴但是卻非常有效果,已經(jīng)能干掉大多數(shù)的XSS攻擊。
而strip_tags()函數(shù)則是用來(lái)去掉HTML及PHP標(biāo)記,比如給這個(gè)函數(shù)傳入“<h1>xxxxx</h1>”,經(jīng)過(guò)它處理后返回的字符串為xxxxx。
3、命令執(zhí)行過(guò)濾函數(shù)
通常我們進(jìn)行系統(tǒng)命令注入的時(shí)候會(huì)使用到||以及&等字符,PHP為了防止系統(tǒng)命令注入的漏洞,提供了escapeshellcmd()和escapeshellarg()兩個(gè)函數(shù)對(duì)參數(shù)進(jìn)行過(guò)濾,escapeshellcmd()函數(shù)過(guò)濾的字符為'&'、';'、'`'、'|'、'*'、'?'、'~'、'<'、'>'、'^'、'('、')'、'['、']'、'{'、'}'、'$'、'\'、'\x0A'、'\xFF'、’%’以及單雙引號(hào),Windows下過(guò)濾方式則是在這些字符前面加了一個(gè)^符號(hào),而在Linux下則是在這些字符前面加了反斜杠(\)。escapeshellarg()函數(shù)過(guò)濾方式比較簡(jiǎn)單,給所有參數(shù)加上一對(duì)雙引號(hào),強(qiáng)制為字符串。
Tags:代碼,安全,參數(shù),過(guò)濾,所有,Web,用的,攻擊,都要,傳入
相關(guān)文章
- 代表建議降低高考外語(yǔ)分值,帶不來(lái)農(nóng)村娃需要的公平
- 高三女生誓師大會(huì)精彩發(fā)言,卻因表情被網(wǎng)暴,父親回應(yīng)
- 學(xué)校勸退初三“差生”,成績(jī)差就沒(méi)有上學(xué)權(quán)利
- 9點(diǎn)沒(méi)寫(xiě)完的作業(yè)就不寫(xiě)了,作業(yè)熔斷引爭(zhēng)議
- 中小學(xué)或?qū)⑷∠n后延時(shí)服務(wù),費(fèi)用一并退還
- 官方寒假?lài)?yán)查住家教師,校外培訓(xùn)再遭滅頂之災(zāi),家長(zhǎng)反
- 強(qiáng)制學(xué)生買(mǎi)平板違規(guī)收費(fèi)2600萬(wàn),學(xué)校怎么老犯同樣的錯(cuò)
- 父母一旦開(kāi)始“內(nèi)耗”,比沒(méi)錢(qián)和哭窮更可怕,連累孩子
- 一場(chǎng)疫情后醒悟:一個(gè)天性涼薄的小孩,父母付出得越多
- 因不會(huì)拼音被嫌棄?學(xué)生回家大哭:老師不歡迎我讓我轉(zhuǎn)
隨機(jī)圖文
記憶實(shí)例 記憶實(shí)例 | 利用數(shù)字編碼法快速記憶《愛(ài)蓮說(shuō)
水陸草木之花,可愛(ài)者甚蕃。晉陶淵明獨(dú)愛(ài)菊。自李唐來(lái),世人甚愛(ài)牡丹。予獨(dú)愛(ài)蓮之出淤泥而不染,濯清漣而不...男子開(kāi)著豪車(chē),與女大學(xué)生一周約會(huì)13次,室友:這是我
在我們的生活中,其實(shí)有無(wú)數(shù)的拜金女,大部分人都會(huì)覺(jué)得他們的行為并不是很光彩,而且沒(méi)有道德底線,當(dāng)然這...孩子有嫌棄父母的跡象,家長(zhǎng)就要引起重視,不然會(huì)養(yǎng)出
身為人父母最希望的就是自己家的孩子能夠尊重自己,孝敬自己,在老了之后對(duì)自己也是十分敬重的,但實(shí)際上孩...“新型補(bǔ)課”卷土而來(lái),取代傳統(tǒng)補(bǔ)課班,家長(zhǎng)表示:內(nèi)
作為家長(zhǎng)就沒(méi)有不希望自己家的孩子好好學(xué)習(xí)的,因?yàn)橹挥羞@樣才能夠以后重復(fù)重復(fù),而且對(duì)自己的生活也是有所...
點(diǎn)擊排行

- 男子開(kāi)著豪車(chē),與女大學(xué)生一周約會(huì)13次,室友:這是我
- 孩子有嫌棄父母的跡象,家長(zhǎng)就要引起重視,不然會(huì)養(yǎng)出
- “新型補(bǔ)課”卷土而來(lái),取代傳統(tǒng)補(bǔ)課班,家長(zhǎng)表示:內(nèi)
- 教育做不到的,就交給閱讀!
- 邁過(guò)高考這道坎,從此之后成為男子漢,網(wǎng)友:百善孝為
- 大學(xué)當(dāng)班委是浪費(fèi)時(shí)間?過(guò)來(lái)人以實(shí)際經(jīng)歷告訴你,這些
- 虛榮!45歲女老師“炫耀”家長(zhǎng)送禮:系閨蜜送花,學(xué)校
- 放手讓孩子做幾件事,雖然看似無(wú)用,孩子童年最大的幸
猜你喜歡
- 代表建議降低高考外語(yǔ)分值,帶不來(lái)農(nóng)村娃需要的公平
- 高三女生誓師大會(huì)精彩發(fā)言,卻因表情被網(wǎng)暴,父親回應(yīng)
- 學(xué)校勸退初三“差生”,成績(jī)差就沒(méi)有上學(xué)權(quán)利
- 9點(diǎn)沒(méi)寫(xiě)完的作業(yè)就不寫(xiě)了,作業(yè)熔斷引爭(zhēng)議
- 中小學(xué)或?qū)⑷∠n后延時(shí)服務(wù),費(fèi)用一并退還
- 官方寒假?lài)?yán)查住家教師,校外培訓(xùn)再遭滅頂之災(zāi),家長(zhǎng)反
- 強(qiáng)制學(xué)生買(mǎi)平板違規(guī)收費(fèi)2600萬(wàn),學(xué)校怎么老犯同樣的錯(cuò)
- 父母一旦開(kāi)始“內(nèi)耗”,比沒(méi)錢(qián)和哭窮更可怕,連累孩子
- 一場(chǎng)疫情后醒悟:一個(gè)天性涼薄的小孩,父母付出得越多
- 因不會(huì)拼音被嫌棄?學(xué)生回家大哭:老師不歡迎我讓我轉(zhuǎn)