2011-10-12 45 views
1

我需要做些什麼才能正確清理/轉義正在輸入到編程SSH命令中的參數?進入SSH命令的Sanitize/escape參數

例如,路徑參數 -

public boolean exists(String path) { 

    try { 
     ChannelExec c = (ChannelExec) session.openChannel("exec"); 

     //Here *** would like to be sure that the path is completely valid 
     c.setCommand("[ -f " + path + " ] && echo \"File exists\" || echo \"File does not exists\""); 

     InputStream in = c.getInputStream(); 

     c.connect(); 

     ByteArrayOutputStream out = new ByteArrayOutputStream(); 

     IOUtils.copy(in, out); 

     in.close(); 
     out.close(); 

     System.out.println(out.toString("UTF-8")); 
     c.disconnect(); 

    } catch (JSchException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    // TODO Auto-generated method stub 
    return false; 
} 

其原因是不安全是該路徑參數可以來自用戶的上傳。惡意用戶可能會在技術上上載帶有無效文件名的文件。雖然我可以事先檢查(我正在做這個),但我也想在這裏檢查一下。

+0

取決於你的意思是「無效」的東西,我想。 –

+0

惡意。確保它本身沒有執行「SSH注入」... –

+0

只是反斜槓不是「正常」的所有內容,所以它肯定是一個文件名,我猜?特別是分號,當然。 –

回答

1

我認爲這裏的一個好主意是確保它作爲單個參數傳遞給[,而不是多個(甚至多個命令)。因此,簡單地將它包裝在'中,並用'\''代替字符串內的任何'

private String escape(String s) { 
    return "'" + s.replace("'", "'\\''") + "'"; 
} 

您還可以使用'代替\"該命令的echo一部分,只要你不需要在服務器端變量擴展(也有在這些字符串沒有變量):

c.setCommand("[ -f " + escape(path) + " ] && " + 
       "echo 'File exists' || echo 'File does not exist'"); 

(請注意,我還做了一個小小的語法修正。)

+0

我喜歡這裏要去的地方......非常感謝答案。它返回的文件不存在,但。我會繼續修補它,看看我能否得到它的工作 –

+0

此外,爲什麼使用'''''而不是隻用'\''來轉義? –

+0

我從[這個Unix&Linux問題](http://unix.stackexchange.com/q/4770/5779)得到了這個引用機制,它很好地解釋了它。 * Bourne-like貝殼的單引號實際上是字面的(這意味着你不能用它來引用單引號字符本身)。* –