diff --git a/Userland/Libraries/LibWeb/HTML/FrameHostElement.cpp b/Userland/Libraries/LibWeb/HTML/FrameHostElement.cpp
index 19d5d6a560e..30b338a8d37 100644
--- a/Userland/Libraries/LibWeb/HTML/FrameHostElement.cpp
+++ b/Userland/Libraries/LibWeb/HTML/FrameHostElement.cpp
@@ -26,8 +26,11 @@ void FrameHostElement::inserted()
HTMLElement::inserted();
if (!is_connected())
return;
- if (auto* frame = document().frame())
+ if (auto* frame = document().frame()) {
m_content_frame = Frame::create_subframe(*this, frame->main_frame());
+ m_content_frame->set_frame_nesting_levels(frame->frame_nesting_levels());
+ m_content_frame->register_frame_nesting(document().url());
+ }
}
Origin FrameHostElement::content_origin() const
diff --git a/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp b/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp
index d0052aed99c..c36000191b7 100644
--- a/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp
+++ b/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp
@@ -136,6 +136,11 @@ bool FrameLoader::load(const LoadRequest& request, Type type)
return false;
}
+ if (!m_frame.is_frame_nesting_allowed(request.url())) {
+ dbgln("No further recursion is allowed for the frame, abort load!");
+ return false;
+ }
+
auto& url = request.url();
set_resource(ResourceLoader::the().load_resource(Resource::Type::Generic, request));
diff --git a/Userland/Libraries/LibWeb/Page/Frame.cpp b/Userland/Libraries/LibWeb/Page/Frame.cpp
index 99c0e111b36..0a4386fadce 100644
--- a/Userland/Libraries/LibWeb/Page/Frame.cpp
+++ b/Userland/Libraries/LibWeb/Page/Frame.cpp
@@ -286,4 +286,14 @@ void Frame::unregister_viewport_client(ViewportClient& client)
VERIFY(was_removed);
}
+void Frame::register_frame_nesting(URL const& url)
+{
+ m_frame_nesting_levels.ensure(url)++;
+}
+
+bool Frame::is_frame_nesting_allowed(URL const& url) const
+{
+ return m_frame_nesting_levels.get(url).value_or(0) < 3;
+}
+
}
diff --git a/Userland/Libraries/LibWeb/Page/Frame.h b/Userland/Libraries/LibWeb/Page/Frame.h
index 49370b86837..daac8635815 100644
--- a/Userland/Libraries/LibWeb/Page/Frame.h
+++ b/Userland/Libraries/LibWeb/Page/Frame.h
@@ -81,6 +81,12 @@ public:
void did_edit(Badge);
+ void register_frame_nesting(URL const&);
+ bool is_frame_nesting_allowed(URL const&) const;
+
+ void set_frame_nesting_levels(const HashMap frame_nesting_levels) { m_frame_nesting_levels = move(frame_nesting_levels); };
+ HashMap const& frame_nesting_levels() const { return m_frame_nesting_levels; }
+
private:
explicit Frame(DOM::Element& host_element, Frame& main_frame);
explicit Frame(Page&);
@@ -105,6 +111,8 @@ private:
bool m_cursor_blink_state { false };
HashTable m_viewport_clients;
+
+ HashMap m_frame_nesting_levels;
};
}