An old OAuth redirect URL was still active and vulnerable to XSS. Clicking a crafted link silently sent the user's token to the attacker.
No effective rate limiting on the login endpoint. Credentials from third-party breaches worked because users reused passwords.
Missing authentication on content endpoints, combined with sequential IDs and no rate limiting, allowed full bulk scraping.
PUT /account accepted any valid token without password confirmation. One stolen token = permanent account takeover.