淺析Java執行外部命令的幾個要點(4)——支持shell的"|","`","*","?"等特殊符號

轉貼請註明出處:http://blog.csdn.com/froole

在上一章已經驗證了CommandExec可以很好的支持超時功能,通過它可以更方便的執行外部命令。
但是,這裏還有一點需要注意——那就是shell(DOS)中的特殊符號。
因爲用Java作爲後臺程序的系統,多運行於Unix/Linux,以下的介紹將基於如何shell來展開討論。

假設,系統需要通過提取某個命令的標準輸出,來進行某項處理。例如,搜索/路徑下的xml文件並對結果處理,如下:
find / -name "*.xml" -type f | xargs java 相應程序
如果按照常規的方式,將以上的幾個字串直接傳遞給Runtime.exec的參數,通過CommandExec的實現方法如下:
  1. CommandExec exec = new CommandExec();
  2. Process process = exec.exec(new String(){"find""/""-name""/"*.xml/"""-type""f""|""xargs""java""相應程序"});

但是,實際結果將事與願違,因爲,在解析"|"的時候是以特殊符號來解析,而JVM將把"|"作爲普通的字符串來處理。
在通常的處理中,這種功能可以屏蔽命令溢出的漏洞,但是在特殊需求的時候,就不方便了。
當然,在特殊需求下也有解決方法,可以如下執行以下命令:
  1. CommandExec exec = new CommandExec();
  2. Process process = exec.exec(new String(){"shell""-c""/"find / -name '*.xml' -type f | xargs java 相應程序/""});

也就是把要執行的命令作爲shell的一個參數讓Runtime.exec執行,爲shell命令加上-c參數就可以正常執行目標命令了。

細心的讀者已經看出,用上面的方法,有一個缺點就是,如果動態生成命令,很容易發生命令溢出的漏洞。
這裏有一個解決方法,就是設定一個前提,被執行命令,文字串都必須以單引號包含,那樣就比較容易escape了。
escape的方法可以如下定義,並添加到CommandExec當中。
  1.     /**
  2.      *
  3.      * 對shell字串進行escape
  4.      *
  5.      * @param s 對象字串
  6.      * @return 返回escape之後的shell字串
  7.      */
  8.     public static String escapeShellSpecialCharacters(String s) {
  9.         StringBuilder sb = new StringBuilder(s.length() + 128);
  10.         sb.append('/'');
  11.         for (int i = 0; s != null && i < s.length(); i++) {
  12.             char c = s.charAt(i);
  13.             if (c == '/'') {
  14.                 sb.append('//');
  15.             }
  16.             sb.append(c);
  17.         }
  18.         sb.append('/'');
  19.         return sb.toString();
  20.     }
JVM執行外部命令功能的漏洞
到此爲止,在Java中執行外部命令的方法以及注意點基本敘述完畢。但是,最後還有一點必須注意的就是JVM本身存在的一個漏洞。

這個漏洞的現象是,當被執行的外部命令,標準輸出的量比較大的時候,程序會無故鎖死。
特別是在JDK1.3版本尤爲明顯,在新版本中仍舊存在此漏洞。
不過,通過外部命令的執行方式,可以避免此漏洞的出現——通過重定向避免標準輸出。
CommandExec的執行方法如下:
  1. CommandExec exec = new CommandExec();
  2. Process process = exec.exec(new String(){"shell""-c""/"find / -name '*.xml' -type f | xargs java 相應程序 > /dev/null/""});

到此結束,歡迎拍磚!

相關:
-淺析Java執行外部命令的幾個要點(1)
-淺析Java執行外部命令的幾個要點(2)
-淺析Java執行外部命令的幾個要點(3)
-淺析Java執行外部命令的幾個要點(4)

<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
轉貼請註明出處:http://blog.csdn.net/froole
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章