2015-08-09 16 views
4

在我的PHP應用程序中,我有這個textarea框從用戶接收降價(如stackoverflow的),然後它顯示在網站上。我正在使用Laravel Framework並使用parsedown-laravel包。
我可以這樣做:如何從用戶的降價輸入中刪除腳本標記?

{!! Markdown::parse('__Hello__ Markdown!'); !!} 

它的工作原理。

{!! Markdown::parse('<h1>Hello</h1> Markdown!'); !!} 

它仍然有效。我相信這一點。

現在,如果我做的:

{!! Markdown::parse('<script>alert("XSS Attack!!!")</script> Markdown!'); !!} 

它仍然有效!

如何使用Laravel和此包阻止應用程序中的腳本標記?

+0

這可能是相關的:https://github.com/erusev/parsedown/issues/229 – spenibus

回答

-2

接受用戶輸入並將其與應用程序代碼無縫整合永遠不會安全。這是不行的。

如果這只是顯示代碼,那麼您可以使用<textinput>標籤來實現。你可以設計它,使其看起來不像輸入。或者,您只需使用htmlescape()<pre>標籤組合的功能即可。

+0

這是行不通的,因爲降價解析器將創建HTML標籤和'htmlentities'(我假設你的意思是,因爲'htmlescape'不存在於PHP中)也會逃避這些標籤。輸入元素會有同樣的問題。 – Frog

5

如果您看看Markdown規範(original syntax by Jon GruberCommonMark),您會發現Markdown不應取代HTML。它唯一的目標是讓你更容易閱讀你寫的文字。由於Markdown僅涵蓋HTML標籤的一小部分,您仍然可以使用HTML代碼內聯來創建您想要的內容。事實上,約翰格魯伯說:

對於Markdown的語法沒有涵蓋的任何標記,你只需使用HTML本身。沒有必要在前言或分隔它以表明您正在從Markdown切換到HTML;你只需使用標籤。

所以基本上,這是Markdown應該工作的方式。顯然,如果你解析用戶的輸入,情況就不會如此。由於Markdown解析器輸出HTML代碼,因此不能使用htmlentities函數或類似的解決方案。

解決問題的最簡單方法是使用像HTML Purifier這樣的HTML過濾庫。這會從您的Markdown輸出中刪除惡意代碼,並嘗試阻止XSS攻擊。基本上你應該首先調用你的Markdown解析器,並使用該輸出調用HTML Purifier庫。

3

原來Parsedown庫中有一個選項,以逃避HTML:

echo Parsedown::instance() 
    ->setMarkupEscaped(true) # escapes markup (HTML) 
    ->text("<div><strong>*Some text*</strong></div>"); 

# Output: 
# <p>&lt;div&gt;&lt;strong&gt;<em>Some text</em>&lt;/strong&gt;&lt;/div&gt;</p> 

Parsedown Tutorial: Get Started

據推測,因爲parsedown-laravel是隻是一個包裝,你應該能夠訪問選項。

顯然,這將禁用所有標記而不是特定的標記。

的GitHub上issue 229 - Disable parsing of specific elementsParsedown錯誤追蹤用戶moldcraft提供following code,這可能鋪平道路的解決方案:

moldcraft評論2月24日•2015-02-24 18時41分31秒+0100

可能對某人有用:我也使用Parsedown進行用戶評論,我想用h4替換所有h1,h2,h3以防止SEO警告(例如,只有一個h1必須在頁面上),這裏是我的Symfony2服務

<?php 

namespace App\MainBundle\Service; 

use Parsedown; 
use HTMLPurifier; 
use Emojione\Emojione; 
use Symfony\Component\DependencyInjection\ContainerInterface; 

class Markdown extends Parsedown 
{ 
    /** 
    * @var HTMLPurifier 
    */ 
    private $purifier; 

    public function __construct(ContainerInterface $container) 
    { 
     $this->setMarkupEscaped(true); 

     { 
      $purifierConfig = array(
       'HTML.ForbiddenElements' => array('h1', 'h2', 'h3'), 
       'HTML.ForbiddenAttributes' => array('style', 'onclick',), 
       'HTML.TargetBlank' => true, 
      ); 

      $this->purifier = new HTMLPurifier($purifierConfig); 
     } 

     { 
      Emojione::$imageType = 'svg'; 
      Emojione::$sprites = true; 
      Emojione::$imagePathSVGSprites = $container->get('templating.helper.assets')->getUrl(
       'bundles/appmain/emojione/sprites/emojione.sprites.svg' 
      ); 
      Emojione::$ascii = true; 
     } 
    } 

    function text($raw) 
    { 
     return Emojione::shortnameToImage(
      $this->purifier->purify(
       parent::text($raw) 
      ) 
     ); 
    } 

    private function safeHeader($Block) 
    { 
     if ($Block && isset($Block['element'])) { 
      /** 
      * Change h1, h2, h3 to h4 
      */ 
      if (in_array($Block['element']['name'], array('h1', 'h2', 'h3'))) { 
       $Block['element']['name'] = 'h4'; 
      } 
     } 

     return $Block; 
    } 

    protected function blockHeader($Line) 
    { 
     return $this->safeHeader(
      parent::blockHeader($Line) 
     ); 
    } 

    protected function blockSetextHeader($Line, array $Block = null) 
    { 
     return $this->safeHeader(
      parent::blockSetextHeader($Line, $Block) 
     ); 
    } 
} 
+0

這基本上使用我建議的HTMLPurifier與其他圖像特定的東西。 ;) – Frog

相關問題