HTML for Confluence Pages — Security Information

This document describes the security posture of HTML for Confluence Pages, the Atlassian Marketplace app. It is intended for security reviewers at customer organisations evaluating HTML for Confluence Pages for installation.


Platform

HTML for Confluence Pages is built entirely on Atlassian Forge, Atlassian's hosted application platform. HTML for Confluence Pages operates no third-party servers and runs no code outside Atlassian's network. No End-User Data is transmitted outside Atlassian's infrastructure.

What this means in practice


Permissions

HTML for Confluence Pages requests two Atlassian scopes:

Scope Reason
read:attachment:confluence List the page's attachments and read the .html file the page editor selected as a block source
storage:app Persist the two site-wide admin settings (Allow JavaScript, Maximum safety profile) in Forge Key Value Store

That is the complete scope list. The app requests no content write scopes, no administrative scopes, no user scopes, and no outbound network scopes.

The app does not request external network egress. No host appears in permissions.external.fetch because the app never calls any external host. The app declares unsafe-inline content security for its own iframe only, which is what allows the author's CSS and (when permitted) JavaScript to run inside the sealed sandbox described below.

Authentication

The app uses one authentication pattern, Forge asUser(), for every Confluence read.

Forge asUser() (attachments)

When a block uses an attached-file source, the attachments list and the selected file's content are read asUser(), so Atlassian's identity platform authorises each read against the viewer's own permissions. A viewer who cannot read the attachment sees a "no permission" notice — the app cannot read content the viewer themselves cannot read.

Admin settings reads/writes use Forge app storage and are only accepted from the app's Confluence-administration module (enforced server-side by module-key checks in the resolver, in addition to Confluence restricting who can open that screen).

There are no other authentication paths. The app does not use asApp() for content, does not consume customer-supplied API keys, and stores no credentials anywhere.

Secret handling

None. The app stores no secrets, no API keys, no OAuth tokens, no client credentials, and no encryption keys. The only stored record is the two-value admin settings object, which is not secret material. There is nothing to rotate, revoke, or audit on the secrets side.

Account actions

Content: none. The app never writes to any account, page, attachment, or group. The block's authored code is written by Confluence itself as part of the page when the editor saves — exactly as for any macro — never by the app.

The app's interaction with the Atlassian platform is exhaustively:

  1. Receive an invocation when a page containing the block is rendered (or its editor or admin screen is opened)
  2. For attached-file blocks, read the selected attachment via asUser()
  3. Read (and, from the admin screen only, write) the two-value settings record in Forge app storage
  4. Return the rendered result to the macro UI

There is no fifth step.

Sandboxing and sanitization — how author code is contained

Author-written code renders inside a double sandbox:

  1. The app's own Forge Custom UI iframe (Atlassian's standard app isolation), and
  2. An inner srcdoc iframe with sandbox="allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox" and without allow-same-origin — author code runs on a null origin with no access to Confluence data, cookies, storage, the Forge bridge, or even the app's own frame.

Before rendering, HTML passes through DOMPurify according to the block's safety profile (Strict / Standard / Trusted); the Standard default strips all scripts and event handlers. Whether JavaScript may run at all is decided server-side-of-the-block by the intersection of the block's profile and the admin guardrails (site-wide JavaScript kill-switch and maximum-profile ceiling) — an author can never exceed what the Confluence admin allows. Auto-height uses a validated postMessage protocol with a per-render token; malformed or foreign messages are ignored.

All sanitization, policy, and composition logic lives in pure TypeScript functions in lib/, unit-tested with Vitest (including XSS vectors and tag-breakout attempts such as </script> injection inside authored CSS/JS). Hard limits are enforced in memory: 100 KB combined source per block, 10 MB attachment reads. There is no AI, no analytics, no telemetry, no error reporting service, and no third-party runtime SDKs beyond DOMPurify and CodeMirror, both bundled and pinned.


Vulnerability reporting

Security vulnerabilities can be reported to security@taskhooker.com. We commit to acknowledging reports within 5 business days and disclosing patches via the Marketplace "What's new" section.

HTML for Confluence Pages is a solo-developer product. We do not currently operate a paid bug bounty programme.


Compliance

HTML for Confluence Pages inherits the security and compliance posture of the underlying Atlassian Forge platform. Atlassian Forge is certified under:

HTML for Confluence Pages itself does not have independent certifications. The app code is reviewed by Atlassian as part of the Marketplace listing approval process.


Audit & change history

For your records, every code change to HTML for Confluence Pages is reflected in the What's new section of the Marketplace listing for each version. The Marketplace partner portal also exposes a full version history for compliance audits.