Skip to content

Conversation

LoadJulz
Copy link

@LoadJulz LoadJulz commented Sep 4, 2025

This PR provides a proof-of-concept implementation for integrating the App-Learning Academy inside Blink Wallet using react-native-webview.

The purpose is a security review so the Blink team can verify how the academy is embedded, how data is passed, and how potential attack vectors are mitigated.

Out of Scope (to be addressed later)
❌ UI behavior (e.g. hiding/showing bottom bar, safe area handling, dark mode)
❌ Reuse of the existing wallet WebView component

Security Documentation

Before reviewing the code, please read our WebView Security Guide.
It explains the security measures that sandbox the academy from the rest of the application, including:

  • JWT-based session binding
  • Navigation hardening
  • Message bridge protection
  • Script and resource restrictions

How to Run the Integration

  1. Generate a JWT token.
    In academy-screen.tsx, replace the placeholder with your token:

const jwtToken = '[PUT YOUR JWT TOKEN HERE]'

  1. To generate a token for testing, you can use the demo secret 2ffcf8032bd40626f4e90edf35b44e45 and the following script:
require('dotenv').config()
const jose = require('jose')

async function generateJWT() {
  const secret = '[PUT THE SECRET HERE]'
  const durationSeconds = 60 * 60 

  const now = Math.floor(Date.now() / 1000)
  const claims = {
    sub: 123409876, // Unique user identifier
    service: 'academy',
    exp: now + durationSeconds,
  }

  const secretBytes = new TextEncoder().encode(secret)

  const jwt = await new jose.SignJWT(claims)
    .setProtectedHeader({ alg: 'HS256', typ: 'JWT' })
    .sign(secretBytes)

  console.log('JWT:', jwt)
}

generateJWT().catch(console.error)

Summary

This PoC demonstrates how the academy can be integrated securely inside the Blink Wallet.
It shows that:

✅ User sessions are bound via short-lived JWTs.
✅ The WebView is sandboxed and locked down.
✅ The message bridge is hardened against injection or spoofing.
✅ External navigation and script injection are prevented.

Addendum: Eager Loading on iOS
Using enableScreens(false) allows us on iOS to eagerly load the Academy tab. Without it, the Academy tab would only load once the user clicks on it, resulting in a slight delay. We can safely set this option to false, as it is primarily intended for navigation-heavy apps, which currently is not the case for Blink Mobile.

@LoadJulz LoadJulz changed the title Academy integration poc and security showcase Academy integration proof of concept Sep 4, 2025
@LoadJulz LoadJulz changed the title Academy integration proof of concept Academy integration (proof of concept) Sep 4, 2025
@k9ert
Copy link
Contributor

k9ert commented Sep 16, 2025

The biggest question here is, how the mobile-app authenticate against the academy. So the suggestion from this PR above is that this should be done via a jwt-token. Unfortunately we're not using JWT tokens inside the mobile app yet.

We're using kratos database based session tokens which we can't simply pass for obvious reasons: This token of the mobile-app is an authentication token which is used by the mobile-app against the graphQL-API (and not self-contained but DB based).
API-tokens could potentially be obtained via the kratos-token but they are not self-contained but also database backed (and not for frontend use anyway, considering the mobile app as frontend). But we need something self-contained like jwt in order to avoid that the academy needs to call the blink-backend to verify session-tokens.

This hesitation needs to be discussed on an architectural level.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants