// This is the heuristic which detects the requests issued by Flash.ocx.
// It turned out that the implementation from ''Flash.ocx'' (tested version is 15.0.0.152)
// returns quite minimal configuration in comparison with the implementation from Microsofts'
// libraries (see grfBINDF and bindInfo.dwOptions). The impl from MS often includes something
// else.
bool WBPassthruSink::IsFlashRequest(const wchar_t* const* additionalHeaders)
{
  if (additionalHeaders && *additionalHeaders)
  {
    auto flashVersionHeader = ExtractHttpHeader<std::wstring>(*additionalHeaders, L"x-flash-version:", L"\n");
    if (!TrimString(flashVersionHeader).empty())
    {
      return true;
    }
  }
  ATL::CComPtr<IBindStatusCallback> bscb;
  if (SUCCEEDED(QueryServiceFromClient(&bscb)) && !!bscb)
  {
    DWORD grfBINDF = 0;
    BINDINFO bindInfo = {};
    bindInfo.cbSize = sizeof(bindInfo);
    if (SUCCEEDED(bscb->GetBindInfo(&grfBINDF, &bindInfo)) &&
      (BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE| BINDF_PULLDATA) == grfBINDF &&
      (BINDINFO_OPTIONS_ENABLE_UTF8 | BINDINFO_OPTIONS_USE_IE_ENCODING) == bindInfo.dwOptions
      )
    {
      return true;
    }
  }
  return false;
}
示例#2
0
STDMETHODIMP MonitorSink::BeginningTransaction(
    LPCWSTR szURL,
    LPCWSTR szHeaders,
    DWORD dwReserved,
    LPWSTR *pszAdditionalHeaders)
{
    CComPtr<IHttpNegotiate> spHttpNegotiate;
    QueryServiceFromClient(&spHttpNegotiate);
    HRESULT hr = spHttpNegotiate ?
                 spHttpNegotiate->BeginningTransaction(szURL, szHeaders,
                         dwReserved, pszAdditionalHeaders) : E_UNEXPECTED;

    // BeginningTransaction() is the first function called for this sink object.
    // Record its URL here.
    m_strURL = szURL;

    ExtractReferer(pszAdditionalHeaders);

    // Query the associated CIEHostWindow object for later use.
    QueryIEHostWindow();

    // Abort everything the utils window requests
    if (m_pIEHostWindow && m_pIEHostWindow->IsUtils() && m_bIsSubRequest)
        return E_ABORT;

    if (m_pIEHostWindow && !m_bIsSubRequest)
        m_pIEHostWindow->SetMainPageDone();

    // Append additonal headers, such as DNT
    SetCustomHeaders(pszAdditionalHeaders);

    return hr;
}
STDMETHODIMP WBPassthruSink::OnResponse(DWORD dwResponseCode, LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
{
  if (pszAdditionalRequestHeaders)
  {
    *pszAdditionalRequestHeaders = 0;
  }

  CComPtr<IHttpNegotiate> spHttpNegotiate;
  QueryServiceFromClient(&spHttpNegotiate);

  return spHttpNegotiate ? spHttpNegotiate->OnResponse(dwResponseCode, szResponseHeaders, szRequestHeaders, pszAdditionalRequestHeaders) : S_OK;
}
示例#4
0
void MonitorSink::QueryIEHostWindow()
{
    // Query the IE window that initiated the request
    CComPtr<IWindowForBindingUI> spWindowForBindingUI;
    if ( SUCCEEDED(QueryServiceFromClient(&spWindowForBindingUI)) && spWindowForBindingUI )
    {
        HWND hwndIEServer = NULL;
        if ( SUCCEEDED(spWindowForBindingUI->GetWindow(IID_IHttpSecurity, &hwndIEServer)) && IsWindow(hwndIEServer))
        {
            // Here hwndIEServer could be different handles in different scenarios.
            // When Internet Explorer_Server window is not created yet (when the request is just initiated),
            // hwndIEServer is the handle to the Shell Embedding window; After that it is most likely a handle
            // to the Internet Explorer_Server, and sometimes it could be the Shell DocObject View window as well.

            // Based on the above information, we look for the CIEHostWindow by traversing up in the window
            // hierarchy. For security reasons, we only traverse up for 5 layers of windows.
            m_pIEHostWindow = CIEHostWindow::FromChildWindow(hwndIEServer);
        }
    }

    // Determine whether it's a sub-request by comparing request URL to the page URL
    m_bIsSubRequest = !(m_pIEHostWindow && FuzzyUrlCompare(m_pIEHostWindow->GetLoadingURL(), m_strURL));
}
STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR* pszAdditionalHeaders)
{
  if (!szURL)
  {
    return E_POINTER;
  }
  std::wstring src = szURL;
  UnescapeUrl(src);
  DEBUG_GENERAL(src);

  std::string acceptHeader = ExtractHttpAcceptHeader(m_spTargetProtocol);

  if (pszAdditionalHeaders)
  {
    *pszAdditionalHeaders = nullptr;
  }

  CComPtr<IHttpNegotiate> httpNegotiate;
  QueryServiceFromClient(&httpNegotiate);
  // This fills the pszAdditionalHeaders with more headers. One of which is the Referer header, which we need.
  // There doesn't seem to be any other way to get this header before the request has been made.
  HRESULT nativeHr = httpNegotiate ? httpNegotiate->BeginningTransaction(szURL, szHeaders, dwReserved, pszAdditionalHeaders) : S_OK;

  if (pszAdditionalHeaders && *pszAdditionalHeaders)
  {
    m_boundDomain = ExtractHttpHeader<std::wstring>(*pszAdditionalHeaders, L"Referer:", L"\n");
  }
  m_boundDomain = TrimString(m_boundDomain);
  m_contentType = GetContentType(ATL::CString(acceptHeader.c_str()), m_boundDomain, src);

  CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId());
  CPluginClient* client = CPluginClient::GetInstance();

  if (tab && client)
  {
    std::wstring documentUrl = tab->GetDocumentUrl();
    // Page is identical to document => don't block
    if (documentUrl == src)
    {
      return nativeHr;
    }
    else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhitelistedUrl(documentUrl))
    {
      if (tab->IsFrameCached(src))
      {
        m_contentType = ContentType::CONTENT_TYPE_SUBDOCUMENT;
      }
    }
  }

  if (IsFlashRequest(pszAdditionalHeaders))
  {
    m_contentType = ContentType::CONTENT_TYPE_OBJECT_SUBREQUEST;
  }

  if (pszAdditionalHeaders && *pszAdditionalHeaders && IsXmlHttpRequest(*pszAdditionalHeaders))
  {
    m_contentType = ContentType::CONTENT_TYPE_XMLHTTPREQUEST;
  }

  if (client->ShouldBlock(szURL, m_contentType, m_boundDomain, /*debug flag but must be set*/true))
  {
    // NOTE: Feeding custom HTML to Flash, instead of original object subrequest
    // doesn't have much sense. It also can manifest in unwanted result
    // like video being blocked (See https://issues.adblockplus.org/ticket/1669)
    // So we report blocked object subrequests as failed, not just empty HTML.
    m_isCustomResponse = m_contentType != ContentType::CONTENT_TYPE_OBJECT_SUBREQUEST;
    return E_ABORT;
  }
  return nativeHr;
}
示例#6
0
STDMETHODIMP MonitorSink::OnResponse(
    DWORD dwResponseCode,
    LPCWSTR szResponseHeaders,
    LPCWSTR szRequestHeaders,
    LPWSTR *pszAdditionalRequestHeaders)
{
    if (pszAdditionalRequestHeaders)
        *pszAdditionalRequestHeaders = NULL;

    CComPtr<IHttpNegotiate> spHttpNegotiate;
    QueryServiceFromClient(&spHttpNegotiate);

    HRESULT hr = spHttpNegotiate ?
                 spHttpNegotiate->OnResponse(dwResponseCode, szResponseHeaders,
                         szRequestHeaders, pszAdditionalRequestHeaders) :
                 S_OK;

    if ((dwResponseCode >= 200 ) && (dwResponseCode < 300))
    {
        bool bExportCookies = PrefManager::instance().isCookieSyncEnabled();

        if (abp::AdBlockPlus::isEnabled())
        {
            static const WCHAR CONTENT_TYPE_HEAD [] = L"Content-Type:";
            LPWSTR pContentType = NULL;
            size_t nLen = 0;
            if (Utils::HTTP::ExtractFieldValue(szResponseHeaders, CONTENT_TYPE_HEAD, &pContentType, &nLen))
            {
                ContentType_T aContentType = ScanContentType(pContentType);

                if (pContentType) Utils::HTTP::FreeFieldValue(pContentType);

                if ((ContentType::TYPE_DOCUMENT == aContentType) && m_bIsSubRequest)
                    aContentType = ContentType::TYPE_SUBDOCUMENT;

                // Check sub-requests only. The main page is always allowed to be loaded.
                if (m_bIsSubRequest && !CanLoadContent(aContentType))
                {
                    // No need to export cookies if it's blocked
                    bExportCookies = false;

                    switch (aContentType)
                    {
                    case ContentType::TYPE_IMAGE:
                    {
                        pTargetBuffer = TRANSPARENT_GIF_1x1;
                        dwTargetBufSize = TRANSPARENT_GIF_1x1_LENGTH;

                        break;
                    }
                    case ContentType::TYPE_DOCUMENT:
                    case ContentType::TYPE_SUBDOCUMENT:
                    {
                        pTargetBuffer = BLANK_HTML;
                        dwTargetBufSize = BLANK_HTML_LENGTH;

                        break;
                    }
                    case ContentType::TYPE_SCRIPT:
                    case ContentType::TYPE_STYLESHEET:
                    default:
                    {
                        pTargetBuffer = EMPTY_FILE;
                        dwTargetBufSize = EMPTY_FILE_LENGTH;
                        break;
                    }
                        //{
                        //	// For other types of content, abort immediately
                        //	hr = E_ABORT;
                        //}
                    }

                    if (m_spInternetProtocolSink) m_spInternetProtocolSink->ReportData(BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE, 0, 0);
                    if (m_spInternetProtocolSink) m_spInternetProtocolSink->ReportResult(S_OK, S_OK, NULL);
                }
            }
        }

        if (bExportCookies)
            ExportCookies(szResponseHeaders);
    }

    return hr;
}