iT邦幫忙

1

XSS 的放入val()的轉換

  • 分享至 

  • xImage

目前正在做預防XSS攻擊
想請問,
1.如果轉換過的資料使用append()或html()放入都可以正常顯示,但是如果使用val()插入,就還是未經html轉譯過的內容,想請問這要怎麼解決呢?(input的val:A "quote" is 123)
2.一般是上傳時就先轉譯後存到資料庫嗎?
3.小弟有查到htmlspecialchars()和htmlentities()都可以,大家比較推薦個呢?
煩請各路高手幫小弟解答 謝謝

<?php
$test = 'A "quote" is 123';
$test = htmlentities($test);
echo $test;
?>
<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <title>title</title>
</head>

<body>
  <main>
    <div id='test' contenteditable="true" class="box"></div>
    <input type="text" id='inp'>
  </main>
  <script src='js/jquery.js'></script>
  <script>
    let test = "<?php echo $test ?>";
    $('#inp').val(test);
    $('#test').append(test)
    $('#test').html(test)
  </script>
</body>

</html>
我是會先在前端擋一次,並提醒使用者
後端再做第二次確認,直接處理掉,再存入資料庫~
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

2

一般來說,這並沒有絕對性。
大多數都會用 addslashes 來對字串加入拖位符處理。然後用 stripslashes 來還原。

雖然你用的 htmlspecialchars 也是可以,它會將一些定義符做html碼處理。
也是可以達到處理被注入的問題。

但就我個人而言。html盡量還是用在需要html顯示的地方就好。
正常來說,如果今天我很確定的,我是要存html碼且要做內容字元顯示的話。
我會用 htmlentities 來處理。

但一般防注入的字串值或是非html顯示用的。
我還是我用 addslashes 來處理。借此區分儲存值的特性為何。

但 addslashes 只是一層的防護。它只是防注入的其中一環。
不要認為這樣子就夠了。

看更多先前的回應...收起先前的回應...
豬豬人 iT邦新手 4 級 ‧ 2020-12-24 13:54:05 檢舉

感謝星大,也就是說如果我今天的值有可能出現在input 的val()裡面,就應該用addslashes 來作處理並儲存,

豬豬人 iT邦新手 4 級 ‧ 2020-12-24 14:04:09 檢舉

如果今天有一筆資料有可能出現在input的value內,也可能出現在html內,那應該如何處理呢? (畢竟addslashes 沒有過濾掉< >)

基本上有這樣的情況,就該打了。

理論上html的內容,不可能可以出現在input上。只會出現在textarea上。
如果說只是單純的div在input上。那就是規劃上的問題。
設計上一定不能用input單一html元件來做儲存。
因為這叫自找麻煩的事。

但,如真有這樣的情況。那就只能理所當然的用。 htmlspecialchars
且用 htmlspecialchars 本身也不會違背我剛說的字串特性。
因為你確定這個字串是html用。

豬豬人 iT邦新手 4 級 ‧ 2020-12-24 15:58:48 檢舉

抱歉,頭腦有點打結,如果讓使用者可以輸入地址,讓其他使用者可以看到,並且自身也可以修改地址,就有可能出現在input 或 html
頭腦打結了...

淺水員 iT邦大師 6 級 ‧ 2020-12-24 16:02:23 檢舉

豬豬人

如果今天有一筆資料有可能出現在input的value內,也可能出現在html內

請問:假如資料內有 html 標籤,那麼要讓那個標籤有作用還是直接拿掉那個標籤?

假設資料原始內容是 abc<span style="color:red">def</span>
那麼希望輸出是「忽略顏色設定」還是「def會變成紅色」?

淺水員 iT邦大師 6 級 ‧ 2020-12-24 16:13:08 檢舉

如果只是輸入地址,然後顯示地址,也就是說不允許 html tag 作用的話。
jQuery 可以用 .text(...) 而不是用 .html(...) 插入資料。
原生 js 可以用 textContent 而不是 innerHTML

豬豬人 iT邦新手 4 級 ‧ 2020-12-24 16:48:50 檢舉

整理一下問題,描述得不好,抱歉
如果今天使用者輸入A "quote" is < 123 然後經過 htmlspecialchars($test)之後存入資料庫 如下
$test = 'A "quote" is < 123'; $test = htmlspecialchars($test);
現在要取用資料庫資料,取出來的資料是已經經過編碼的如下:
A "quote" is < 123
然後使用append html 顯示為 A "quote" is < 123

$('#test').append(test)
$('#test').html(test)

使用val 顯示為 A "quote" is < 123

$('#inp').val(test)

想請問val 內的編碼問題要如何解決
謝謝

淺水員 iT邦大師 6 級 ‧ 2020-12-24 17:03:48 檢舉
$('#inp').val($('<div></div>').html(test).text());
0
淺水員
iT邦大師 6 級 ‧ 2020-12-24 16:46:16

大多數狀況下,把使用者輸入的資料顯示在網頁時,我會優先採用 Node.textContent 的方式
jQuery 是 .text()
這樣即使使用者輸入 html tag ,也只會當純文字忠實的呈現在網頁上

範例

<?php
$testStr='A "quote" <a href=\'c:\\windows\\\'>is 123</a>';
?><!DOCTYPE html>
<html lang="Zh-Hant">
<head>
    <meta charset="utf-8">
    <title></title>
    <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
</head>
<body>
    <div id='ex1'></div>
    <div id='ex2'></div>
    <script>
        let testStr=<?php echo json_encode($testStr);?>;
        //純 javascript
        document.querySelector('#ex1').textContent=testStr;
        //jQuery
        $('#ex2').text(testStr);
    </script>
</body>
</html>

純文字資料這樣已經很夠用了
如果是允許使用者添加效果,改變字型、插入超連結那種要做編輯器的再另外說吧

froce iT邦大師 1 級 ‧ 2020-12-29 08:31:09 檢舉

編輯器的話我會推薦使用像 jsxss的lib。
https://jsxss.com/zh/index.html

我要發表回答

立即登入回答