6個”檔案上傳”功能的資訊安全風險與防護
有些網站會提供檔案上傳的功能,例如 DropBox、社交網站提供照片上傳或是部落格網站提供檔案上傳分享等功能。
駭客可以透過檔案上傳的方式執行惡性程式或是產生非預期的結果。因此,檔案上傳的安全防護不亞於帳號密碼的保護措施。
這篇文章主要討論這些”檔案上傳”的網站,需要注意哪些資訊安全風險與防護的建議。
我們會舉 6 個檔案上傳相關安全風險的原因、程式範例討論與安全防護必須要注意的建議。
風險1: 檔案路徑
file path injection 又稱為 path traversal。這樣的攻擊主要是透過檔案路徑的搜尋,間接存取其他網站的資源。
當URL 網址的路徑內包含 ../ 就表示該網站有潛在的風險
舉例來說,下列檔名的參數中,帶有路徑位置,因此駭客就可以藉由修改路徑位置,間接存取網站伺服器其他檔案資源。
http://www.awesomefileupload.com/downloadFile?filename=/../downloadSrc/my_vacation_photos.zip
例如,駭客可能會嘗試下列網址
http://www.awesomefileupload.com/downloadFile?filename=/../../../../etc/passwd
因此,針對這樣的攻擊,並須對於檔案名稱的輸入加以過濾。相關檔案的權限管理必須加以限制。
風險2: Null Byte Injection
Null 在系統內部,主要告訴電腦說,這是這個字串的結尾。
在一些舊版的IIS 或是Java 對於這樣的 Null 並沒有妥善的處理,會導致一些非預期的行為。讓我們看幾個個案如果使用null byte (%00)在檔名中,會發生什麼情況?
例如
http://www.site.com/files?filename=../../../../etc/passwd%00profile.jpg
雖然剛輸入的檔名為 JPG 結尾,但是舊版的 Java 程式讀取,
還是會直接讀取到 /etc/passwd。
雖然這樣的漏洞已經在 Java 7之後修正,
但是正確的處理 Null byte 的輸入,還是處理輸入值重要的一環。
風險3: 沒有適當的關閉資源
當每一個檔案被開啟時,都有會一個相對應的 handle 紀錄該檔案開啟的狀態。
檔案沒有被使用的時候,應該要適時的將該 Handle 關閉。讓系統資源釋放。
如果長時間都沒有關閉 Handle,會慢慢地導致系統資源不足,
甚至系統當機,需要重新開機才能解決。
以下列這個例子,finally這段 code就很重要,因為不管是正常執行還是發生 I/O exception 都還是要 close file handles。
[pastacode lang=”java” message=”Close File Handle” highlight=”16,17,18″ provider=”manual”]
try {
fileIn = getUploadInputStream();
fileOut = new FileOutputStream(validatedFilePath);
byte[] buffer = new byte[bufferSize];
int byteCount = 0;
while ((byteCount = input.read(buffer)) >= 0) {
//what happens if an exception happens here?
output.write(buffer, 0, byteCount);
}
} catch (IOException ioe) {
//handle the exception somehow
} finally {
//close output streams to release memory resources!
fileIn.close();
fileOut.close();
}
[/pastacode]
但是這樣的寫法,如果遇到 close file handles 又出現 exception 那麼怎辦? 還要額外在處理這樣的 exception 比較複雜。Java 7之後提供 “try-with-resources statement”的寫法,可以自動處理相關 resource 的釋放與關閉。
[pastacode lang=”java” message=”try-with-resources statement” highlight=”3″ provider=”manual”]
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
[/pastacode]
風險4:上傳惡性程式
駭客可能利用一些檔案的特性,上傳惡性程式以達到特定行為。下列是比較常見被駭客使用的檔案格式。
- 病毒、惡性程式
- 還有 JavaScript 可以造成 CSRF 或是XSS攻擊的 HTML
- 可執行的程式。例如 JSP, JSPX, WAR, JAR, PHP, ASP, SH等
以下提供相關副檔名的處理方式,如果真的需要儲存該類的副檔名,建議將該儲存的伺服器與網站伺服器分開。
避免該儲存的檔案直接存放在與網站伺服器同一台機器。
副檔名 | 防護建議 |
HTMLHTM | 拒絕這樣的檔案上傳。因為 HTML可以內含有害的 JavaScript |
.JS | 拒絕JavaScript 可以帶來許多程式執行的風險,例如 JavaScript Injection, XSS, CSRF等。 |
.jsp, .jspx | 拒絕這類的檔案主要是 Java 網頁的執行。也會間接讓許多有害的程式執行。 |
war | 拒絕這是 JAR 檔案的集合。包含了 XML, HTML, JSP等。這樣的檔案可以控制取代整個網站的服務。更不能夠上傳。 |
jpg pnggif | 這些圖形檔的上傳必須要確認檔案格式的正確性。如何確認檔案格式的正確性,這邊另外介紹一個小技巧。”ImageMagick”ImageMagick是command-line的工具程式,可以用來轉換讀取各式各樣的圖形檔。使用這樣的工具,由於是 command-line 執行,要另外注意 command injection 的風險。 |
.zip | 在解壓縮之前要做一定的驗證。 |
.doc, .ppt, .txt, | 上傳之後,建議用防毒軟體做一定的掃描。 |
風險5:壓縮檔炸彈
這是一個特別製作的ZIP壓縮檔,該檔案壓縮的層數較多,壓縮之後再壓縮再壓縮…另外,解壓縮之後檔案高達好幾 G
因此,如果網站沒有經過驗證就直接解壓縮,很容易造成該網站資源耗盡無法運作。
http://www.unforgettable.dk/
目前有許多程式都提供相關的 API 可以檢查壓縮檔。
例如下列 Java 程式碼,在實際解壓縮之前,檢查該壓縮檔案解開後的大小 。
[pastacode lang=”java” message=”Get uncompressed ZIP filesize” highlight=”19″ provider=”manual”]
import java.io.IOException;
import java.util.Date;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class MainClass {
public static void main(String[] args) {
try {
ZipFile zf = new ZipFile("your.zip");
Enumeration e = zf.entries();
while (e.hasMoreElements()) {
ZipEntry ze = (ZipEntry) e.nextElement();
String name = ze.getName();
long uncompressedSize = ze.getSize();
long compressedSize = ze.getCompressedSize();
System.out.println(name);
System.out.println(uncompressedSize);
System.out.println(compressedSize);
}
} catch (IOException ex) {
System.err.println(ex);
}
}
}
[/pastacode]
參考:http://www.java2s.com/Tutorial/Java/0180__File/GetuncompressedandcompressedSize.htm
風險6:真實檔名
檔案上傳 之後使用一個對照的 ID來儲存,不要用使用者所提供的檔名儲存。
可進一步參考,這裡有些關於”檔案上傳”的安全設計建議,
https://wiki.mozilla.org/WebAppSec/Secure_Coding_Guidelines#Uploads
http://software-security.sans.org/blog/2009/12/28/8-basic-rules-toimplement-secure-file-uploads/
摘要
針對網站有提供檔案上傳功能,需要注意下列事項:
- 確認檔案相關的權限,特別是寫入的權限應該要透過控管。
- 確認檔名。例如 null byte 或是特殊符號的禁止。像是 / or \ ‘ 或是 ..。
- 確認檔案內的型態內容。例如JPG, PNG 為副檔名時,確認該檔案是否為圖形檔。
- 檢查檔案的 File headers以確認該檔案內容型態。
- 用防毒軟體掃描該檔案是否為已知惡性程式。
- 禁制特定類型可執行的檔案。例如 JS, EXE, SH, HTML 等