Skip to content

Commit 54848cf

Browse files
aldro61claude
andcommitted
Hide context menus on form and list pages to prevent exploits
The right-click context menus on form headers and list rows provided options that could be used to modify fields/data outside the task scope. This adds MutationObservers that remove context menus as soon as they appear, preventing agents from using this mechanism to bypass restrictions. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 4134527 commit 54848cf

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

src/browsergym/workarena/tasks/form.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,30 @@ def get_init_scripts(self) -> List[str]:
395395
396396
runInGsftMainOnlyAndProtectByURL(removeAdditionalActionsButton, '{url_suffix}');
397397
""",
398+
f"""
399+
function removeContextMenus() {{
400+
waLog('Setting up context menu removal observer...', 'removeContextMenus');
401+
// Remove any existing context menus
402+
document.querySelectorAll('.context_menu').forEach((menu) => {{
403+
menu.remove();
404+
}});
405+
// Observe for new context menus being added
406+
const observer = new MutationObserver((mutations) => {{
407+
mutations.forEach((mutation) => {{
408+
mutation.addedNodes.forEach((node) => {{
409+
if (node.nodeType === 1 && node.classList && node.classList.contains('context_menu')) {{
410+
node.remove();
411+
waLog('Removed dynamically added context menu', 'removeContextMenus');
412+
}}
413+
}});
414+
}});
415+
}});
416+
observer.observe(document.body, {{ childList: true, subtree: true }});
417+
waLog('Context menu observer active', 'removeContextMenus');
418+
}}
419+
420+
runInGsftMainOnlyAndProtectByURL(removeContextMenus, '{url_suffix}');
421+
""",
398422
]
399423

400424
def start(self, page: Page) -> None:

src/browsergym/workarena/tasks/list.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ def get_init_scripts(self) -> List[str]:
116116
return super().get_init_scripts() + [
117117
"registerGsftMainLoaded();",
118118
self._get_remove_personalize_list_button_script(),
119+
self._get_remove_context_menus_script(),
119120
]
120121

121122
def _get_remove_personalize_list_button_script(self):
@@ -136,6 +137,37 @@ def _get_remove_personalize_list_button_script(self):
136137
"""
137138
return script
138139

140+
def _get_remove_context_menus_script(self):
141+
"""
142+
Removes context menus that appear on right-click in list views.
143+
These menus provide options that could be used to modify list data outside the task scope.
144+
"""
145+
script = """
146+
function removeContextMenus() {
147+
waLog('Setting up context menu removal observer...', 'removeContextMenus');
148+
// Remove any existing context menus
149+
document.querySelectorAll('.context_menu').forEach((menu) => {
150+
menu.remove();
151+
});
152+
// Observe for new context menus being added
153+
const observer = new MutationObserver((mutations) => {
154+
mutations.forEach((mutation) => {
155+
mutation.addedNodes.forEach((node) => {
156+
if (node.nodeType === 1 && node.classList && node.classList.contains('context_menu')) {
157+
node.remove();
158+
waLog('Removed dynamically added context menu', 'removeContextMenus');
159+
}
160+
});
161+
});
162+
});
163+
observer.observe(document.body, { childList: true, subtree: true });
164+
waLog('Context menu observer active', 'removeContextMenus');
165+
}
166+
167+
runInGsftMainOnlyAndProtectByURL(removeContextMenus, '_list.do');
168+
"""
169+
return script
170+
139171
def _get_visible_list(self, page: Page):
140172
self._wait_for_ready(page)
141173

0 commit comments

Comments
 (0)