当前位置: 动力学知识库 > 问答 > 编程问答 >

php - XSS keep script tag and avoid attack - why aren't reliable

问题描述:

I have some articles around the web that talks about XSS attack prevention,but I haven't found any solution:

htmlspecialchars(mb_convert_encoding($value, "UTF-8", "UTF-8"),ENT_QUOTES,'UTF-8')

or

json_encode($value, JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS);

or simply strip_tags.
At this moment I'pm using these methos everytime I need to retrieve and display some information, execpt for the mesages, because it breaks the format


What I need to do is to prevent XSS attack from this situation:

  • I have got an upload form that if there are any error it returns the name and alert it;

    echo '<script>parent.noty({text: "File Name:'.json_encode($_FILES['filename']['name'][$i]).' Error Code:'.$_FILES['filename']['error'][$i].'",type:"error",timeout:9000});</script>';

  • User can write messages that can contain html tags, such as the script one, I need to keep it: I use ckeditor to write new messages and I when I retrieve the message I need the main format(

    ...) to remain and make the script part armless

At this moment when I return the file name I use json_encode, but I'm not sure


EDIT

From the comments I have got that there aren't many possibilities, so I would like to know why those methods aren't reliable

EDIT

This is how I retrieve the messages:

$query = "SELECT

a.enc_id,

IF(b.department_name IS NOT NULL, b.department_name,'Unknown'),

IF(c.name IS NOT NULL, c.name,IF(a.ticket_status='2','Not Assigned','Unknown'),

a.title,

CASE a.priority WHEN '0' THEN 'Low' WHEN '1' THEN 'Medium' WHEN '2' THEN 'High' WHEN '3' THEN 'Urgent' WHEN '4' THEN 'Critical' ELSE priority END,

a.created_time,

a.last_reply,

CASE a.ticket_status WHEN '0' THEN '<span class=\'label label-success\'>Closed</span>' WHEN '1' THEN '<span class=\'label label-important\'>Open</span>' WHEN '2' THEN '<span class=\'label label-warning\'>To Assign</span>' WHEN '3' THEN '<span class=\'label label-important\'>Reported</span>' ELSE 'Error' END

FROM ".$SupportTicketsTable." a

LEFT JOIN ".$SupportDepaTable." b

ON b.id=a.department_id

LEFT JOIN ".$SupportUserTable." c

ON c.id=a.operator_id

WHERE a.user_id=".$_SESSION['id']."

ORDER BY a.last_reply DESC

LIMIT 350";

$STH = $DBH->prepare($query);

$STH->execute();

$list=array('response'=>'ret','tickets'=>array('user'=>array()));

$STH->setFetchMode(PDO::FETCH_ASSOC);

$a = $STH->fetch();

if(!empty($a)){

do{

$list['tickets']['user'][]=array('id'=>$a['enc_id'],'dname'=>$a['dname'],'opname'=>$a['opname'],'title'=>htmlspecialchars(mb_convert_encoding($a['title'], "UTF-8", "UTF-8"),ENT_QUOTES,'UTF-8'),'priority'=>$a['prio'],'date'=>$a['created_time'],'reply'=>$a['last_reply'],'status'=>$a['stat']);

}while ($a = $STH->fetch());

}

...

echo json_encode($list);

网友答案:

In this particular case, the correct way to escape your content is like so:

echo '...{text: "File Name:"+'.json_encode($_FILES['filename']['name'][$i]).'+" Error code...'

The reason for this is that json_encode will take any input and make it safe to dump in a JavaScript context. A string will be surrounded by quotes and appropriately escaped to be valid. However, you must close out of existing quotes before concatenating in your value for it to work.

That said, I'm assuming that the function putting this text into your page will use something like document.createTextNode(arguments[0].text); to create a text node, NOT an HTML context.

分享给朋友:
您可能感兴趣的文章:
随机阅读: