2011-02-14 75 views
3

我有一個通過Apache或命令行調用的Perl腳本。如何使用setuid()作爲cgi-bin成功運行Perl腳本?

出於測試目的,我將它傳遞給我想要Perl腳本運行的用戶名,並使用POSIX::setuid來設置uid

如果我運行在命令行腳本,則uid正確設置:

use CGI::Pretty qw/:standard/; 
use POSIX qw(setuid getuid); 

... 
my ($pwName, $pwCode, $pwUid, $pwGid, $pwQuota, $pwComment, 
    $pwGcos, $pwHome, $pwLogprog) = getpwnam($username); 

if ((defined $pwUid) && (getuid() == $pwUid)) { 
    setuid($pwUid); 
    print header; 
    print Dumper $<; 
} 
else { 
    print header(-status => 401); 
    print "Could not setuid to correct uid (currently:)".getuid()."\n"; 
} 

命令行輸出顯示指定$username的正確uid,代替測試帳戶的uid開始運行腳本。

如果我通過Apache調用腳本,那麼uid仍然設置爲apache用戶的ID,並且永不改變。

我不相信我可以用suExec在這裏,因爲,閱讀文檔後:

  1. 我不能把這個腳本的副本到http://www.example.com/~username每一個$username。腳本需要從一個位置運行,我需要在腳本中指定uid

  2. 我需要在運行時將腳本作爲指定的用戶名運行,而不是在Apache配置文件中的虛擬主機指令中指定的單個用戶名。每當新用戶運行此腳本時,更改此配置文件並重新啓動Apache是​​不現實的。

我如何獲得一個Perl腳本運行的cgi-bin目錄正確地改變uid,用setuid()什麼時候?

+1

您的命令行用戶可能有權更改其UID,您的web服務器用戶可能不會? – Konerak 2011-02-14 10:26:12

回答

4

您可以將setuid轉換爲任意uid的唯一方法是以root用戶身份運行[1]。

我不瞭解你,但是以root身份運行CGI程序的想法給了我惡夢。

此代碼應該在更改uid後實際執行的是什麼?也許有辦法做到這一點,而不必setuid

[1]根據您的代碼和安全模型,您可能能夠收集用戶的密碼並使用su/sudo [2]運行單獨的命令行程序以在網絡外運行實際操作服務器環境,但su/sudo能夠做到這一點,因爲它們是suid root,它仍然會打開與以root用戶身份運行CGI代碼相關的大部分/所有問題。即使您將root用戶過濾爲無效的用戶名,也可以僞裝成任意用戶,從而爲濫用提供了大量機會。

[2] sudo甚至可以配置爲允許它不需要密碼,但是會有龍下來的路徑。確保你知道自己在做什麼,以免讓用戶隨意冒充對方冒充對方。

+0

這個cgi-bin與Ajax調用一起使用。該腳本應該以指定的用戶身份運行,以限制該用戶訪問其Web服務器可訪問的文件系統上的文件列表。 – 2011-02-14 11:02:04