diff --git a/docs/src/content/docs/rules.md b/docs/src/content/docs/rules.md
index ba4e71d..a689253 100644
--- a/docs/src/content/docs/rules.md
+++ b/docs/src/content/docs/rules.md
@@ -251,10 +251,11 @@ HTML metadata is enumerated among the non-rendered carriers in Greshake et al.
- **Default:** on
Walk every element and, for a small allowlist of agent-readable attributes —
-`aria-label`, `aria-description`, `alt`, `title`, `placeholder`, `data-tooltip`,
-and `value` on `` elements the user cannot reach (`disabled` or
-`type="hidden"`) — remove the attribute outright when its value matches the
-prompt-injection pattern set (the same regex bundle used by
+`aria-label`, `aria-description`, `aria-roledescription`, `aria-placeholder`,
+`aria-valuetext`, `aria-keyshortcuts`, `alt`, `title`, `placeholder`,
+`data-tooltip`, and `value` on `` elements the user cannot reach
+(`disabled` or `type="hidden"`) — remove the attribute outright when its value
+matches the prompt-injection pattern set (the same regex bundle used by
`prompt-injection-redact`). Clean attributes are preserved. Attributes outside
the allowlist are not inspected. We remove the whole attribute rather than blank
it because an empty `aria-label` actively hides an element from
diff --git a/extension/src/rules/__tests__/attribute-injection-sanitize.property.test.ts b/extension/src/rules/__tests__/attribute-injection-sanitize.property.test.ts
index db6b690..2b6d9bd 100644
--- a/extension/src/rules/__tests__/attribute-injection-sanitize.property.test.ts
+++ b/extension/src/rules/__tests__/attribute-injection-sanitize.property.test.ts
@@ -17,6 +17,10 @@ import { FIXTURES } from "./injection-fixtures";
const ALLOWLISTED_ATTRS = [
"aria-label",
"aria-description",
+ "aria-roledescription",
+ "aria-placeholder",
+ "aria-valuetext",
+ "aria-keyshortcuts",
"alt",
"title",
"placeholder",
@@ -26,6 +30,10 @@ const ALLOWLISTED_ATTRS = [
const TAG_FOR_ATTR: Record<(typeof ALLOWLISTED_ATTRS)[number], string> = {
"aria-label": "button",
"aria-description": "div",
+ "aria-roledescription": "div",
+ "aria-placeholder": "input",
+ "aria-valuetext": "div",
+ "aria-keyshortcuts": "button",
alt: "img",
title: "span",
placeholder: "input",
diff --git a/extension/src/rules/__tests__/attribute-injection-sanitize.test.ts b/extension/src/rules/__tests__/attribute-injection-sanitize.test.ts
index 4b5d3de..aa512f4 100644
--- a/extension/src/rules/__tests__/attribute-injection-sanitize.test.ts
+++ b/extension/src/rules/__tests__/attribute-injection-sanitize.test.ts
@@ -21,6 +21,10 @@ describe("attribute-injection-sanitize candidate attributes", () => {
it.each([
["aria-label", "button"],
["aria-description", "div"],
+ ["aria-roledescription", "div"],
+ ["aria-placeholder", "input"],
+ ["aria-valuetext", "div"],
+ ["aria-keyshortcuts", "button"],
["alt", "img"],
["title", "span"],
["placeholder", "input"],
@@ -39,6 +43,10 @@ describe("attribute-injection-sanitize candidate attributes", () => {
["alt", "img", "Product photo"],
["title", "span", "Posted 3 days ago"],
["placeholder", "input", "Search products"],
+ ["aria-roledescription", "div", "carousel"],
+ ["aria-valuetext", "div", "$129.99"],
+ ["aria-keyshortcuts", "button", "Control+S"],
+ ["aria-placeholder", "input", "Search products"],
])("preserves clean %s values", (attribute, tag, value) => {
document.body.innerHTML = `<${tag} ${attribute}="${value}">${tag}>`;
diff --git a/extension/src/rules/attribute-injection-sanitize.ts b/extension/src/rules/attribute-injection-sanitize.ts
index 8642698..fa1d581 100644
--- a/extension/src/rules/attribute-injection-sanitize.ts
+++ b/extension/src/rules/attribute-injection-sanitize.ts
@@ -3,13 +3,15 @@
// Apply the prompt-injection pattern set to a small allowlist of
// agent-readable element attributes. Sighted users typically don't see
-// these strings — `aria-label`, `aria-description`, `title`,
-// `placeholder`, `alt`, and `data-tooltip` surface in screen readers,
-// hover popups, or empty-state hints, not as the main visible label.
-// Browser-use agents, in contrast, read the accessibility tree where
-// these values are first-class names and descriptions for every
-// element. That asymmetry makes attributes a clean carrier for
-// instruction-shaped text the page operator never has to render.
+// these strings — `aria-label`, `aria-description`,
+// `aria-roledescription`, `aria-placeholder`, `aria-valuetext`,
+// `aria-keyshortcuts`, `title`, `placeholder`, `alt`, and `data-tooltip`
+// surface in screen readers, hover popups, or empty-state hints, not as
+// the main visible label. Browser-use agents, in contrast, read the
+// accessibility tree where these values are first-class names,
+// descriptions, value text, and shortcut hints for every element. That
+// asymmetry makes attributes a clean carrier for instruction-shaped
+// text the page operator never has to render.
//
// We also scrub `value` on `` elements the user cannot reach:
// `disabled` inputs render to humans but cannot be edited, and
@@ -44,6 +46,10 @@ const RULE_ID = "attribute-injection-sanitize" as const;
const CANDIDATE_ATTRIBUTES = [
"aria-label",
"aria-description",
+ "aria-roledescription",
+ "aria-placeholder",
+ "aria-valuetext",
+ "aria-keyshortcuts",
"alt",
"title",
"placeholder",