DEV Community

Discussion on: I am a Developer Advocate for Security in Mobile Apps and APIs, Ask Me Anything

Collapse
 
wolfiton profile image
wolfiton

Hi @paulorenato,

You are still interested to discuss mobile and web security I have a case that I couldn't find a reliable solution so far.

Imagine the following stack:

Graphql
SSR App - NuxtJS
PWA - feature

How to deny the users access when the app goes in PWA mode(offline) or allow only the index action?

Can the auth be something else than a JWT? (paseto doesn't work because it needs the server for decrypting the token)?

How secure can a JWT auth app be for Stripe payments?

Some ideas I have related to JWT:

  • They are not secure
  • can be tampered
  • need to check also server-side
  • never trust data from the client(NUXTJs) in this case.
  • always try to encrypt them
  • problems when storing them in local storage

I think the main question is this:

Given these problems should an application be built-in Graphql SSR and PWA or is it better to just have a backend and some javascript to make a better user experience in some areas?

Collapse
 
exadra37 profile image
Paulo Renato • Edited

PWA and Offline Mode

How to deny the users access when the app goes in PWA mode(offline) or allow only the index action?

I know what a PWA is, but I have no experience with it, thus I cannot be of great help here, but as I always like to say an app should be as dumb as possible and leave the business logic to the server, and just worry about the presentation layer.

So I would say that if you need to restrict access to content by user, then the offline model will not be the one you want to use in any kind of technology of your choice. I say this because once the data is in the client side, it's public and should be considered as leaked. No matter the amount of measures you put in place it will be just a question of time and skills to reverse engineer the logic restricting the access to the data and bypass it to extract the protected data. This is even easier in browser based apps, but also doable in mobile apps that as you may know are compiled to binary format.

The Difference Between WHO and WHAT is Accessing the API Server

Before I dive into your other questions I would like to first clear a misconception about who and what is accessing an API server.

I wrote a series of articles around API and Mobile security, and in the article Why Does Your Mobile App Need An Api Key? you can read in detail the difference between who and what is accessing your API server, but I will extract here the main takes from it:

The what is the thing making the request to the API server. Is it really a genuine instance of your mobile app, or is it a bot, an automated script or an attacker manually poking around your API server with a tool like Postman?

The who is the user of the mobile app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.

So think about the who as the user your API server will be able to Authenticate and Authorize access to the data, and think about the what as the software making that request in behalf of the user.

JWT Security

Some ideas I have related to JWT:
They are not secure

They are secure when you sign them, and in this moment the correct term to use is JWS. Signing them only serves to guarantee the recipient it's intended to that the payload of it was not tampered with, but will not protect the payload from being extract and used.

JWS

A JSON Web Signature (abbreviated JWS) is an IETF-proposed standard (RFC 7515) for signing arbitrary data.[1] This is used as the basis for a variety of web-based technologies including JSON Web Token.

If you need to hide the payload data because it contains sensitive data then you want to also encrypt the payload part of the token, and at this moment you should call it a JWE.

JWE

JSON Web Encryption (JWE) is an IETF standard providing a standardised syntax for the exchange of encrypted data, based on JSON and Base64.[1] It is defined by RFC7516. Along with JSON Web Signature (JWS), it is one of the two possible formats of a JWT (JSON Web Token). JWE forms part of the JavaScript Object Signing and Encryption (JOSE) suite of protocols.

When a JWE it's used the payload cannot be decrypted, unless you have used a weak encryption algorithm or you have leaked the encryption keys.

Some ideas I have related to JWT:
can be tampered

If using JWS or JWE they cannot be tampered without you detect it on the validation.

Some ideas I have related to JWT:
need to check also server-side

That for what they were designed, aka the recipient using it needs to validate it with a public key or with the shared secret only known by the sender and the receiver.

Some ideas I have related to JWT:
never trust data from the client(NUXTJs) in this case.

That true for literally ANY client.

Some ideas I have related to JWT:
always try to encrypt them

It depends if they contain or not sensitive data.

Some ideas I have related to JWT:
problems when storing them in local storage

Local storage in browsers is always a problem, because Javascript can always access them.

Web Apps

Given these problems should an application be built-in Graphql SSR and PWA or is it better to just have a backend and some javascript to make a better user experience in some areas?

I am from the time that the web app development was simpler, and I also got into the bandwagon of building web apps with as much logic as possible on the client side and backed by an API, but from the moment I got into API security I just realized how hard is to secure API backends serving them, thus the web app that I am building now it's using session cookies and no API, just a traditional web server in Elixir with the Phoenix Framework, but off course this in my peculiar situation that I am not planning for mobile app releases, but even If I decide to add a mobile app later I wrote the backend code in a way that will be easy to extend to create an API from the web server, because the business logic is separated from the presentation layer.

My take on web apps since I got into API security in 2018 is to use Javascript only for the presentation layers, aka to manipulate the HTML DOM and enrich the user interactivity. Business logic belongs to the backend.

So my recommendation is to carefully think if you really need to build an API for your web app, and that web apps should not be using JWT tokens if they are not using an API, because a web app that gets server side rendered html is best served in terms of security with the use of session cookies with http only flag set, that will prevent Javascript to access them.

Collapse
 
wolfiton profile image
wolfiton • Edited

Thanks for sharing your take on this. I am also glad that someone else uses phoenix and elixir in their stack.

Regarding the jose standard for jwt, I was looking at paseto but never managed to make it working with laravel. the good news is that Elixir has a paseto package and might be worth looking at it if you want a powerfull security with SSR.

Also is SSR possible with http only cookies, because i couldn't find anything related to this, have you tried it?
Just found this and i am wondering if it is secure enough to be able to use it to leverage SSR for seo and security with the auth header cookie
swapnil.dev/blog/authentication-in...
Also sorry if I write so much, I am just very happy that I could find someone that is very knowledgeable regarding security and can understand my worries of the new web stacks that everybody is so thrilled about.
Thanks in advance

Thread Thread
 
exadra37 profile image
Paulo Renato

Also is SSR possible with http only cookies, because i couldn't find anything related to this, have you tried it?

Well be it server side rendered or not httpOnly cookies are not controlled by your app in the client side, instead it's the browser the one in charge of sending them back in each request to the backend, therefore you just need to check them on each request your backend receives:

From Mozilla:

Ways to mitigate attacks involving cookies:

  • Use the HttpOnly attribute to prevent access to cookie values via JavaScript.
  • Cookies that are used for sensitive information (such as indicating authentication) should have a short lifetime, with the SameSite attribute set to Strict or Lax. (See SameSite cookies, above.) In browsers that support SameSite, this has the effect of ensuring that the authentication cookie is not sent with cross-origin requests, so such a request is effectively unauthenticated to the application server.

Also remember to always encrypt the session cookies in your backend so that no one can spy on them, thus mitigating what Mozilla mentions:

Security

Information should be stored in cookies with the understanding that all cookie values are visible to, and can be changed by, the end-user. Depending on the application, it may be desirable to use an opaque identifier which is looked-up by the server or to investigate alternative authentication/confidentiality mechanisms such as JSON Web Tokens.

So if you decide to put the JWT in a session cookie, then use JWE, aka encrypted JWT's... This is what I am doing in my Elixir/Phoenix app.


the good news is that Elixir has a paseto package and might be worth looking at it if you want a powerfull security with SSR.

No need to use Paseto with Phoenix in Elixir, just use the native encrypted tokens.


Thanks for sharing your take on this. I am also glad that someone else uses phoenix and elixir in their stack.

Professionally I code in a lot of different languages, personally only in Elixir ;)