- Iframe embedding —
X-Frame-Optionsand CSPframe-ancestorsto prevent clickjacking - Phishing domain attacks — how to lock your integration to the correct tenant slug and appId
- The slug/appId attack vector — specific to multi-tenant platforms; how look-alike tenant registration can compromise your users
- CSP for in-memory token protection — blocking the script-injection path that bypasses the in-memory storage defense
- Library limitations — an honest disclosure of what ailita-library cannot prevent
Iframe embedding protection
A login form embedded in an attacker-controlled<iframe> allows clickjacking attacks where the user believes they are interacting with the legitimate page but their clicks are captured by an invisible overlay on the attacker’s site. Both X-Frame-Options and CSP frame-ancestors prevent your login page from being embedded in third-party frames.
X-Frame-Options header
Set this response header on pages that renderLoginForm or any ailita-library auth component:
X-Frame-Options is widely supported but is superseded by the CSP frame-ancestors directive in modern browsers. If you set both, frame-ancestors takes precedence in supporting browsers. Set both for maximum compatibility.CSP frame-ancestors
Add aContent-Security-Policy header with a frame-ancestors directive. In Next.js, set this in next.config.ts:
Phishing domain protection
A phishing attack presents users with a look-alike domain (e.g.,app-mycompany.com vs app.mycompany.com) that hosts a copy of your login page. At the ailita-library integration layer, the slug and appId props are the canonical identifiers that bind the login form to a specific tenant.
Validate slug and appId at startup
Hard-code your expectedslug and appId as constants and assert them at app startup — never derive them dynamically from the URL, query parameters, or localStorage.
The slug/appId attack vector
ailita-library is a multi-tenant platform. Any party can register a tenant with an arbitrary slug. An attacker who knows your slug can registeryour-tenant-slug-support or your-tenant-slug-help on the same platform and obtain a legitimate appId for that look-alike tenant.
Here is how the attack unfolds: If your consumer app reads slug from the URL (e.g., ?tenant=your-tenant-slug) and the attacker crafts a phishing URL pointing at their look-alike tenant, AilitaProvider will call GET /auth/discovery?slug=your-tenant-slug-support, receive a valid response from the attacker’s tenant, and inject the attacker’s X-App-ID and X-Mid-Key headers. Credentials submitted via LoginForm would then be sent to the attacker’s backend.
The discovery call sequence in AilitaProvider is:
setTenantConfig uses data.app from the discovery response — the value the server returns for the given slug — not the consumer-provided appId prop. If the slug resolves to an attacker’s tenant, the attacker controls data.app and data.publicApiKey. All subsequent requests carry the attacker’s tenant headers.
CSP headers to protect the in-memory token
TheaccessToken is stored in memory and is not accessible via localStorage. However, a script injection that executes in the same browsing context before the library initializes can monkey-patch XMLHttpRequest or fetch to intercept requests and extract tokens from Authorization headers. A strict Content Security Policy prevents untrusted scripts from running.
For more context on the in-memory storage pattern and why XSS is still a threat despite it, see Token Security Model.
Recommended CSP
Next.js generates runtime inline scripts for hydration. You will need to use nonces or hashes for those scripts. See the Next.js CSP documentation for the nonce-based approach with Middleware.
Library limitations
ailita-library is a client-side React library. It cannot enforce the following properties — and does not claim to.| Protection | Why ailita-library cannot provide it |
|---|---|
| Prevent phishing of the host app | The library runs inside your app; if the user navigates to a phishing domain, the library is not loaded — the attacker’s page is |
| Prevent credential interception by malicious browser extensions | Extensions run with elevated privileges and can read page content regardless of CSP |
| Enforce HTTPS | SSL/TLS is a network layer concern — your web server or CDN must enforce HTTPS |
| Verify domain authenticity (DNSSEC, HSTS) | Infrastructure concern — configure HSTS headers and DNSSEC at the DNS/CDN layer |
| Prevent server-side credential stuffing | The library submits credentials to your backend; rate limiting and account lockout are backend concerns |
The most important protection against phishing is user education (recognizing the correct domain) combined with TOTP/hardware key 2FA. Even with a perfect client-side implementation, a user who types credentials into a phishing page has bypassed all library-level protections. The library provides correct integration patterns — not a substitute for 2FA.
Next steps
Token Security Model
How accessToken and ailita_rt are stored, the 401 refresh queue, and the security boundary table
Fingerprinting & Bot Detection
BehaviorData signals, VPN/incognito detection, and GDPR privacy requirements

