4

Can I access session cookies marked as HttpOnly via IHTMLDocument2::cookie inside ActiveX running in Internet Explorer 11? Here is the code example that comes from the answer to this question:

CComPtr<IHTMLDocument2> pDoc // get document from event as shown in the sample.

// read the cookie
CComBSTR cookie;
hr = pDoc->get_cookie(&cookie);

If this is non possible via IHTMLDocument2 are there any other way to access all cookies for the website open in IE inside ActiveX?

IT Hit WebDAV
  • 5,652
  • 12
  • 61
  • 98
  • So you have tested the code and it doesn't get you the HTTP only cookies or you have not yet tested? – Tarun Lalwani May 13 '18 at 15:33
  • https://www.codeproject.com/Articles/38616/Retrieve-HttpOnly-Session-Cookie-in-WebBrowser - go through this article. This may work on lower version of browsers. – Brijesh May 20 '18 at 05:19
  • I think this should help you out https://stackoverflow.com/questions/38726408/retrieve-all-cookies-from-internet-explorer – Tarun Lalwani May 20 '18 at 06:12

1 Answers1

1

The cookies can't be read using the document object. So you need to read cookies outside the context of the browser as such. There is a SO thread which explains how to do the same

Retrieve ALL cookies from Internet Explorer

Below is the VBA code for reference from the answer

Option Explicit

Sub GetIECookies()

    Dim sCookiesPath As String
    Dim oCookies As Object
    Dim oFSO As Object
    Dim oFolder As Object
    Dim oFile
    Dim sContent As String
    Dim a() As String
    Dim i As Long
    Dim aItems
    Dim aCookies()

    ' read IE cookie files
    sCookiesPath = CreateObject("shell.application").Namespace("shell:Cookies").self.Path
    Set oCookies = CreateObject("Scripting.Dictionary")
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Set oFolder = oFSO.GetFolder(sCookiesPath)
    For Each oFile In oFolder.Files
        If LCase(oFSO.GetExtensionName(oFile.Name)) = "txt" Then
            With oFile.OpenAsTextStream(1, 0) ' read-only, ascii
                sContent = .ReadAll
                .Close
            End With
            sContent = Replace(sContent, vbCr, "")
            ' split cookies within file
            a = Split(sContent, vbLf & "*" & vbLf)
            For i = 0 To UBound(a) - 1
                oCookies.Add oCookies.Count, a(i)
            Next
        End If
    Next
    ' parse data, repack to 2d array
    aItems = oCookies.Items()
    If UBound(aItems) = -1 Then
        MsgBox "No cookies found"
    Else
        ReDim aCookies(1 To UBound(aItems) + 1, 1 To 6)
        For i = 1 To UBound(aItems) + 1
            a = Split(aItems(i - 1), vbLf)
            aCookies(i, 1) = a(0)
            aCookies(i, 2) = a(1)
            aCookies(i, 3) = a(2)
            aCookies(i, 4) = GetInetCookieFlags(a(3))
            aCookies(i, 5) = ConvDT(a(4), a(5))
            aCookies(i, 6) = ConvDT(a(6), a(7))
        Next
        ' output
        With ThisWorkbook.Sheets(1)
            .Cells.Delete
            .Range("A1:F1") = Array("Name", "Value", "Host/Path", "Flags", "Expiration", "Created")
            Output .Range("A2"), aCookies
        End With
    End If

End Sub

Function ConvDT(sLowNTFmt As String, sHighNTFmt As String) As Date

    Dim dNTFmt As Double
    Dim dUnixFmt As Double

    ' FILETIME format is the number of 100 nanosecond ticks since 00:00 1 Jan, 1601 (UTC).
    dNTFmt = sHighNTFmt * 4294967296# + sLowNTFmt
    ' Unix time format is the number of seconds since 00:00 1 Jan 1970
    dUnixFmt = 0.0000001 * dNTFmt - 11644473600#
    ' VB time format is the number of days since 00:00 1 Jan 1900
    ConvDT = CDate(dUnixFmt / 86400 + 25569)

End Function

Function GetInetCookieFlags(sFlags As String) As String

    Dim lFlags As Long
    Dim aFlag

    ' reset bit 32 to avoid overflow
    If sFlags >= 2147483648# Then lFlags = CLng(sFlags - 2147483648#) Else lFlags = CLng(sFlags)
    ' convert flags bits to string representation
    With CreateObject("Scripting.Dictionary")
        For Each aFlag In Array( _
            Array(&H1, "IS SECURE"), _
            Array(&H2, "IS SESSION"), _
            Array(&H10, "THIRD PARTY"), _
            Array(&H20, "PROMPT REQUIRED"), _
            Array(&H40, "EVALUATE P3P"), _
            Array(&H80, "APPLY P3P"), _
            Array(&H100, "P3P ENABLED"), _
            Array(&H200, "IS RESTRICTED"), _
            Array(&H400, "IE6"), _
            Array(&H800, "IS LEGACY"), _
            Array(&H1000, "NON SCRIPT"), _
            Array(&H2000, "HTTPONLY"), _
            Array(&H4000, "HOST ONLY"), _
            Array(&H8000, "APPLY HOST ONLY"), _
            Array(&H20000, "RESTRICTED ZONE"), _
            Array(&H20000000, "ALL COOKIES"), _
            Array(&H40000000, "NO CALLBACK"), _
            Array(&H80000000, "ECTX 3RDPARTY") _
        )
            If lFlags And aFlag(0) Then .Add .Count, aFlag(1)
        Next
        GetInetCookieFlags = Join(.Items(), vbCrLf)
    End With

End Function

Sub Output(oDstRng As Range, aCells As Variant)

    With oDstRng
        .Parent.Select
        With .Resize( _
            UBound(aCells, 1) - LBound(aCells, 1) + 1, _
            UBound(aCells, 2) - LBound(aCells, 2) + 1 _
        )
            .NumberFormat = "@"
            .Value = aCells
            .Columns.AutoFit
        End With
    End With

End Sub

Of course you will need to port it to VC++ code if you want to use it there

Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265
  • I guess this code was tested with Windows versions released yer 2017 and earlier. In year 2018 Windows received an update in which cookies storage was redesigned, specifically to avoid storing them in files. There is no way use this approach in latest Windows versions. – IT Hit WebDAV Apr 11 '19 at 01:08