1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifndef BindingSecurity_h
32 #define BindingSecurity_h
33
34 #include "BindingSecurityBase.h"
35 #include "Element.h"
36 #include "Frame.h"
37 #include "GenericBinding.h"
38 #include "HTMLFrameElementBase.h"
39 #include "HTMLNames.h"
40 #include "HTMLParserIdioms.h"
41 #include "Settings.h"
42
43 namespace WebCore {
44
45 class DOMWindow;
46 class Node;
47
48 // Security functions shared by various language bindings.
49 template <class Binding>
50 class BindingSecurity : public BindingSecurityBase {
51 public:
52 // Check if the active execution context can access the target frame.
53 static bool canAccessFrame(State<Binding>*, Frame*, bool reportError);
54
55 // Check if it is safe to access the given node from the
56 // current security context.
57 static bool checkNodeSecurity(State<Binding>*, Node* target);
58
59 static bool allowPopUp(State<Binding>*);
60 static bool allowSettingFrameSrcToJavascriptUrl(State<Binding>*, HTMLFrameElementBase*, String value);
61 static bool allowSettingSrcToJavascriptURL(State<Binding>*, Element*, String name, String value);
62
63 static bool shouldAllowNavigation(State<Binding>*, Frame*);
64
65 private:
BindingSecurity()66 explicit BindingSecurity() {}
67 ~BindingSecurity();
68
69 // Check if the current DOMWindow's security context can access the target
70 // DOMWindow. This function does not report errors, so most callers should
71 // use canAccessFrame instead.
72 static bool canAccessWindow(State<Binding>*, DOMWindow* target);
73 };
74
75 // Implementations of templated methods must be in this file.
76
77 template <class Binding>
canAccessWindow(State<Binding> * state,DOMWindow * targetWindow)78 bool BindingSecurity<Binding>::canAccessWindow(State<Binding>* state,
79 DOMWindow* targetWindow)
80 {
81 DOMWindow* activeWindow = state->activeWindow();
82 return canAccess(activeWindow, targetWindow);
83 }
84
85 template <class Binding>
canAccessFrame(State<Binding> * state,Frame * target,bool reportError)86 bool BindingSecurity<Binding>::canAccessFrame(State<Binding>* state,
87 Frame* target,
88 bool reportError)
89 {
90 // The subject is detached from a frame, deny accesses.
91 if (!target)
92 return false;
93
94 if (!canAccessWindow(state, getDOMWindow(target))) {
95 if (reportError)
96 state->immediatelyReportUnsafeAccessTo(target);
97 return false;
98 }
99 return true;
100 }
101
102 template <class Binding>
checkNodeSecurity(State<Binding> * state,Node * node)103 bool BindingSecurity<Binding>::checkNodeSecurity(State<Binding>* state, Node* node)
104 {
105 if (!node)
106 return false;
107
108 Frame* target = getFrame(node);
109
110 if (!target)
111 return false;
112
113 return canAccessFrame(state, target, true);
114 }
115
116 template <class Binding>
allowPopUp(State<Binding> * state)117 bool BindingSecurity<Binding>::allowPopUp(State<Binding>* state)
118 {
119 if (state->processingUserGesture())
120 return true;
121
122 Frame* frame = state->firstFrame();
123 ASSERT(frame);
124 Settings* settings = frame->settings();
125 return settings && settings->javaScriptCanOpenWindowsAutomatically();
126 }
127
128 template <class Binding>
allowSettingFrameSrcToJavascriptUrl(State<Binding> * state,HTMLFrameElementBase * frame,String value)129 bool BindingSecurity<Binding>::allowSettingFrameSrcToJavascriptUrl(State<Binding>* state, HTMLFrameElementBase* frame, String value)
130 {
131 if (protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(value))) {
132 Node* contentDoc = frame->contentDocument();
133 if (contentDoc && !checkNodeSecurity(state, contentDoc))
134 return false;
135 }
136 return true;
137 }
138
139 template <class Binding>
allowSettingSrcToJavascriptURL(State<Binding> * state,Element * element,String name,String value)140 bool BindingSecurity<Binding>::allowSettingSrcToJavascriptURL(State<Binding>* state, Element* element, String name, String value)
141 {
142 if ((element->hasTagName(HTMLNames::iframeTag) || element->hasTagName(HTMLNames::frameTag)) && equalIgnoringCase(name, "src"))
143 return allowSettingFrameSrcToJavascriptUrl(state, static_cast<HTMLFrameElementBase*>(element), value);
144 return true;
145 }
146
147 template <class Binding>
shouldAllowNavigation(State<Binding> * state,Frame * frame)148 bool BindingSecurity<Binding>::shouldAllowNavigation(State<Binding>* state, Frame* frame)
149 {
150 Frame* activeFrame = state->activeFrame();
151 return activeFrame && activeFrame->loader()->shouldAllowNavigation(frame);
152 }
153
154 }
155
156 #endif // BindingSecurity_h
157