Asp.net mvc C#MVC:对png、jpg或pdf返回值进行编码以防止XSS

Asp.net mvc C#MVC:对png、jpg或pdf返回值进行编码以防止XSS,asp.net-mvc,image,security,encoding,xss,Asp.net Mvc,Image,Security,Encoding,Xss,假设我有一个C#MVC应用程序,它有一个控制器方法,返回三种内容类型之一:image png、image jpeg或application pdf。我已经读到,可能有包含XSS有效载荷的图像。对这些返回内容进行编码/转义的最佳方法是什么,这样它们就不会受到XSS的攻击?控制器方法如下所示: string contentType = "image/png"; MemoryStream mem = new MemoryStream();

假设我有一个
C#
MVC应用程序,它有一个控制器方法,返回三种内容类型之一:
image png、image jpeg或application pdf
。我已经读到,可能有包含
XSS
有效载荷的图像。对这些返回内容进行编码/转义的最佳方法是什么,这样它们就不会受到
XSS
的攻击?控制器方法如下所示:

string contentType = "image/png";
                    MemoryStream mem = new MemoryStream();
                    if (ImageFormat == null || ImageFormat == "")
                    {
                        image.Save(mem, System.Drawing.Imaging.ImageFormat.Png);
                    }
                    else
                    {
                        if (ImageFormat.ToUpper() == "PNG") image.Save(mem, System.Drawing.Imaging.ImageFormat.Png);
                        if (ImageFormat.ToUpper() == "JPEG")
                        {
                            image.Save(mem, System.Drawing.Imaging.ImageFormat.Jpeg);
                            contentType = "image/jpeg";
                        }
                    }
                    mem.Position = 0;
                    mem.Seek(0, SeekOrigin.Begin);
                    return this.Image(mem, contentType);
此处定义了以下类别的图像:

using …

    namespace x.Classes
    {
        public static class ControllerExtensions
        {
            public static ImageResult Image(this Controller controller, Stream imageStream, string contentType)
            {
                return new ImageResult(imageStream, contentType);
            }        
       }
    }
输出流通过以下方式写入:

using …
namespace x.Classes
{
    public class ImageResult : ActionResult
    {
        public ImageResult(Stream imageStream, string contentType)
        {
            if (imageStream == null)
                throw new ArgumentNullException("imageStream");
            if (contentType == null)
                throw new ArgumentNullException("contentType");
           this.ImageStream = imageStream;
           this.ContentType = contentType;
       }
       public Stream ImageStream { get; private set; }
       public string ContentType { get; private set; }
       public override void ExecuteResult(ControllerContext context)
       {
           if (context == null)
               throw new ArgumentNullException("context");
           HttpResponseBase response = context.HttpContext.Response;
           response.ContentType = this.ContentType;
           byte[] buffer = new byte[4096];
           while (true)
           {
               int read = this.ImageStream.Read(buffer, 0, buffer.Length);
               if (read == 0)
                   break;
               response.OutputStream.Write(buffer, 0, read);
           }
           response.End();
       }
   }
}
有没有一种方法可以让我转义/编码正在写入OutputStream的缓冲区:`

response.OutputStream.Write(buffer, 0, read);
要防止
XSS
攻击?例如,如果返回的是
HTML

response.OutputStream.Write(HttpUtility.HtmlEncode(buffer), 0, read);

但是我们知道我们返回的是jpeg、pdf或png,这意味着
Html
encode在这里不起作用。那么,我们使用什么来安全地转义/编码图像/pdf?

您不需要对图像本身进行编码,您需要对图像链接进行编码/转义

例如:

其中
image.url.png?注销
来自用户输入


您将url编码
image.url.png?以
image.url.png%3Flogout
的形式注销
,这样攻击者就不会使用它了。

当您准备好
缓冲区时,已经太晚了。与HTML一样,您希望对这些文件中的任何用户输入进行上下文敏感编码,而不是全部内容

现在,对于图像,这在XSS上下文中没有多大意义,图像由图像渲染器渲染,而不是作为html,因此不会运行任何javascript。上传图像的一般最佳做法是在服务器上处理它们并将其保存为新图像,因为这会删除所有不必要的内容,但如果处理器本身是攻击目标,则也会有风险

例如,SVG是一个不同的beast,SVG可以包含代码,PDF也可以。但同样,PDF将通过PDF查看器在客户端打开,而不是在web应用程序的上下文中打开,即使PDF查看器本身就是浏览器(浏览器希望将PDF中的Javascript与网页分离,即使源代码相同)

但是PDF中的javascript对于客户端来说仍然是一个问题。在PDF中运行的Javascript可能会做一些有害的事情,其中最简单的就是消耗客户端资源(即某种DoS),或者它可能会试图利用查看器漏洞突破PDF上下文。因此,攻击可能是一个用户上传恶意PDF供其他人下载。我认为你能做的最好的办法就是扫描上传的文件中的恶意软件(无论如何你都应该这样做)

如果您是从用户输入(图像、PDF)生成所有这些内容,那么您使用的库应该注意正确编码值,以便恶意用户不能在PDF中插入代码。当PDF已经生成时,您无法再“修复”它,用户输入与代码混合在一起

还要确保在回答中设置以下标题(以及正确的课程内容类型):
X-Content-Type-Options:nosniff

但在本例中,没有指向图像的链接。映像本身是流式传输到客户端/调用方的整个结果/响应。我正在用自定义的图像结果覆盖mvc操作结果。在这种情况下,我不相信有任何html被返回到客户端。XSS攻击通常发生在html页面上,而不是图像上。你唯一的问题是,如果有人可以上传给你的图像是有害的,由于图像解码器的问题。此外,PDF可能是可利用的。请注意,上面的编码不能防止
javascript:
,并且PDF可以包含javascript,但我认为即使在浏览器中打开,它也可以独立于web应用程序上下文运行,因此对web应用程序的影响较小(~零)(但对于其他原因,您可能仍然希望避免使用它,例如客户端DoS)。从我所读到的内容来看,XSS攻击可以通过图像元数据、注释或提取的标记进行。因此,我认为我需要找到一种方法对其进行加密。我认为我的内容类型设置可以保护我免受浏览器内容嗅探攻击,其中图像实际上只是一个带有图像文件扩展名的html文件。我还返回了.pdfs我不知道这些xss漏洞属于哪种类型。@Engelbart用户在这些字段中的输入只在你在HTML中的某个地方写入时才起作用。在这种情况下,在你写入它们的地方需要HTML编码。如果你将它们写入Javascript,你需要Javascript编码,但同样,与标准web应用程序一样。我认为stion是关于上述形式的注射。