2012-01-06 94 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