2012-01-06 102 views
2

我在本地網絡上爲我的家人創建了一個簡單的http服務器,當我添加一個html文件和png圖片並試圖查看該HTML文件時,我的圖像無法加載。
它說:
「的圖片:‘http:// :。255/header.png’無法顯示,因爲它包含錯誤」
這裏有點我的代碼python http web服務器

 elif self.path.endswith(".bm"): #our dynamic content 
      self.send_response(200) 
      self.send_header('Content-type', 'text/html') 
      self.end_headers() 
      f= open(curdir + sep + self.path) 
      ren = self.render(f.read()) 
      self.wfile.write(ren) 
      return 
     elif self.path.endswith('.png'): 
      print "IMAGE WANTED!" 
      self.send_response(200) 
      self.send_header('Content-type', 'image/png') 
      self.end_headers() 
      f = open(curdir + sep + self.path) 
      self.wfile.write(f.read()) 
      return 
     elif self.path.endswith('.jpg'): 
      print "IMAGE WANTED!" 
      self.send_response(200) 
      self.send_header('Content-type', 'image/jpeg') 
      self.end_headers() 
      f= open(curdir + sep + self.path) 
      print f.read() 
      self.wfile.write(f.read()) 
      return 
     elif self.path.endswith(".esp"): 
      self.send_response(200) 
      self.send_header('Content-type', 'text/plain') 
      self.end_headers() 
      self.wfile.write("This Format Is Not Supported Any More, Upgrade To BM Script") 
      return 

他們除了PNG和JPEG部分的所有工作。 BM腳本我自己做的,與esp一樣,這樣就沒什麼了

+2

請告訴我,這將永遠不會從互聯網上,因爲你將有一個寬敞的安全漏洞(你允許相對路徑像'../../../ etc/passwd \ 0') – 2012-01-06 01:09:07

+5

爲什麼不要只使用內置的'python -m SimpleHTTPServer'。這將提供當前目錄。 – wim 2012-01-06 01:21:46

回答

7

open的默認模式是'r',它代表讀取文本數據並在Windows上自動進行EOL轉換。與

fn = os.path.normpath(os.path.join(curdir, self.path)) 
if not fn.startswith(abspath + os.path.sep): 
    raise Exception('Path traversal attempt') 
with open(fn, 'rb') as f: 
    self.wfile.write(f.read()) 

更換f = open(curdir + sep + self.path); self.wfile.write(f.read())with聲明修復的文件句柄泄漏。或者(在Python < 2.5上),你可以手動調用f.close()

os.path.join(您可能需要在文件的開頭爲import os.path)是比字符串連接更清潔的文件名構建機制。檢查生成的文件名是否在您期望的目錄中會阻止path traversal vulnerability,允許任何人讀取系統上的所有文件。

+0

我可能會遺漏一些東西,但* normpath *如何防止路徑遍歷?我的理解是,它只是「正常化」一條路,基本上只是把它清理乾淨。 A // B,A/B /,A /./ B和A/foo /../ B都變成A/B。 – monkut 2012-01-06 02:31:34

+0

@monkut - 您使用normpath將web根目錄與用戶路徑進行連接,然後確保它實際上以webroot開頭:import os; root =「/ web/root」; path_from_client =「../../etc/passwd」; os.path.normpath(os.path.join(root,path_from_client))。startswith(root)' – jdi 2012-01-06 03:08:37

+0

@jdi這是有道理的,但在這裏的答案看起來並不清楚。對* normpath *的調用本身並不能保護你不受路徑遍歷的影響。 – monkut 2012-01-06 04:12:55