2010-01-29 25 views
12

我的(基於Perl的)應用程序需要讓用戶輸入正則表達式來匹配幕後的各種字符串。我的計劃迄今已採取的字符串,並把它包在像如何安全地使用用戶輸入的正則表達式?

$regex = eval { qr/$text/ }; 
if (my $error = [email protected]) { 
    # mangle $error to extract user-facing message 

$text已經被剝奪了換行的時間提前,因爲它是在一個多行文本字段實際上多正則表達式,我split)。

這樣做有沒有任何潛在的安全風險 - 一些奇怪的輸入可能導致任意代碼執行? (除了像CVE-2007-5116這樣的正則表達式引擎中的緩衝區溢出漏洞外)。如果是這樣,是否有辦法緩解它們?

有沒有更好的方法來做到這一點?任何有助於抽象將用戶輸入轉換爲正則表達式的操作的抽象Perl模塊(比如提取錯誤消息......或者提供像/i這樣的修飾符,我在這裏不需要這些修飾符,但會很好)?我搜查CPAN並沒有發現太多有希望的東西,但是我有可能錯過了一些東西。

+4

你的意思是像'(?{code})'令牌? – 2010-01-29 01:44:55

+0

曾聽說過taintperl? – Ether 2010-01-29 04:20:40

+3

@Ether:如何幫助這裏的污點?它有助於防止您在可能導致安全問題的情況下意外使用不可信輸入。在這裏,我們正在尋找一種安全使用不可信的正則表達式的方法。 – cjm 2010-01-29 09:15:03

回答

5

使用(?{ code })構造,可以使用用戶輸入來執行任意代碼。見例如perlre#code並在那裏說

local $cnt = $cnt + 1, 

與表達

system("rm -rf /home/fennec"); print "Ha ha.\n"; 

取代它(事實上,不這樣做。)

+4

幸運的是,如果正則表達式包含可變插值,除非您說'use re'eval''(正是由於這個原因)''(?{code})'會導致編譯時錯誤。 – cjm 2010-01-29 06:07:35

+1

@cjm - 但是說'$ re = eval {qr/$ tainted /}'然後使用該正則表達式並不是錯誤,因爲OP已經完成了(除非使用'taintperl') – mob 2010-01-29 14:48:03

+0

啊,在幫助下我在文檔中發現了這一點: 「在Perl知道如何在模式中執行內插代碼之前,從安全的角度來看,這個操作是完全安全的,儘管它可能會引發一個非法模式的異常。」這很安慰。 – fennec 2010-01-29 18:09:42

3

最好的辦法,就是不要讓用戶有太多特權。爲用戶提供足夠的界面,讓他們做他們想做的事。 (就像一臺只有各種選項按鈕的ATM機,不需要鍵盤輸入)。當然,如果你需要用戶鍵入輸入,然後提供文本框,然後在後端,使用Perl來處理請求(例如消毒等)。讓用戶輸入正則表達式的動機是搜索字符串模式?那麼在這種情況下,最簡單最安全的方法就是告訴他們只輸入字符串。然後在後端,使用Perl的正則表達式來搜索它。是否有任何其他令人信服的理由讓用戶輸入正則表達式?

+1

假設他們想要搜索* patterns *,搜索普通字符串的能力要比通過正則表達式搜索要小得多。 – geoffspear 2010-01-29 02:20:44

+1

是的。 $客戶要求比在這種情況下簡單的字符串匹配能夠提供更多的靈活性。 至於權限,但只有適度信任的用戶才能執行正則表達式。我只是不想擴展這些用戶系統(「rm -rf /」)功能等。 – fennec 2010-01-29 18:02:00

6

使用不可信的輸入作爲正則表達式創建拒絕服務漏洞,如perlsec中所述:

正則表達式 - Perl的正則表達式引擎被稱爲NFA(非確定性有限自動機),其中 意味着如果正則表達式可能以多種方式匹配,它可以非常容易地消耗大量的時間和空間。 精心設計正則表達式可以幫助,但很多時候確實沒有太多人能夠做到(「掌握常規 表達式」是必讀內容,請參閱perlfaq2)。空間不足表現爲Perl耗盡內存。

+2

我可以應付暴露的DOS漏洞。善良知道其他人可以輸入這些正則表達式的其餘部分有很多。不過,一個神奇的'擦除硬盤'按鈕是另一回事。 :) – fennec 2010-01-29 17:57:53

1

有關於此的一些討論在The Monastery

TLDR:use re::engine::RE2 -strict => 1;

確保添加-strict => 1您使用的語句或重新::引擎:: RE2將回落到Perl的重。

以下是從保羅Wankadia(junyer),該project on GitHub的所有者引文:

RE2的設計和具有能夠處理來自不可信用戶的正則表達式沒有風險的明確目標實現。其主要保證之一是匹配時間在輸入字符串的長度上是線性的。還考慮到了生產問題:解析器,編譯器和執行引擎通過在可配置的預算內工作來限制其內存使用率 - 在耗盡時優雅地失敗 - 並且它們通過避免遞歸來避免堆棧溢出。

要總結要點:

  • 這是一個從任意代碼執行默認情況下的安全,但增加了「不重‘EVAL’;」防止PERL5OPT或其他任何東西?從設置你。我不確定是否這樣做會阻止一切。

  • 使用BSD :: Resource(即使在Linux上)的子進程(fork)來限制內存並在某些超時後終止子進程。

相關問題