Reviewed by Darin.
<rdar://problem/
3888931> frame naming allows malicious site to bring up a window when you click on a link in another
Added opener bridge method to help WebKit implement security check
for named frame visibility.
* khtml/khtml_part.h:
* kwq/WebCoreBridge.h:
* kwq/WebCoreBridge.mm:
(-[WebCoreBridge opener]):
WebKit:
Reviewed by Darin.
<rdar://problem/
3888931> frame naming allows malicious site to bring up a window when you click on a link in another
Implement a security check on name frame visbility. This is the
same rule as mozilla. You can only target frames by name if you
are in the same window, have the same domain as the frame or an
ancestor, or if it's a top level window have the same domain as
the opener.
* WebView.subproj/WebFrame.m:
(-[WebFrame _shouldAllowAccessFrom:]):
(-[WebFrame _descendantFrameNamed:sourceFrame:]):
(-[WebFrame findFrameNamed:]):
* WebView.subproj/WebFramePrivate.h:
* WebView.subproj/WebView.m:
(-[WebView _findFrameInThisWindowNamed:sourceFrame:]):
(-[WebView _findFrameNamed:sourceFrame:]):
* WebView.subproj/WebViewPrivate.h:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@8286
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2004-12-21 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Darin.
+
+ <rdar://problem/3888931> frame naming allows malicious site to bring up a window when you click on a link in another
+
+ Added opener bridge method to help WebKit implement security check
+ for named frame visibility.
+
+ * khtml/khtml_part.h:
+ * kwq/WebCoreBridge.h:
+ * kwq/WebCoreBridge.mm:
+ (-[WebCoreBridge opener]):
+
2005-01-03 Ken Kocienda <kocienda@apple.com>
Reviewed by John
return Value(val);
}
+ // Check for child frames by name before built-in properties to
+ // match behavior of other browsers.
+ KHTMLPart *childFrame = m_part->childFrameNamed(p.ustring().qstring());
+ if (childFrame)
+ return retrieve(childFrame);
+
const HashEntry* entry = Lookup::findEntry(&WindowTable, p);
if (entry)
{
return res;
}
+KHTMLPart *KHTMLPart::childFrameNamed(const QString &name) const
+{
+ FrameList::Iterator it = d->m_frames.find(name);
+ if (it != d->m_frames.end())
+ return static_cast<KHTMLPart *>(&*(*it).m_part);
+ return NULL;
+}
+
+
#if !APPLE_CHANGES
bool KHTMLPart::openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs )
QPtrList<KParts::ReadOnlyPart> frames() const;
+ KHTMLPart *childFrameNamed(const QString &name) const;
+
/**
* Finds a frame by name. Returns 0L if frame can't be found.
*/
KJSProxy *jScript();
+#if APPLE_CHANGES
+ public:
+#endif
KHTMLPart *opener();
+#if APPLE_CHANGES
+ private:
+#endif
long cacheId() const;
void setOpener(KHTMLPart *_opener);
bool openedByJS();
- (NSURL *)URL;
- (NSString *)referrer;
- (NSString *)domain;
+- (WebCoreBridge *)opener;
- (void)installInFrame:(NSView *)view;
- (void)removeFromFrame;
return nil;
}
+- (WebCoreBridge *)opener
+{
+ KHTMLPart *openerPart = _part->opener();
+
+ if (openerPart)
+ return KWQ(openerPart)->bridge();
+
+ return nil;
+}
+
+ (NSString *)stringWithData:(NSData *)data textEncoding:(CFStringEncoding)textEncoding
{
if (textEncoding == kCFStringEncodingInvalidId || textEncoding == kCFStringEncodingISOLatin1) {
+2004-12-21 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Darin.
+
+ <rdar://problem/3888931> frame naming allows malicious site to bring up a window when you click on a link in another
+
+ Implement a security check on name frame visbility. This is the
+ same rule as mozilla. You can only target frames by name if you
+ are in the same window, have the same domain as the frame or an
+ ancestor, or if it's a top level window have the same domain as
+ the opener.
+
+ * WebView.subproj/WebFrame.m:
+ (-[WebFrame _shouldAllowAccessFrom:]):
+ (-[WebFrame _descendantFrameNamed:sourceFrame:]):
+ (-[WebFrame findFrameNamed:]):
+ * WebView.subproj/WebFramePrivate.h:
+ * WebView.subproj/WebView.m:
+ (-[WebView _findFrameInThisWindowNamed:sourceFrame:]):
+ (-[WebView _findFrameNamed:sourceFrame:]):
+ * WebView.subproj/WebViewPrivate.h:
+
=== Safari-177 ===
=== Safari-176 ===
return [_private->bridge isFrameSet];
}
-- (WebFrame *)_descendantFrameNamed:(NSString *)name
+- (BOOL)_shouldAllowAccessFrom:(WebFrame *)source
{
- if ([[self name] isEqualToString: name]){
+ // if no source frame, allow access
+ if (source == nil) {
+ return YES;
+ }
+
+ // - allow access if the two frames are in the same window
+ if ([self webView] == [source webView]) {
+ return YES;
+ }
+
+ // - allow if the request is made from a local file.
+ NSString *sourceDomain = [[source _bridge] domain];
+ if ([sourceDomain length] == 0) {
+ return YES;
+ }
+
+ // - allow access if this frame or one of its ancestors
+ // has the same origin as source
+ WebFrame *ancestor = self;
+ while (ancestor != nil) {
+ NSString *ancestorDomain = [[ancestor _bridge] domain];
+ if (ancestorDomain != nil && [sourceDomain _web_isCaseInsensitiveEqualToString:ancestorDomain]) {
+ return YES;
+ }
+ ancestor = [ancestor parentFrame];
+ }
+
+ // - allow access if this frame is a toplevel window and the source
+ // can access its opener. Note that we only allow one level of
+ // recursion here.
+ if ([self parentFrame] == nil) {
+ NSString *openerDomain = [[[self _bridge] opener] domain];
+ if (openerDomain != nil && [sourceDomain _web_isCaseInsensitiveEqualToString:openerDomain]) {
+ return YES;
+ }
+ }
+
+ // otherwise deny access
+ return NO;
+}
+
+
+- (WebFrame *)_descendantFrameNamed:(NSString *)name sourceFrame:(WebFrame *)source
+{
+ // for security reasons, we do not want to even make frames visible to frames that
+ // can't access them
+ if ([[self name] isEqualToString: name] && [self _shouldAllowAccessFrom:source]) {
return self;
}
for (i = 0; i < [children count]; i++){
frame = [children objectAtIndex: i];
- frame = [frame _descendantFrameNamed:name];
+ frame = [frame _descendantFrameNamed:name sourceFrame:source];
if (frame){
return frame;
}
}
// Search from this frame down.
- WebFrame *frame = [self _descendantFrameNamed:name];
+ WebFrame *frame = [self _descendantFrameNamed:name sourceFrame:self];
if (!frame) {
// Search in this WebView then in others.
- frame = [[self webView] _findFrameNamed:name];
+ frame = [[self webView] _findFrameNamed:name sourceFrame:self];
}
return frame;
- (void)_setWebView:(WebView *)webView;
- (void)_setName:(NSString *)name;
-- (WebFrame *)_descendantFrameNamed:(NSString *)name;
+- (WebFrame *)_descendantFrameNamed:(NSString *)name sourceFrame:(WebFrame *)source;
- (void)_detachFromParent;
- (void)_closeOldDataSources;
- (void)_setDataSource:(WebDataSource *)d;
[[self mainFrame] _setName:name];
}
-- (WebFrame *)_findFrameInThisWindowNamed: (NSString *)name
+- (WebFrame *)_findFrameInThisWindowNamed:(NSString *)name sourceFrame:(WebFrame *)source
{
- return [[self mainFrame] _descendantFrameNamed:name];
+ return [[self mainFrame] _descendantFrameNamed:name sourceFrame:(WebFrame *)source];
}
-- (WebFrame *)_findFrameNamed:(NSString *)name
+- (WebFrame *)_findFrameNamed:(NSString *)name sourceFrame:(WebFrame *)source
{
// Try this WebView first.
- WebFrame *frame = [self _findFrameInThisWindowNamed:name];
+ WebFrame *frame = [self _findFrameInThisWindowNamed:name sourceFrame:source];
if (frame != nil) {
return frame;
NSEnumerator *enumerator = [WebViewSets webViewsInSetNamed:_private->setName];
WebView *webView;
while ((webView = [enumerator nextObject]) != nil && frame == nil) {
- frame = [webView _findFrameInThisWindowNamed:name];
+ frame = [webView _findFrameInThisWindowNamed:name sourceFrame:source];
}
}
/*
- WebViewPrivate.m
- Copyright 2001, Apple, Inc. All rights reserved.
+ WebViewPrivate.h
+ Copyright 2001 Apple, Inc. All rights reserved.
*/
#import <WebKit/WebView.h>
- (void)setDefersCallbacks:(BOOL)defers;
- (void)_setTopLevelFrameName:(NSString *)name;
-- (WebFrame *)_findFrameInThisWindowNamed: (NSString *)name;
-- (WebFrame *)_findFrameNamed: (NSString *)name;
+- (WebFrame *)_findFrameInThisWindowNamed:(NSString *)name sourceFrame:(WebFrame *)source;
+- (WebFrame *)_findFrameNamed:(NSString *)name sourceFrame:(WebFrame *)source;
- (WebView *)_openNewWindowWithRequest:(NSURLRequest *)request;