mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 07:32:44 +00:00 
			
		
		
		
	LibWeb: Disallow cross-origin access to <iframe>.contentDocument
With this patch, we now enforce basic same-origin policy for this one
<iframe> attribute.
To make it easier to add more attributes like this, I've added an
extended IDL attribute ("[ReturnNullIfCrossOrigin]") that does exactly
what it sounds like. :^)
			
			
This commit is contained in:
		
							parent
							
								
									4c1f317572
								
							
						
					
					
						commit
						37c287b1d4
					
				
					 4 changed files with 28 additions and 4 deletions
				
			
		|  | @ -445,8 +445,9 @@ void generate_implementation(const IDL::Interface& interface) | |||
|     out() << "#include <LibWeb/Bindings/NodeWrapperFactory.h>"; | ||||
|     out() << "#include <LibWeb/Bindings/" << wrapper_class << ".h>"; | ||||
|     out() << "#include <LibWeb/DOM/Element.h>"; | ||||
|     out() << "#include <LibWeb/HTML/HTMLElement.h>"; | ||||
|     out() << "#include <LibWeb/DOM/EventListener.h>"; | ||||
|     out() << "#include <LibWeb/HTML/HTMLElement.h>"; | ||||
|     out() << "#include <LibWeb/Origin.h>"; | ||||
|     out() << "#include <LibWeb/Bindings/CommentWrapper.h>"; | ||||
|     out() << "#include <LibWeb/Bindings/DocumentWrapper.h>"; | ||||
|     out() << "#include <LibWeb/Bindings/DocumentFragmentWrapper.h>"; | ||||
|  | @ -457,6 +458,7 @@ void generate_implementation(const IDL::Interface& interface) | |||
|     out() << "#include <LibWeb/Bindings/ImageDataWrapper.h>"; | ||||
|     out() << "#include <LibWeb/Bindings/TextWrapper.h>"; | ||||
|     out() << "#include <LibWeb/Bindings/CanvasRenderingContext2DWrapper.h>"; | ||||
|     out() << "#include <LibWeb/Bindings/WindowObject.h>"; | ||||
| 
 | ||||
|     // FIXME: This is a total hack until we can figure out the namespace for a given type somehow.
 | ||||
|     out() << "using namespace Web::DOM;"; | ||||
|  | @ -606,6 +608,11 @@ void generate_implementation(const IDL::Interface& interface) | |||
|         out() << "    if (!impl)"; | ||||
|         out() << "        return {};"; | ||||
| 
 | ||||
|         if (attribute.extended_attributes.contains("ReturnNullIfCrossOrigin")) { | ||||
|             out() << "    if (!impl->may_access_from_origin(static_cast<WindowObject&>(global_object).origin()))"; | ||||
|             out() << "        return JS::js_null();"; | ||||
|         } | ||||
| 
 | ||||
|         if (attribute.extended_attributes.contains("Reflect")) { | ||||
|             auto attribute_name = attribute.extended_attributes.get("Reflect").value(); | ||||
|             if (attribute_name.is_null()) | ||||
|  |  | |||
|  | @ -26,17 +26,20 @@ | |||
| 
 | ||||
| #include <LibGUI/Button.h> | ||||
| #include <LibGUI/TextBox.h> | ||||
| #include <LibWeb/Bindings/WindowObject.h> | ||||
| #include <LibWeb/DOM/Document.h> | ||||
| #include <LibWeb/DOM/Event.h> | ||||
| #include <LibWeb/DOM/Window.h> | ||||
| #include <LibWeb/Dump.h> | ||||
| #include <LibWeb/HTML/HTMLFormElement.h> | ||||
| #include <LibWeb/HTML/HTMLIFrameElement.h> | ||||
| #include <LibWeb/HTML/Parser/HTMLDocumentParser.h> | ||||
| #include <LibWeb/InProcessWebView.h> | ||||
| #include <LibWeb/Layout/LayoutFrame.h> | ||||
| #include <LibWeb/Layout/LayoutWidget.h> | ||||
| #include <LibWeb/Loader/ResourceLoader.h> | ||||
| #include <LibWeb/Origin.h> | ||||
| #include <LibWeb/Page/Frame.h> | ||||
| #include <LibWeb/InProcessWebView.h> | ||||
| 
 | ||||
| namespace Web::HTML { | ||||
| 
 | ||||
|  | @ -81,6 +84,18 @@ void HTMLIFrameElement::load_src(const String& value) | |||
|     m_content_frame->loader().load(url, FrameLoader::Type::IFrame); | ||||
| } | ||||
| 
 | ||||
| Origin HTMLIFrameElement::content_origin() const | ||||
| { | ||||
|     if (!m_content_frame || !m_content_frame->document()) | ||||
|         return {}; | ||||
|     return m_content_frame->document()->origin(); | ||||
| } | ||||
| 
 | ||||
| bool HTMLIFrameElement::may_access_from_origin(const Origin& origin) const | ||||
| { | ||||
|     return origin.is_same(content_origin()); | ||||
| } | ||||
| 
 | ||||
| const DOM::Document* HTMLIFrameElement::content_document() const | ||||
| { | ||||
|     return m_content_frame ? m_content_frame->document() : nullptr; | ||||
|  |  | |||
|  | @ -44,6 +44,9 @@ public: | |||
| 
 | ||||
|     const DOM::Document* content_document() const; | ||||
| 
 | ||||
|     Origin content_origin() const; | ||||
|     bool may_access_from_origin(const Origin&) const; | ||||
| 
 | ||||
|     void content_frame_did_load(Badge<FrameLoader>); | ||||
| 
 | ||||
| private: | ||||
|  |  | |||
|  | @ -7,6 +7,5 @@ interface HTMLIFrameElement : HTMLElement { | |||
|     [Reflect] attribute DOMString width; | ||||
|     [Reflect] attribute DOMString height; | ||||
| 
 | ||||
|     readonly attribute Document? contentDocument; | ||||
| 
 | ||||
|     [ReturnNullIfCrossOrigin] readonly attribute Document? contentDocument; | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling