1/*
2 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3 * Copyright (C) 2004-2011, 2013, 2016 Apple Inc. All rights reserved.
4 * Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
5 * Copyright (C) 2013 Michael Pruett <michael@68k.org>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include "config.h"
23#include "JSDOMBindingSecurity.h"
24
25#include "DOMWindow.h"
26#include "Document.h"
27#include "Frame.h"
28#include "HTTPParsers.h"
29#include "JSDOMExceptionHandling.h"
30#include "JSDOMWindowBase.h"
31#include "SecurityOrigin.h"
32#include <wtf/text/WTFString.h>
33
34
35namespace WebCore {
36using namespace JSC;
37
38void printErrorMessageForFrame(Frame* frame, const String& message)
39{
40 if (!frame)
41 return;
42 frame->document()->domWindow()->printErrorMessage(message);
43}
44
45static inline bool canAccessDocument(JSC::ExecState* state, Document* targetDocument, SecurityReportingOption reportingOption)
46{
47 VM& vm = state->vm();
48 auto scope = DECLARE_THROW_SCOPE(vm);
49
50 if (!targetDocument)
51 return false;
52
53 DOMWindow& active = activeDOMWindow(*state);
54
55 if (active.document()->securityOrigin().canAccess(targetDocument->securityOrigin()))
56 return true;
57
58 switch (reportingOption) {
59 case ThrowSecurityError:
60 throwSecurityError(*state, scope, targetDocument->domWindow()->crossDomainAccessErrorMessage(active, IncludeTargetOrigin::No));
61 break;
62 case LogSecurityError:
63 printErrorMessageForFrame(targetDocument->frame(), targetDocument->domWindow()->crossDomainAccessErrorMessage(active, IncludeTargetOrigin::Yes));
64 break;
65 case DoNotReportSecurityError:
66 break;
67 }
68
69 return false;
70}
71
72bool BindingSecurity::shouldAllowAccessToFrame(ExecState& state, Frame& frame, String& message)
73{
74 if (BindingSecurity::shouldAllowAccessToFrame(&state, &frame, DoNotReportSecurityError))
75 return true;
76 message = frame.document()->domWindow()->crossDomainAccessErrorMessage(activeDOMWindow(state), IncludeTargetOrigin::No);
77 return false;
78}
79
80bool BindingSecurity::shouldAllowAccessToDOMWindow(ExecState& state, DOMWindow* globalObject, String& message)
81{
82 return globalObject && shouldAllowAccessToDOMWindow(state, *globalObject, message);
83}
84
85bool BindingSecurity::shouldAllowAccessToDOMWindow(ExecState& state, DOMWindow& globalObject, String& message)
86{
87 if (BindingSecurity::shouldAllowAccessToDOMWindow(&state, globalObject, DoNotReportSecurityError))
88 return true;
89 message = globalObject.crossDomainAccessErrorMessage(activeDOMWindow(state), IncludeTargetOrigin::No);
90 return false;
91}
92
93bool BindingSecurity::shouldAllowAccessToDOMWindow(JSC::ExecState* state, DOMWindow& target, SecurityReportingOption reportingOption)
94{
95 return canAccessDocument(state, target.document(), reportingOption);
96}
97
98bool BindingSecurity::shouldAllowAccessToDOMWindow(JSC::ExecState* state, DOMWindow* target, SecurityReportingOption reportingOption)
99{
100 return target && shouldAllowAccessToDOMWindow(state, *target, reportingOption);
101}
102
103bool BindingSecurity::shouldAllowAccessToFrame(JSC::ExecState* state, Frame* target, SecurityReportingOption reportingOption)
104{
105 return target && canAccessDocument(state, target->document(), reportingOption);
106}
107
108bool BindingSecurity::shouldAllowAccessToNode(JSC::ExecState& state, Node* target)
109{
110 return !target || canAccessDocument(&state, &target->document(), LogSecurityError);
111}
112
113} // namespace WebCore
114