Reveal Blocked Message URLs In Outlook Web Access 2010

[ 5 ] Comments
Share

There was a post in the MS Technet Exchange forum recently from someone who wanted to be able to open links to non-standard protocols in their OWA. Normally, if you click on a link that isn’t http or mailto, you will get the simple message saying ‘This link has been disabled to protect your security.’ Normally, this makes good sense, as you don’t want your users to click on unsafe links. But what if you really, really need to give them the option to do so? Well, it appears you’re stuck. As it happens, I found a way to get round it, but it involves replacing the UrlBlockedError.aspx file with a customised one that shows all the links in the message (along with their true destinations), and then the message itself once more, but with the links restored.

First, find your UrlBlockedError.aspx file in C:\Program Files\Microsoft\Exchange Server\V14\ClientAccess\Owa . Make a backup copy then open it in Notepad. Delete the entire contents, and replace with the code below:

<% @ Page AspCompat = True Language = "VB" %>
<strong>
The URL you clicked was originally blocked by Outlook Web Access.
If you are sure it is safe, please review the message below and try again.
</strong>
<hr>
<%
Dim strReferrer As String = Request.ServerVariables("HTTP_REFERER")
Dim p As Integer = Instr(strReferrer, "&id=")
If p <> 0 Then
  p = p + 4
  Dim p2 As Integer = Instr(p, strReferrer, "&")
  If p2 <> 0 Then
    Dim strOwaId = Mid(strReferrer, p, p2 - p)
    Dim objLogonUser As Object = Request.LogonUserIdentity
    strLogonUser = objLogonUser.Name
    strPassword = Request.ServerVariables("AUTH_PASSWORD")
    Dim strSID As String = objLogonUser.User.ToString()
    Dim objNameTranslate = Server.CreateObject("NameTranslate")
    objNameTranslate.Set(12, strSID) ' 12 = ADS_NAME_TYPE_SID_OR_SID_HISTORY_NAME
    Dim strDistinguishedName As String = objNameTranslate.Get(1) ' 1 = ADS_NAME_TYPE_1779
    Dim objUser As Object = GetObject("LDAP://" & strDistinguishedName)
    Dim arrProxyAddresses As Object
    Dim strSMTPAddress As String = objUser.mail
    objWinHTTP = Server.CreateObject("WinHTTP.WinHTTPRequest.5.1")
    objWinHTTP.SetAutoLogonPolicy(0)
    objWinHTTP.Option(4) = &H3300 ' Option_SSLErrorIgnoreFlags = SslErrorFlag_Ignore_All
    objWinHTTP.Option(6) = False ' Option_EnableRedirects
    objWinHTTP.SetTimeOuts(-1, -1, -1, -1)
    objXMLDOM = Server.CreateObject("MSXML2.DomDocument")
    Dim strXML As String
    strXML = _
     "<m:ConvertId DestinationFormat=""EwsId"">" & _
     "<m:SourceIds>" & _
     "<t:AlternateId Format=""OwaId"" Id=""" & strOwaId & """ Mailbox=""" & strSMTPAddress & """ />" & _
     "</m:SourceIds>" & _
     "</m:ConvertId>"
    doSoapRequest(strXML)
    Dim strEwsID As String = getXMLNodeXPath2("//m:AlternateId/@Id")
    strXML = _
     "<m:GetItem>" & _
     "<m:ItemShape>" & _
     "<t:BaseShape>Default</t:BaseShape>" & _
     "</m:ItemShape>" & _
     "<m:ItemIds>" & _
     "<t:ItemId Id=""" & strEwsId & """/>" & _
     "</m:ItemIds>" & _
     "</m:GetItem>"
    doSoapRequest(strXML)
    Dim strBody = getXMLNodeXPath2("//t:Body")
    Dim objLinks As System.Text.RegularExpressions.MatchCollection
    objLinks = Regex.Matches(strBody, "<a.*?href=""(.*?)"".*?>(.*?)</a>")
    For Each objLink As System.Text.RegularExpressions.Match In objLinks
      Dim strURL As String = objLink.Groups(1).Value
      If strURL.ToLower.StartsWith("javascript:") Then Continue For
      Response.Write("Link caption: " & objLink.Groups(2).Value & "<br>")
      Response.Write("Link target: <a href=""" & strURL & """>" & strURL & "</a>" & "<br><hr>")
    Next
    Response.Write("<strong>Here is the message text with the above links in original context. ")
    Response.Write("You should only click on a link below if you are completely sure of its destination.</strong><hr>")
    Response.Write(strBody)
  End If
End If
%>

<script language="VB" runat= "server">

Dim objWinHTTP, objXMLDOM As Object
Dim strEWSURL As String = "https://localhost/ews/"
Dim strLogonUser, strPassword As String

Function doSOAPRequest(inS As String) As String

  Dim s As String = _
   "<?xml version=""1.0"" encoding=""utf-8""?>" & _
   "<soap:Envelope" & _
   " xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/""" & _
   " xmlns:t=""http://schemas.microsoft.com/exchange/services/2006/types""" & _
   " xmlns:m=""http://schemas.microsoft.com/exchange/services/2006/messages""" & _
   ">" & _
   "<soap:Header><t:RequestServerVersion Version=""Exchange2010""/></soap:Header>" & _
   "<soap:Body>" & _
   inS & _
   "</soap:Body>" & _
   "</soap:Envelope>"
  doWinHTTPPost(strEWSURL & "Exchange.asmx", s, "Content-type,text/xml")

  Dim s2 As String = objWinHTTP.ResponseText

  objXMLDOM.LoadXML(objWinHTTP.ResponseText)
  objXMLDOM.SetProperty("SelectionLanguage", "XPath")
  objXMLDOM.SetProperty("SelectionNamespaces", "xmlns:m=""http://schemas.microsoft.com/exchange/services/2006/messages"" xmlns:t=""http://schemas.microsoft.com/exchange/services/2006/types""")
  doSOAPRequest = objWinHTTP.ResponseText

  If getXMLNodeXPath2("//m:ResponseCode") <> "NoError" Then
    Response.Write("EWS Error<br>")
    Response.Write("Request:<br>")
    Response.Write(Server.HTMLEncode(s) & "<br>")
    Response.Write("Response:<br>")
    Response.Write(Server.HTMLEncode(s2) & "<br>")
    Response.End
  End If

