\documentclass{article}
\usepackage[affil-it]{authblk}
\usepackage{graphicx}
\usepackage[space]{grffile}
\usepackage{latexsym}
\usepackage{textcomp}
\usepackage{longtable}
\usepackage{tabulary}
\usepackage{booktabs,array,multirow}
\usepackage{amsfonts,amsmath,amssymb}
\providecommand\citet{\cite}
\providecommand\citep{\cite}
\providecommand\citealt{\cite}
\usepackage{url}
\usepackage{hyperref}
\hypersetup{colorlinks=false,pdfborder={0 0 0}}
\usepackage{etoolbox}
\makeatletter
\patchcmd\@combinedblfloats{\box\@outputbox}{\unvbox\@outputbox}{}{%
  \errmessage{\noexpand\@combinedblfloats could not be patched}%
}%
\makeatother
% You can conditionalize code for latexml or normal latex using this.
\newif\iflatexml\latexmlfalse
\providecommand{\tightlist}{\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}%

\AtBeginDocument{\DeclareGraphicsExtensions{.pdf,.PDF,.eps,.EPS,.png,.PNG,.tif,.TIF,.jpg,.JPG,.jpeg,.JPEG}}

\usepackage[utf8]{inputenc}
\usepackage[english]{babel}




\begin{document}

\title{Authenticating Route Transitions in an SPA: What to do About the
Developer Console ~\\}


\author{Alec Aivazis}
\affil{Affiliation not available}



\date{\today}

\maketitle




In a single page app, all of the decisions about what view/subview to
render occurs on the client. This means that ideally the client would be
able to authenticate the currently logged in user on transitions to
sensitive pages and access its data without going back to the server.
This means that~special care needs to be made to protect our application
from a malicious user interacting with the developer console present in
all modern browsers. One possible security vulnerability is the
escalation of a globally stored user user role. This would cause the
hacker to view a part of the website that they were forbidden to.\\

This blog post summarizes my attempts at adding an additional layer of
security to my locally stored authentication information.~Also, I just
want to make it clear: even if a perfect solution is found for this
vulnerability, server endpoints still need to verify the request. The
client can~\emph{never}~be trusted~and performing crypto on the browser
is
a~\textbf{\href{http://tonyarcieri.com/whats-wrong-with-webcrypto}{bad
idea}}.~\\

\section{No one is an island}\label{auto-label-section-343306}

Our problem is simply stated: we need a way to store the user
authentication information on the client in a trustworthy manner.~If we
allow ourselves one connection to the client, we can authenticate the
credentials and save a copy of the authentication information in a way
that prevents it from being easily changed by the console. This means we
have moved the crypto part off of the client and we can begin to think
about trusting the data that we have stored.\\

JavaScript has a problem with global state. This problem is known by
almost all JavaScript developers and is exacerbated by the presence of
the developers console. We can assign a function that is available
globally in the success handler of the xhr request which will returned
the decrypted authentication information in a read-only manner. The
global scope of the closure makes the unencrypted authentication data
readable by anyone who requires it\\

\subsection{More callbacks?? I like raw data
types.}\label{more-callbacks-i-like-raw-data-types.}

Sometimes, it's not convinient to authenticate against a closure. For
instance, it might make more sense to store your authentication
information in a redux store so that you can keep all of your data in a
particular place. While this is probably unnecessary in all but the
extreme cases, it is possible to prevent the globally available data
store from being tampered with.~We can let~them modify the data so long
as~we have some way of invalidating it afterwards and fetching new data
to use.\\

\section{Persisting Authentication Between Browser
Sessions}\label{auto-label-section-555278}

In most cases, in order to achieve persistance, an additional storage
mechanism is required whose lifetime exceeds the memory stack of the
browser window to store the session data. Two options exist in the
mainstream: storing a session token that is referenced agains the
server, or an encrypted version of JSON called a
\href{http://openid.net/specs/draft-jones-json-web-token-07.html}{JWT}.\\

\subsection{Choose your weapon: JWT vs Session Token and Local Storage
vs
Cookies~}\label{choose-your-weapon-jwt-vs-session-token-and-local-storage-vs-cookies}

JWTs are a good storage candidate because they allow for the client to
be responsible for keeping track of the permissions of the currently
logged in user. This removes the need for a session store in most cases
which dramatically increases scalability and there are no more potential
problem of synchronizing the store among processes with separate memory.
~However JWTs require a secret key to be decrypted which means it can't
happen on the frontend with the same key that the server uses, say for
its~\href{http:}{csrf}~protection. A malicious visiter would be able to
download the source code compiled on a few different views and look for
similar strings. One of them would be the secret key so its easily
brute-forcible.~\\

Now that we have decided to use JWTs, we need to figure out where to
store them.~The two most common approaches
are~\href{https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie}{cookies}~or~\href{https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage}{local
storage}. For a good comparison of the two for storing JWTs
see~\href{https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/}{this}~blog
post. In short, local storage is susceptible to xss and cookies are
susceptible to csrf. Since csrf protection is standard in most backend
and xss is a bit tricker, I opted to store my JWT in a cookie with the
HttpOnly, and Secure flags\\

\subsection{Handling ~the Request for Authentication
Information}\label{auto-label-subsection-964588}

Since we rely on the server to decrypt the JWT, we are always forced to
make a single request when the client starts that authenticates the
token. In order to avoid race conditions, it is reccomended that this
request is made synchronously, before the application starts.~\\

\section{Nothing's Perfect}\label{nothings-perfect}

One situation in which it fails is in the universal javascript
environment. To the best of my knowledge, the server is unable to
prepare the closure in a way that is not susceptible to locally changing
the source code. While CORS would protect the server from processing
request made by a malicious local host, something just
feels~\emph{wrong} about storing the authentication information in
generated source code. If you have any other ideas or solution, please
comment.\\

\section{Final Thoughts}\label{auto-label-section-168926}

In this blog post I described a technique I use to secure my
authentication information on the client in a read only manner. This can
be used to perform authentication logic on the client and prevent
unnecessary requests to the backend. Even while this is the case, it is
necessary to authenticate the backend endpoints to prevent data leakage.
If you have any questions, comments, or can think of a way to solve this
in the isomorphic environment, please leave a comment.

\selectlanguage{english}
\FloatBarrier
\end{CJK}\end{document}

