1926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/*
2926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2013 Google, Inc. All Rights Reserved.
3926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *
4926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
5926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * modification, are permitted provided that the following conditions
6926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * are met:
7926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
8926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
9926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
10926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
11926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *    documentation and/or other materials provided with the distribution.
12926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *
13926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */
25926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
26926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#include "config.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/parser/XSSAuditorDelegate.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
30bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "core/frame/Frame.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/DocumentLoader.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/FrameLoader.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/FrameLoaderClient.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/PingLoader.h"
351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/JSONValues.h"
36bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/network/FormData.h"
3751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/weborigin/SecurityOrigin.h"
38591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/text/StringBuilder.h"
39926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
40926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)namespace WebCore {
41926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
421e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)String XSSInfo::buildConsoleError() const
43926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
44926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    StringBuilder message;
45926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    message.append("The XSS Auditor ");
461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    message.append(m_didBlockEntirePage ? "blocked access to" : "refused to execute a script in");
47926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    message.append(" '");
481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    message.append(m_originalURL);
49926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    message.append("' because ");
501e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    message.append(m_didBlockEntirePage ? "the source code of a script" : "its source code");
51926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    message.append(" was found within the request.");
52926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (m_didSendCSPHeader)
54926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        message.append(" The server sent a 'Content-Security-Policy' header requesting this behavior.");
551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    else if (m_didSendXSSProtectionHeader)
56926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        message.append(" The server sent an 'X-XSS-Protection' header requesting this behavior.");
57926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    else
58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        message.append(" The auditor was enabled as the server sent neither an 'X-XSS-Protection' nor 'Content-Security-Policy' header.");
59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
60926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return message.toString();
61926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)bool XSSInfo::isSafeToSendToAnotherThread() const
641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return m_originalURL.isSafeToSendToAnotherThread();
661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)XSSAuditorDelegate::XSSAuditorDelegate(Document* document)
691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    : m_document(document)
701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    , m_didSendNotifications(false)
711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(isMainThread());
731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(m_document);
741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
761e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)PassRefPtr<FormData> XSSAuditorDelegate::generateViolationReport(const XSSInfo& xssInfo)
77926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSERT(isMainThread());
79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
80f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    FrameLoader& frameLoader = m_document->frame()->loader();
81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    String httpBody;
82f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    if (frameLoader.documentLoader()) {
83f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        if (FormData* formData = frameLoader.documentLoader()->originalRequest().httpBody())
84926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            httpBody = formData->flattenToString();
85926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
87591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    RefPtr<JSONObject> reportDetails = JSONObject::create();
881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    reportDetails->setString("request-url", xssInfo.m_originalURL);
89926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    reportDetails->setString("request-body", httpBody);
90926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
91591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    RefPtr<JSONObject> reportObject = JSONObject::create();
92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    reportObject->setObject("xss-report", reportDetails.release());
93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return FormData::create(reportObject->toJSONString().utf8().data());
95926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
96926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void XSSAuditorDelegate::didBlockScript(const XSSInfo& xssInfo)
98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSERT(isMainThread());
100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    m_document->addConsoleMessage(JSMessageSource, ErrorMessageLevel, xssInfo.buildConsoleError());
102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
10353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // stopAllLoaders can detach the Frame, so protect it.
10453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RefPtr<Frame> protect(m_document->frame());
105f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    FrameLoader& frameLoader = m_document->frame()->loader();
106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (xssInfo.m_didBlockEntirePage)
107f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        frameLoader.stopAllLoaders();
108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!m_didSendNotifications) {
110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_didSendNotifications = true;
111926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
112f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        frameLoader.client()->didDetectXSS(m_document->url(), xssInfo.m_didBlockEntirePage);
113926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
114926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (!m_reportURL.isEmpty())
1151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            PingLoader::sendViolationReport(m_document->frame(), m_reportURL, generateViolationReport(xssInfo), PingLoader::XSSAuditorViolationReport);
116926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
117926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
118926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (xssInfo.m_didBlockEntirePage)
119e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)        m_document->frame()->navigationScheduler().scheduleLocationChange(m_document, SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
120926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
121926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
122926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} // namespace WebCore
123