ALEXANDER NOHE: Well, I've
finished coding my app, and I have my
security rules set. I no longer have to
worry about security. SPEAKER: Did you remember
to configure App Check? [MUSIC PLAYING] ALEXANDER NOHE: You
have an awesome API that you built and want to get
directly into clients' apps. You come up with a solution
that allows your users access to your API through an API key. All pretty safe, right? Well, what if your clients
start embedding your API key in their client apps? Then anyone can
decompile the source code and find your API
key and make calls on the authorized client's
behalf to your resources. Now your authorized client is
open to their key being leaked and requests coming
in fraudulently to their backend resources. What could we have
done to help prevent this in the first place? Well, we could have
started serving requests using App Check. App Check helps protect your
API resources from abuse by preventing unauthorized
clients from accessing your backend resources. App Check will test the
requests originating from an authentic app. And depending on
the platform, it will also attest that
the device is untampered. Let's take a look
at how it works. Your app makes a request
to an attestation provider, which verifies that you are a
real user using a genuine app on a real, untampered device. The attestation provider
will supply an attestation assessment, which can be
exchanged with Firebase for an App Check token, as long
as the assessment is positive and that the attestation request
didn't occur from a potentially compromised device. After you have the
token, you can then attach it in this header and
send it along to your backend. Luckily, callable
functions in Firebase automatically do this for you. If you are using
the Admin SDK, you can verify the token is
valid and then perform whatever you were planning
on doing with the function. What just happened there? We attach a header
and use the Admin SDK. But you might not always be
using a language supported by the Admin SDK. To consider this, we
need to understand what an App Check token is. An App Check token is a JSON
Web Token also known as a JWT. It's then validated to
prove that the JWT is valid, and data can be served. These JWTs can be valid
anywhere from 30 minutes to seven days set by you
in the Firebase Console. Using a smaller TTL can
increase the amount of latency that your application
experiences as it uses eager refreshes to make sure
that your app does not have a lapse in time
when the token is good versus when it has
expired but will increase the security of your app. To decode the JWT and
validate the token, you will want to download
the Firebase App Check public JSON Web Key set from
the public endpoint shown on screen. Then you will want to
verify the token signature to ensure it's legitimate
using a standard JWS library. Once the token signature
is verified as legitimate, you will want to validate that
the header contains algorithm RSA256 and is of type JWT. The next step is
really important. You must ensure that the token
is issued by Firebase App Check under your
project, and the audience contains your project
number and your project ID. Validating the signature
of the token can tell you it's legitimately signed. But validating that it
belongs to the correct project is what stops you from
accidentally approving someone else's minted tokens. Finally, we checked that
the date is not expired. As an optional step, you
can also confirm the app ID in case you want to limit
this endpoint to only some of your apps. If everything checks
out, serve this request as you normally would. This would allow you to
use any language that is not supported by the Firebase
Admin SDK to validate tokens. Since we understand
JWTs now, you may think that this is great. But what stops someone
from stealing a token and reusing this token
until it expires? This is where replay
protection comes in. Replay protection starts
by doing what we did before with validating a token. But then it tracks
if a token is used by sending the token to a
Firebase endpoint, which then stores the token's
JWT, ID claim, or JTI and its current consumption
state on the server. You merely make a request to
the URL endpoint, supplying your App Check token in
the body of the request, and wait for a response, which
you can then decode and check whether the alreadyConsumed
field is present and set to true. If it's present and true,
throw out the request as the token is not valid. If the field is absent,
continue processing, and return a value as normal. The App Check token is then
consumed and cannot be reused on replay-protected
endpoints after this. The token can still be
consumed on nonreplay-protected endpoints, as it does not change
any of the metadata associated with the token and the
decoding of the token. There you have it. With a little bit of
digging into App Check, we are able to understand
what a token is and how to use it on our
nonadmin-SDK-enabled services. For more information on
how to process tokens in your own backends, check
out the resources below. I am Alexander Nohe reminding
you to enforce App Check.