Search code examples
asp.netiisurl-rewritinghttpresponse

Unable to open export excel file on hiding response headers using URL Rewrite


I have an export to excel code as below:

<%
    Server.ScriptTimeout = 600
    
    'Security check passed, proceed:
    Dim conn, rs, sql, x, outlen
    
    Set conn = Server.CreateObject("ADODB.Connection")
    Set rs = Server.CreateObject("ADODB.Recordset")
    
    sql = "exec " & Request.QueryString("sp") & " "
    For t = 1 To Request.QueryString("p").Count
        'Escape single quotes for SQL:
        If t > 1 Then sql = sql & ", "
        sql = sql & "'" & Replace(Request.QueryString("p").Item(t), "'", "''") & "'"
    Next
    conn.CommandTimeout = 600
    conn.Open strConnString_CyberAgent_WithProvider
    rs.Open sql, conn

    'Prepare the response:
    Response.Buffer = True
    Response.CacheControl = "Private"  
    Response.Expires = 0 
    Response.Clear
    outlen = 0
    
    'Prepare the message headers (Any subsequent response.writes will fall inside the file!)
    Response.AddHeader "Content-Disposition", "attachment; filename=Export.xls"
    Response.ContentType = "application/vnd.ms-excel"
    
    'Output headers:
    For x = 0 To rs.Fields.Count - 1
        If x > 0 Then
            Response.Write(chr(9))
            outlen = outlen + 1
        End If
        Response.Write(rs.Fields.Item(x).Name)
        outlen = outlen + len(rs.Fields.Item(x).Name)
    Next
    Response.Write(chr(13) & chr(10))
    outlen = outlen + 2
    'Loop through records:
    Do While Not rs.EOF
        For x = 0 To rs.Fields.Count - 1
            If x > 0 Then
                Response.Write(chr(9))
                outlen = outlen + 1
            End If
            Response.Write(rs.Fields.Item(x).Value)
            if not(isnull(rs.Fields.Item(x).Value)) then outlen = outlen + len(rs.Fields.Item(x).Value)
        Next
        Response.Write(chr(13) & chr(10))
        outlen = outlen + 2

        rs.MoveNext
    Loop
    rs.Close
    conn.Close 
    
    Set rs = Nothing
    Set conn = Nothing

    Response.AddHeader "Content-Length", outlen

    'Flush the buffer, sending the user the file
    Response.Flush
%>

I am able to download the reports normally but in order to mitigate security vulnerability, I hide the response headers like server name and asp.net version using the URL Rewrite in IIS by adding the below in my web.config

<rewrite>
    <outboundRules>
        <rule name="Remove Server">
            <match serverVariable="RESPONSE_SERVER" pattern=".+" />
            <action type="Rewrite" />
        </rule>
        <rule name="Remove Asp.Net Version">
            <match serverVariable="RESPONSE_X-ASPNET-VERSION" pattern=".+" />
            <action type="Rewrite" />
        </rule>
            <rule name="Remove Umbraco Version">
            <match serverVariable="RESPONSE_X-UMBRACO-VERSION" pattern=".+" negate="false" />
            <action type="Rewrite" />
        </rule>
    </outboundRules>
</rewrite>

<customHeaders>
<remove name="Server" />
<remove name="X-AspNet-Version" />
<remove name="X-Powered-By" />
</customHeaders>

The problem is that adding the rules to block response headers is causing the excel file to not open on download. It throws an error and this makes me wonder if there is any other way to block the response headers while not disturbing the export process.


Solution

  • Okay so I was able to block all but Server response headers and I will share what worked for me so far:

    X-AspNet-Version :

    Just add the attribute enableVersionHeader="false" to <httpRuntime/>. It should look as follows :

    <system.web>
      <httpRuntime enableVersionHeader="false" />
    </system.web>
    

    X-Powered-By:

    1. Open IIS
    2. Select the Sitename under Sites folder
    3. Select HTTP Response Headers under IIS response-headers-module
    4. Select X-Powered-By and remove the existing value and add an empty string.

    X-Powered-By

    Note: I will update once I am able to figure out a way to block server headers as well on this answer.