Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add rules/atlassian/forge-skills/agent-privilege-escalationgit clone --depth 1 https://github.com/atlassian/forge-skillsWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/rules/atlassian/forge-skills/agent-privilege-escalation)<a href="https://agentmods.dev/rules/atlassian/forge-skills/agent-privilege-escalation"><img src="https://agentmods.dev/badge/rules/atlassian/forge-skills/agent-privilege-escalation.svg" alt="Measured on agentmods" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5 | $0.00011 | $0.01290 |
| Opus 5 | $0.00005 | $0.00645 |
| Sonnet 5 | $0.00002 | $0.00258 |
| Haiku 4.5 | $0.00001 | $0.00129 |
Grade A, and why
agent-privilege-escalation scanned grade A with 1 finding against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 4d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Makes network callslowCapability
Not a fault in itself. Listed so you know the mod talks to something, and to what.
const data = await fetch(resourceUrl); // SSRF risk How it starts
The opening of the file, as written. The whole thing — 176 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Context
- Forge Rovo agents can execute actions with elevated privileges via
asApp(). A known AuthZ gap (AGRC-15320) allows agents to perform actions with higher privileges than the requesting user. - Related CWE: CWE-269 (Improper Privilege Management), CWE-862 (Missing Authorization).
- Reference: Rovo Forge A4J Risk documentation.
Scope & Signals
- Manifest:
rovo:agentandrovo:actionmodules. - Risk patterns:
- Actions using
asApp()without user permission verification. - Missing authorization checks before invoking Forge functions.
- LLM-influenced actions without validation.
- Actions on restricted content without access verification.
- Actions using
Rovo-Specific Concerns
- Rovo Forge Actions documentation lacks
asUservsasAppguidance (unlike regular Forge Actions). - Convo AI should prevent unauthorized actions but gaps exist.
- Forge agents may not respect app access rules for restrictions.
- Browser context URLs consumed by agents are user-controlled.
Vulnerable Patterns
// VULNERABLE - asApp without authorization check
export async function deleteIssueAction({ issueId }) {
const api = asApp();
// No check if user can delete this issue!
await api.requestJira(route`/rest/api/3/issue/${issueId}`, {
method: 'DELETE'
});
return { success: true };
}
// VULNERABLE - Trusting LLM-provided identifiers
export async function updateContentAction({ pageId, content }) {
const api = asApp();
// pageId comes from LLM, could reference any page
await api.requestConfluence(route`/wiki/api/v2/pages/${pageId}`, {
method: 'PUT',
body: JSON.stringify({ body: content })
});
}
// VULNERABLE - No validation of agent-provided context
export async function accessResourceAction({ resourceUrl }) {
// resourceUrl from browser context - user controlled!
const data = await fetch(resourceUrl); // SSRF risk
return processData(data);
}
Secure Patterns
// SECURE - Verify user permission before asApp action
export async function deleteIssueAction({ issueId }, context) {
// First verify user has permission
const userApi = asUser();
const permissions = await userApi.requestJira(
route`/rest/api/3/mypermissions?issueId=${issueId}&permissions=DELETE_ISSUES`
);
if (!permissions.permissions.DELETE_ISSUES.havePermission) {
throw new Error('You do not have permission to delete this issue');
}
// Now safe to use asApp
const api = asApp();
await api.requestJira(route`/rest/api/3/issue/${issueId}`, {
method: 'DELETE'
});
return { success: true };
}
// SECURE - Validate and constrain LLM inputs
export async function updateContentAction({ pageId, content }, context) {
// Validate pageId format
if (!isValidPageId(pageId)) {
throw new Error('Invalid page ID');
}
// Verify user has access to this page
const userApi = asUser();
try {
await userApi.requestConfluence(route`/wiki/api/v2/pages/${pageId}`);
} catch (e) {
throw new Error('You do not have access to this page');
}
// Sanitize content from LLM
const sanitizedContent = sanitizeContent(content);
const api = asApp();
await api.requestConfluence(route`/wiki/api/v2/pages/${pageId}`, {
method: 'PUT',
body: JSON.stringify({ body: sanitizedContent })
});
}
// SECURE - Validate URLs from browser context
export async function processUrlAction({ url }, context) {
// Allowlist of acceptable URL patterns
const ALLOWED_PATTERNS = [
/^https:\/\/.*\.atlassian\.net\//,
];
if (!ALLOWED_PATTERNS.some(p => p.test(url))) {
throw new Error('Invalid URL');
}
// Process validated URL
}
Detection Checklist
- Identify all
rovo:agentandrovo:actionmodules in manifest. - Review each action function for
asApp()usage. - Verify authorization checks precede all
asApp()operations. - Check for user permission validation on sensitive actions.
- Look for LLM-provided input used without validation.
- Assess browser context URL handling.
- Verify actions respect content restrictions.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 4d ago First seen · 176 lines · 11 tokens per session scan A 50cadeaa55b4
agent-privilege-escalation is a cursor rule published in the GitHub repository atlassian/forge-skills (20 stars, last pushed 5d ago), licensed Apache-2.0. It adds 11 tokens to every session and 1,290 once invoked, about $0.0001 per session on Opus 5. A static security scan graded it A with 1 finding (makes network calls). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other cursor rules, from other repositories
angular-20
This rule provides comprehensive best practices and coding standards for Angular development, focusing on modern TypeScript, standalone components, signals, and performance optimizations.
dev-standard
Apache Superset development standards and guidelines for Cursor IDE.
cli-error-handling
CLI command error handling patterns.
prefer-direct-imports-over-module-mocks
Prefer extracting a testable core over vi.mock / vi.resetModules when unit tests need to reach production logic entangled with config, env, or singletons.
control-plane-descriptors
Control plane descriptor and instance implementation patterns.
family-instance-domain-actions
Family instance domain action implementation patterns.