Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions examples/scanner_browser_submit/browser_submit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""Synthetic browser-submit fixture for the advisory execution-gap scanner.

The page object below is local-only: it records no data and contacts no service.
"""


class SyntheticPage:
"""Minimal stand-in exposing browser-style methods to static analysis."""

async def fill(self, selector: str, value: str) -> None:
pass

async def click(self, selector: str) -> None:
pass


async def browser_agent_submit_profile(page: SyntheticPage, email: str) -> None:
"""Model a consequential form submission without performing a real action."""
await page.fill("#email", email)
await page.click("button[type=submit]")
24 changes: 24 additions & 0 deletions tests/unit/test_scanner_universal.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,30 @@ async def submit_account(browser_session, params):
self.assertEqual("yes", finding.agent_control_context)
self.assertIn("missing proof gate", finding.control_gaps)

def test_browser_submit_fixture_is_reported_as_an_advisory_candidate(self) -> None:
fixture = (
Path(__file__).resolve().parents[2]
/ "examples"
/ "scanner_browser_submit"
/ "browser_submit.py"
)
report = self._scan_source(
"controller/browser_submit.py",
fixture.read_text(encoding="utf-8"),
)
finding = self._finding_for(report, "S6")
payload = report.to_dict()
markdown = render_markdown_report(report, mode="developer").lower()

self.assertEqual("BROWSER_AGENT_SIDE_EFFECT", finding.category)
self.assertEqual("yes", finding.agent_control_context)
self.assertEqual("RUNTIME_CODE", finding.context_classification)
self.assertIn("candidate", payload["consequence_class_label"].lower())
self.assertIs(False, payload["vulnerability_claim"])
self.assertIsNone(payload["vulnerability_severity"])
self.assertIn("runtime reachability", markdown)
self.assertTrue(all(term not in markdown for term in UNSAFE_DEFINITIVE_TERMS))

def test_computer_use_desktop_actions_are_detected(self) -> None:
report = self._scan_source(
"desktop/bytebot_worker.py",
Expand Down