End Function

Function doWinHTTPPost(inURL As String, inData As String, inHeaders As String) As String
  objWinHTTP.Open("POST", inURL, False)
  If inHeaders <> "" Then
    Dim arrT As String() = Split(inHeaders, "#")
    Dim i As Integer
    For i = LBound(arrT) To UBound(arrT)
      Dim s As String = arrT(i)
      Dim arrT2() As String = Split(s, ",")
      If UBound(arrT2) = 1 Then objWinHTTP.SetRequestHeader(arrT2(0), arrT2(1))
    Next
  End If
  doWinHTTPPost = doWinHTTPSend(inData)
End Function

Function doWinHTTPSend(ByRef inData As String) As String
  If strPassword <> "" Then objWinHTTP.SetCredentials(strLogonUser, strPassword, 0)
  objWinHTTP.Send(inData)
  doWinHTTPSend = objWinHTTP.Status
End Function

Function getXMLNodeXPath2(inNode As String) As String
  Dim s As String = ""
  Dim objNode As Object = objXMLDOM.SelectSingleNode(inNode)
  If Not IsNothing(objNode) Then
    s = objNode.Text
    objNode = Nothing
  End If
  getXMLNodeXPath2 = s
End Function

</script>

Save the file back. Next time you click on an OWA blocked link, although it will not actually take you to the destination, it will now at least show the real URLs so that you can try again.

If you think this is too dangerous, it would be a simple matter to change this code so that it only reveals URLs for certain protocols; or only works for certain AD groups. But I’m not going to go that far yet, because I don’t even know if anyone will ever even read this, let alone try it :)


5 Responses to Reveal Blocked Message URLs In Outlook Web Access 2010

  1. Anonymous says:

    After 15 IT calls and a 30 minute wait for Microsoft (I hung up). I have a solution for what happen with me. I am in the military and I had an AKO email account and they merged my AKO and my enterprise (webmail) account. Now it acts like it is a forward email and will block the hyperlink. What I did to fix this is I went into all my websites that I had my AKO email address. For example Toyota truck payment I changed my email from my AKO email to my enterprise email and that fixed it. I was able to click on the links that I received from Toyota after that and all my other sites that I changed. I hope this helped?

  2. Kevin says:

    After 15 IT calls and a 30 minute wait for Microsoft (I hung up). I have a solution for what happen with me. I am in the military and I had an AKO email account and they merged my AKO and my enterprise (webmail) account. Now it acts like it is a forward email and will block the hyperlink. What I did to fix this is I went into all my websites that I had my AKO email address. For example Toyota truck payment I changed my email from my AKO email to my enterprise email and that fixed it. I was able to click on the links that I received from Toyota after that and all my other sites that I changed. I hope this helped?

  3. Kallie says:

    I am looking to use this modification for a url type that is blocked by OWA. however, i am interested in creating this only for a specific protocol. you had mentioned that you know how to do this and i’m hoping you can provide instruction?

    • admin says:

      The bit that creates the links is this

      Response.Write(“Link caption: ” & objLink.Groups(2).Value & “
      “)
      Response.Write(“Link target: ” & strURL & “” & “


      “)

      So, you can wrap a condition around that. If you only wanted to show urls for (for example) the ftp: protocol (I don’t know why you would, but it helps the example, you would do this:

      If strURL.ToLower.StartsWith(“ftp:”) Then
      Response.Write(“Link caption: ” & objLink.Groups(2).Value & “
      “)
      Response.Write(“Link target: ” & strURL & “” & “


      “)
      End If

    • admin says:

      Well, the WordPress editor made a mess of that. I hope you can work it out. If not, let me know.




Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>