Re: [請益] textarea中的html標籤(emoji)

看板PHP作者 (天真可愛CQD)時間9年前 (2016/07/21 11:17), 9年前編輯推噓6(608)
留言14則, 4人參與, 最新討論串2/2 (看更多)
直接寫一篇可能比較清楚 「存資料的時候應該存未處理過的原始資料,吐 html 的時候才做 escape」 原因有幾個 - 你先 escape 了以後,你就沒有原始資料,只剩下加料過的資料 - 東西不見得塞在 HTML 裡面,不同的地方要做不同的 escape - 萬一未來發現了新的攻擊方法,你有機會改 code 應對,而不是進 DB 改資料 =============================================================== 第一點跟第三點我就不特別討論了,這邊專注在第二點上 範例像這樣 <h1><?= $title?></h1> <script>alert("標題是<?= $title?>")</script> 如果你存檔的時候就做 $title = htmlspecialchars($title) 那麼你就會不知道該怎麼對 javascript 做處理,於是 - <最新>高雄宇宙港遭恐怖份子攻擊 - h1 會顯示,但 script 會噴出怪訊息 - 群星齊唱"愛還記得嗎" - h1 會顯示,但 script 會爛掉 而且完全可以寫出不會被 htmlspecialchars 影響的 xss... 正解會是這樣 <h1><?= htmlspecialchars($title)?></h1> <script>alert("標題是" + <?= json_encode($title)?>)</script> 這些問題就算你用 template engine 也還是得注意,頂多是做起來比較輕鬆 例如 twig,預設是當成 html 來 escape,所以 <h1>{{ title }}</h1> <script>alert("標題是{{ title }}")</script> 還是會死在 javascript,正確的做法是 <h1>{{ title }}</h1> <script>alert("標題是{{ title|e('js') }}")</script> BTW,這邊有個隱藏大魔王叫做 URL 雖然塞在 html 裡面,但是用 htmlspecialchars() 清理是不夠的 因為有 data: 跟 javascript: 這種東西可以用,讓 escape 變得很麻煩 這邊建議用第三方 lib 來處理(例如 htmlpurifier),或根本不讓使用者自填 url... =============================================================== 總之,你在不同的地方,需要用不同的方式 escape 資料 「事先 escape 然後到處通用」這條路...很可惜的是不通的 而為了讓每個地方都能正確的 escape,你必須保留原始的輸入資料 -- 這閃電拳能射出雷射光,威力每平方公分一萬億瓦特 威力無比,拳到之處,攻無不克 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 60.248.122.206 ※ 文章網址: https://www.ptt.cc/bbs/PHP/M.1469071079.A.9CD.html

07/21 12:03, , 1F
Yea, use the source
07/21 12:03, 1F
※ 編輯: GALINE (60.248.122.206), 07/21/2016 13:00:59

07/21 13:17, , 2F
07/21 13:17, 2F

07/21 13:35, , 3F
感謝G大分享,這篇真的很實用,尤其對我這種新手 QQ
07/21 13:35, 3F

07/21 13:36, , 4F
另外想補問,用了escape是否就無法使用n2lbr? 可是這樣取jso
07/21 13:36, 4F

07/21 13:37, , 5F
n格式時,會被換行符號斷行.. 用了n2lbr會變成取<br> 囧!
07/21 13:37, 5F

07/21 16:25, , 6F
可以先htmlspecialchars()再nl2br()阿
07/21 16:25, 6F

07/21 16:25, , 7F
還是你escape的情況不一樣
07/21 16:25, 7F

07/21 16:55, , 8F
我是希望能像Dcard取留言的json格式一樣,像是這樣:
07/21 16:55, 8F

07/21 16:56, , 9F
https://goo.gl/qgExPE 裡面把換行換成\n,其他都能正常顯示
07/21 16:56, 9F

07/21 16:56, , 10F
可是我用n2lbr的話,會在json變成<br>,然後在urldecode()後
07/21 16:56, 10F

07/21 16:57, , 11F
就會變成斷行了
07/21 16:57, 11F

07/22 11:05, , 12F
斷行經過json_encode就會變\n不需要先nl2br啊
07/22 11:05, 12F

07/25 02:09, , 13F
感謝各位前輩指點,後來發現header沒設定到json格式,才衍伸
07/25 02:09, 13F

07/25 02:09, , 14F
很多問題出來 XD
07/25 02:09, 14F
文章代碼(AID): #1Na3xddD (PHP)
文章代碼(AID): #1Na3xddD (PHP)