<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Secure Authentication Model for Public Clients</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Bohdan Bodak</string-name>
          <email>bohdan.bodak@outlook.com</email>
          <xref ref-type="aff" rid="aff1">1</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Anatoliy Doroshenko</string-name>
          <email>doroshenkoanatoliy2@gmail.com</email>
          <xref ref-type="aff" rid="aff0">0</xref>
          <xref ref-type="aff" rid="aff1">1</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Institute of Software Systems of the National Academy of Sciences of Ukraine</institution>
          ,
          <addr-line>Kyiv</addr-line>
          ,
          <country country="UA">Ukraine</country>
        </aff>
        <aff id="aff1">
          <label>1</label>
          <institution>National Technical University of Ukraine “Kyiv Polytechnic Institute”</institution>
          ,
          <addr-line>Kyiv</addr-line>
          ,
          <country country="UA">Ukraine</country>
        </aff>
      </contrib-group>
      <abstract>
        <p>The paper focuses on authentication and authorization in public clients and provides a secure model as an alternative to costly Microsoft Duende BFF solution. After giving a brief overview of confidential and public clients in terms of authorization, we have analyzed problems and potential attack vectors associated with the authorization process in public clients due to their inability to hold credentials securely. Confidential clients are implemented on secure servers or able to facilitate secure authentication by other means, while public clients lack this security. Our research discovered algorithms, models, and methods for secure authorization in public clients. As a part of our model, we have implemented high entropy Proof Key for Code Exchange generator in C# .NET 6.0. In addition, we have provided a solution to a problem of storing sensitive information in public clients using the Backend for Frontend concept. This concept leverages a reverse proxy pattern where a backend application acts as a proxy and handles all client requests. Having a proxy backend application significantly tightens security model for public clients, while restricting possible attack vectors. The authorization model being researched was based on Proof Key for Code Exchange and Backend for Frontend approach. During the testing phase of our research, we have confirmed that the model was not vulnerable to Cross-Site-Scripting and Auth Code Interception attacks. A sequence diagram outlining main actors and interactions among them in context of authorization has been designed. The diagram stands as the visual representation of the model that uses proposed methods and algorithms. As a result, we have managed to build an alternative to secure authorization solutions for public clients that do not rely on the client secret. We have summarized our key findings in a Blazor Web Assembly application, which is classified as public and uses the described authentication model via a shared library.</p>
      </abstract>
      <kwd-group>
        <kwd>Authorization</kwd>
        <kwd>authentication</kwd>
        <kwd>PKCE</kwd>
        <kwd>Proof Key for Code Exchange</kwd>
        <kwd>Identity Server</kwd>
        <kwd>public application</kwd>
        <kwd>OAUTH</kwd>
        <kwd>XSS</kwd>
        <kwd>information security</kwd>
      </kwd-group>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>1. Confidential and public clients</title>
      <p>
        According to OAUTH 2.0 specification [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ] clients can be classified as either confidential or public.
Confidential clients usually facilitate security due to them being implemented on a protected server or
by having other means to secure credentials. Public clients on the other hand are unable to hold user’s
credentials securely because such clients are downloaded and executed directly in an unsecure
environment: a browser or a mobile operating system. Examples of public clients are Single Page
Applications (SPA) regardless of a technology being used and native iOS or Android applications. It
is a common practice to use a client secret as a method to prove a secure authentication, monitor and
handle auth requests within OAUTH 2.0 context. A client secret is a unique application identifier
generated for a client through a process of registration. Every client that uses some kind of an
OAUTH 2.0 compliant auth service has to be registered via that service.
      </p>
      <p>
        Confidential clients store their secret in code or configuration file. However, public clients can not
store a secret without revealing it to unauthorized parties. For example, in mobile applications it is not
possible to keep a secret in code because an attacker could retrieve it via a de-compilation process. In
addition to that, mobile apps are vulnerable to what is called an Auth Code Interception Attack [
        <xref ref-type="bibr" rid="ref2">2</xref>
        ] as
displayed on Figure 1.
      </p>
      <p>In this example, an attacker registers an additional address via a Malicious App to intercept
redirected requests and leverages an ability to intercept an authorization code from the auth server.
This example closely resembles a classic Man-In-The-Middle attack and could be viewed as a
variation of such. While this particular attack is only feasible for mobile apps, SPA also cannot use a
client secret because their entire code is accessible through a browser.</p>
    </sec>
    <sec id="sec-2">
      <title>2. Problem with authorization in public clients</title>
      <p>
        From the moment of publication of OAUTH 2.0 specs in 2013, the specification has become
widely popular and has been adopted by key industry players such as Facebook, Twitter, and Google,
practically becoming a standard [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ]. Considering that the standard was first introduced almost a
decade ago and technologies are constantly moving forward, there is always a need for new models
and methods to protect against security breaches. Formal analysis of popular websites and social
networks that use OAUTH 2.0 authentication model has discovered dozens of previously undetected
security vulnerabilities [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ]. Authors have revealed potential attacks such as Cross-Site Request
Forgery (CSRF) and Open Redirectors without going into details about them. Empirical analysis [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ]
using attack vectors from former work [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ] demonstrated a successful interception of an SSO session
and evaluated various security concerns associated with it. The article [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ] presented a cookie hijacking
attack for Facebook, which was used to authenticate in 95 SSO-applications that support OAUTH
model. Authors then went ahead and proposed a Single Sign-Off standard to become a part of
OAUTH specification, which mitigates consequences of the problem but does not solve the problem
of cookie interception itself.
      </p>
      <p>
        OAUTH 2.0 security best current practice [
        <xref ref-type="bibr" rid="ref5">5</xref>
        ] outlines 9 key attacks together with potential
countermeasures. The standard recommends using PKCE [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ] for public and confidential clients as an
additional level of security against attacks. However, the paper does not state any practical
recommendations regarding the implementation, delegating it to application developers. Based on
research [
        <xref ref-type="bibr" rid="ref3 ref4">3, 4</xref>
        ] and practices [
        <xref ref-type="bibr" rid="ref5 ref7">5, 7</xref>
        ] provided above, developers face a practical problem of
implementing a secure authentication mechanism based on PKCE flow, which would not be
vulnerable to CSRF, Open Redirectors, Auth Code Interception and other known attacks.
      </p>
    </sec>
    <sec id="sec-3">
      <title>3. Proof Key For Code Exchange (PKCE) algorithm</title>
      <p>
        Considering problems stated above, specification OAUTH 2.0 proposes to use PKCE algorithm
[
        <xref ref-type="bibr" rid="ref6">6</xref>
        ] instead of client secret, which is basically a variation of proof of possession. Despite our model
being developed for public clients, it can be utilized to protect confidential clients as well. Base
implementation of this algorithm relies on client providing a proof of code possession to an auth
server in exchange for an auth code. PKCE algorithm introduces additional parameters to the auth
flow depicted on Pic. 1: code_verifier, code_challenge, and code_challenge method. Code verifier is a
randomly generated string used as a form of a secret and generated in accordance with OAUTH 2.0
specs. Code challenge is created on a client by transforming code_verifier value. Code challenge
method is optional parameter, which represents the transformation algorithm for code_challenge and
can be set to either “S256” (SHA256 algorithm) or “plain”. Specification does not recommend using
“plain” as a code challenge method because it can lead to information exposure in case the code
challenge is intercepted. In that case, code challenge may be used directly as a code verifier, rendering
PKCE flow entirely useless. “Generating codes for PKCE algorithm” chapter provides detailed
example of generating code challenge and code verifier according to OAUTH 2.0 specification using
C# .NET 6.0. Generic authorization model using PKCE algorithm is depicted on Figure 2.
      </p>
      <p>Basic authorization model with PKCE algorithm can be broken down into the following steps:
a) Client generates code_challenge and code_verifier; sends an authorization request that
includes code_challenge and code_challenge_method.
b) Authorization server saves code_challenge together with the method and sends an
authorization code back to client.
c) Client sends a request for an access token and includes the auth code with code_verifier.
d) Auth server checks code_verifier against a stored code_challenge and returns an access token
in case the verification was successful.</p>
      <p>This algorithm works successfully because even if attacker manages to intercept the auth code, it
is impossible to exchange the code for an access token without code_verifier, which prevents Auth
Code Interception attack displayed on Pic. 1. Worth mentioning that a pair of code_challenge and
code_verifier must be unique and valid for one time use only. It is equally important to store
code_verifier securely between authorization and access token requests. We dedicated a chapter
“Methods of storing code_verifier in public clients” to solving this problem. In addition, a client has
to use a TLS secure channel for data transfer.</p>
    </sec>
    <sec id="sec-4">
      <title>4. Generating codes for PKCE algorithm</title>
      <p>For generation of code_verifier and code_challenge a class named PkceGenerator was created,
which has methods GenerateCodeVerifier and GenerateCodeChallenge respectively. A constructor of
this class accepts a parameter representing the size of code_verifier. A minimum size is 43 symbols
while maximum is 128 according to the OAUTH 2.0 specification. C# .NET 6.0 with System and
System.Security.Cryptography assemblies was used for developing this class.
namespace DemoApp.Authentication {
/// &lt;summary&gt;
/// Provides a randomly generating PKCE code verifier and it's corresponding code challenge.
/// &lt;/summary&gt;
internal class PkceGenerator {
/// &lt;summary&gt;
/// The randomly generated PKCE code verifier.
/// &lt;/summary&gt;
public string CodeVerifier;
/// &lt;summary&gt;
/// Corresponding PKCE code challenge.
/// &lt;/summary&gt;
public string CodeChallenge;
/// &lt;summary&gt;
/// Initializes a new instance of the Pkce class.
/// &lt;/summary&gt;
/// &lt;param name="size"&gt;The size of the code verifier (43 - 128 charters).&lt;/param&gt;
public PkceGenerator(uint size = 128) {
CodeVerifier = GenerateCodeVerifier(size);
CodeChallenge = GenerateCodeChallenge(CodeVerifier);
}
…
}
}</p>
      <p>According to OAUTH 2.0 RFC-7636 specification, code_verifier must be a cryptographically
strong high-entropy string with length from 43 to 128 symbols. Accepted symbols are A-Z, a-z, 0-9, -,
., _, ~. Proposed implementation compliant with specs can be found below.
/// &lt;summary&gt;
/// Generates a code_verifier according to RFC-7636.
}
}
/// &lt;/summary&gt;
/// &lt;param name="size"&gt;The size of the code verifier (43 - 128 charters).&lt;/param&gt;
/// &lt;returns&gt;A code verifier.&lt;/returns&gt;
public static string GenerateCodeVerifier(uint size = 128) {
if (size &lt; 43 || size &gt; 128)
size = 128;
const string unreservedCharacters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
Random random = new Random();
char[] highEntropyCryptograph = new char[size];
for (int i = 0; i &lt; highEntropyCryptograph.Length; i++) {
highEntropyCryptograph[i] = unreservedCharacters[random.Next(unreservedCharacters.Length)];
}
return new string(highEntropyCryptograph);</p>
      <p>Code challenge is created by hashing code_verifier using a SHA256 algorithm. A method
presented below hashed code_verifier with SHA256 and replaces unacceptable symbols making the
value usable in a URL (doing a so-called URL Encoding).
/// &lt;summary&gt;
/// Generates a code_challenge according to RFC-7636.
/// &lt;/summary&gt;
/// &lt;param name="codeVerifier"&gt;The code verifier.&lt;/param&gt;
/// &lt;returns&gt;A code challenge.&lt;/returns&gt;
public static string GenerateCodeChallenge(string codeVerifier) {
using var sha256 = SHA256.Create();
var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
return Convert.ToBase64String(challengeBytes)
.Replace('+', '-')
.Replace('/', '_')
.Replace("=", "");</p>
      <p>Using this class in the application code is fairly straightforward: developer has to create an
instance of this class and access an appropriate property to get code_verifier or code_challenge value.
Simple and lightweight design of the class ensures proper usage. An example is presented below.
PkceGenerator pkceGenerator = new ();
string codeVerifier = pkceGenerator.CodeVerifier;
string codeChallenge = pkceGenerator.CodeChallenge;</p>
      <p>Developers need to keep in mind that each pair of generated code_challenge and code_verifier
must be used only once to ensure security. Applications should not attempt to utilize the same pair of
codes because it could lead to potential interception and unfair usage of such codes by attacker in a
pursue to retrieve an auth code. OAUTH 2.0 specification and RFC-7636 do not provide any
information or best practices regarding code_verifier storage, so in the next chapter we are set to
outline main methods of storing code_verifier in applications because it is fundamental to PKCE
authorization flow.</p>
    </sec>
    <sec id="sec-5">
      <title>5. Methods of storing code_verifier in public clients</title>
      <p>
        As it was stated before, PKCE algorithm specification does not propose any methods of storing
code_verifier in between requests. Due to the fact that client receives an auth code via a callback, it is
not possible to save code verifier in a variable or by other means in code. We are going to examine
methods for storing code_verifier value in terms of WEB-applications (React, Angular, Web
Assembly). Additional methods of secure data storage for Android [
        <xref ref-type="bibr" rid="ref8">8</xref>
        ] and iOS [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ] mobile apps are
different and lay beyond the scope of this paper.
5.1.
      </p>
    </sec>
    <sec id="sec-6">
      <title>Storing a value in browser storage</title>
      <p>
        Browser storage is the most obvious solution when dealing with information storage in
WEBclients. There are two types of storage in a browser: Local Storage and Session Storage [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ]. By
means of simple JavaScript code accessing a browser’s API, developers can save data and user’s
configuration. A key difference between Local and Session storage is a persistence of data. Session
Storage does not keep data between different tabs or windows of the same browser giving developers
a false sense of security and confidence to save any value there. Unfortunately, if a website is
vulnerable to Cross-Site-Scripting (XSS) attacks, an attacker could read information from browser
storage regardless the storage type: Session or Local.
      </p>
      <p>Pros of storing a value in browser storage:
- Quick read/write operations via native browser API.
- Easy implementation with JS.</p>
      <p>Cons of such approach:
- Vulnerable to XSS attacks.
- Potential for a data leak.</p>
      <p>It is worth mentioning that modern frameworks such as Angular and React do a fair share of
work and provide methods for protecting against XSS-attacks. Nevertheless, there is always a
possibility of sensitive data leak when this data is being stored in a browser.
5.2.</p>
    </sec>
    <sec id="sec-7">
      <title>Storing in JavaScript cookies</title>
      <p>
        Another approach to information storage in a browser are cookies [
        <xref ref-type="bibr" rid="ref12">12</xref>
        ]. JavaScript code is used in
this method as in the previous one, whereby the document.cookie is called to store and retrieve data
from cookies. Pros and cons are practically the same as in the approach outlined above. There is a
simple fact every WEB developer has to understand: if they can do something in their JavaScript code
– the attacker can do it as well. Therefore, instead of investing resources into complicated algorithms
and methods to protect information in browser storage or cookies, WEB developers should look into
protecting applications from XSS attacks while finding different approaches to keep critical
information such as tokens secure.
      </p>
    </sec>
    <sec id="sec-8">
      <title>Storing a value using Server cookies</title>
      <p>
        Server applications are able to set cookies in response to a client, which cannot be retrieved via
JavaScript. Such cookies are added to a response with HttpOnly flag [
        <xref ref-type="bibr" rid="ref13">13</xref>
        ]. In addition, it is strongly
recommended for a server to set SameSite attribute as Lax or Strict [
        <xref ref-type="bibr" rid="ref13">13</xref>
        ] to avoid a situation where
cookies are being sent to third-party domains. If the SameSite attribute is not set and browser does not
support default setting to SameSite.Lax for SameSite.None cookies, then a so-called Hidden iframe
attack could be executed sending cookies to unwanted websites. Assuming that an application is
vulnerable to XSS-attack and has HttpOnly cookie without SameSite attribute, an attacker could
embed a hidden iframe into website’s DOM, which sends requests to a third-party service. All cookies
without SameSite or SameSite.None would end up on attacker’s website in this case.
      </p>
      <p>Pros of Server cookies approach:
- Makes XSS attack impossible if configured correctly.
- The most secure method for storing sensitive information.</p>
      <p>Cons of this approach:
- A backend service hosted on the same domain as the client is mandatory in order to set</p>
      <p>HttpOnly cookies with SameSite.Strict attribute.
- Deployment process could become complicated because it is required to deploy both a client
and a server application.</p>
    </sec>
    <sec id="sec-9">
      <title>6. Implementing a Backend authorization</title>
    </sec>
    <sec id="sec-10">
      <title>For Frontend (BFF) method with</title>
    </sec>
    <sec id="sec-11">
      <title>PKCE</title>
      <p>6. Authorization server directs a user to a login page where the user enters credentials and
provides consent.
7. Authorization handles the login result, saves code_challenge, and generates auth_code.
8. Authorization server redirects request back to return_url adding an auth_code.
9. Client sends a POST request to BFF for authorization token adding an auth_code to request
parameters.
10. BFF reads code_verifier from cookies, adds code_verifier and auth_code and calls
authorization service to get a token. BFF can delete code_verifier from cookies at this point.
11. Authorization server verifies code_verifier against stored code_challenge, auth_code and
other parameters such as requestor’s IP address.
12. After a successful verification, auth server issues an auth token and sends it back.
13. BFF receives authorization token, writes it in cookies as HttpOnly, Secure, SameSite.Strict.
14. BFF returns successful result to a client application.
15. Client requests user’s information via BFF and restores state.</p>
      <p>Authorization flow is depicted in details on Figure 3.</p>
      <p>
        Therefore, after successful authorization, a client is authorized to call protected BFF methods
designated for authorized users only. At the same time, a client does not contain any sensitive
information which could be vulnerable to XSS-attacks. Secure data such as code_verifier or
authorization token is stored in HttpOnly cookies with SameSite.Strict as presented in the chapter
above. In this model BFF acts as a reverse proxy pattern [
        <xref ref-type="bibr" rid="ref16">16</xref>
        ] that routes requests and handles client
authorization.
      </p>
    </sec>
    <sec id="sec-12">
      <title>7. Shared authentication library</title>
      <p>In order to ensure code reusability and scalability of this project, we have built a shared library,
which uses our proposed model. This common project handles authentication and authorization
for .NET Core API and Blazor applications. Our library can be packaged as a NuGet package and
distributed via Azure Artifacts or similar package distribution platform. Customers will simply install
the necessary packages in their projects, complete the configuration, and be able to facilitate secure
authentication in public single-page applications. This paragraph provides an overview of the library
as well as configuration that is required for the setup.
7.1.</p>
    </sec>
    <sec id="sec-13">
      <title>Shared library structure</title>
      <p>Our shared library is called BFFLight and it consists of two projects: BFFLight.Wasm and
BFFLight.Server.</p>
      <p>The first project – BFFLight.Wasm has all necessary classes and extensions to setup secure
authentication in Blazor Web Assembly client application. Project’s structure is the following:
 Authentication (folder with authentication interfaces, classes, and models)
o ProfileResponse.cs (model for user’s info response)
o BFFLightPostLogin.razor (post-login component, gets user’s info, restores state)
o PkceGenerator.cs (class that generates code_verifier and code_challenge, described in
chapter 4)
o SsoConnector.cs (a service that handles HTTP requests to a backend API for
authentication, user’s info, token exchange, etc.)
o SsoClientOptions.cs (model for client’s configuration)
o TokenResponse.cs (model for the access_token response)
o IBFFLightSignInManager.cs (interface for SignIn, SignOut, and GetClaimsPrincipalAsync
methods)
o BFFLightSignInManager.cs (implementation of the interface above, uses the</p>
      <p>SsoConnector, PkceGenerator to handle sign in, sign out, and get user’s information)
 Extensions (folder with extension classes and methods)
o IServiceCollectionExtensions.cs (provides an extension method AddBFFLightWasmAuth
that configures options and injects required services during application start)</p>
      <p>The second project is BFFLight.Server targets .NET Core 6.0 API and has necessary controllers,
classes, and extensions for secure server authentication. The project structure is described below:
 Controllers (folder with API controllers)
o SsoController.cs (main authentication controller with Token, GetProfile, and Logout
methods; uses ISsoService implementation)
 Models (folder with models)
o SsoServerOptions.cs (model for server’s configuration)
o UserInfoModel.cs (model for user’s info)
 Services (folder with services)

o ISsoService.cs (authentication service interface with methods GetAuthToken, GetProfile,</p>
      <p>Logout)
o SsoService.cs (default implementation of the ISsoService)
Extensions (folder with extension classes and methods)
o IServiceCollectionExtensions (provides an extension method AddBFFLightServerAuth that
configures options and injects required services during application start)
7.2.</p>
    </sec>
    <sec id="sec-14">
      <title>Shared library configuration</title>
      <p>Before developers begin to use this library, they first need to make sure that their application is
registered with an authentication provider. As a result of this registration process, they will get a
Client ID and Client Secret. In addition, developer also needs to know the URL address of an OpenId
SSO provider they use. The setup process begins with the installation of BFFLight.Wasm and
BFFLight.Server to Blazor Web Assembly and .NET Core API projects respectively.</p>
      <p>Let us review client’s configuration first. After installing NuGet packages, a developer should
open Program.cs file in their Blazor project to add the following lines before the await
builder.Build().RunAsync():
builder.Services.AddBFFLightWasmAuth(); // configure BFFLight services
builder.Services.AddAuthorizationCore(); // add default Core authorization if not already added
Next, a developer should open wwwroot/appsettings.json file (create a new file if it does not
exist) and add the following configuration keys:
“SsoClientOptions”: {</p>
      <p>“ClientId”: “sso_provider_client_id”, // id given to you by the SSO provider after registration
}</p>
      <p>Finally, a developer should open the App.razor file and wrap all content in a
&lt;CascadingAuthenticationState&gt;&lt;/CascadingAuthenticationState&gt; tag. This is a built-in Blazor tag
used to propagate an authentication state down components’ tree. With the
CasadingAuthenticationState, developers will be able to inject a [CascadingParameter]
Task&lt;AuthenticationState&gt; parameter to then get the auth state and user’s information in their pages.</p>
      <p>After completing client’s configuration, developers can move on to the server project setup. First,
they should introduce a call to initialize BFFLight services in Program.cs file before the var app =
builder.Build() line:
builder.Services.AddBFFLightServerAuth(); // configure BFFLightServices</p>
      <p>Moving on from the Program.cs setup, a developer should open appsettings.json file in order to
add these configuration keys:
“SsoServerOptions”: {
“ClientId”: “sso_provider_client_id”, // id given to you by the SSO provider after registration
“ClientSecret”: “sso_provider_secret”, // secret key provided by SSO after registration
“SsoServiceUrl”: “sso_url”, // URL of the SSO provider
}</p>
      <p>This completes the configuration process. Following these steps and using our BFFLight library
will allow developers to implement secure authentication and authorization in Blazor single page
public client.</p>
    </sec>
    <sec id="sec-15">
      <title>8. Conclusions</title>
      <p>In this paper we have outlined key differences between confidential and public clients in terms of
secure authorization, provided analysis of problems associated with secure authorization in public
clients using OAUTH 2.0 protocol. During the analysis stage of this research, we have managed to
discover algorithms, models, and methods for implementing secure authorization in public clients. In
addition, we have performed practical modeling and implementation of Proof Key for Code Exchange
algorithm with Backend For Frontend method. Finally, we have developed a proof-of-concept public
client that uses our shared BFFLight library with the model and algorithm for secure authorization and
is not vulnerable to attacks mentioned in the analysis phase: Cross-Site Scripting (XSS), Auth Code
Interception, CSRF, etc.</p>
    </sec>
    <sec id="sec-16">
      <title>9. References</title>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>Microsoft</given-names>
            <surname>Internet Engineering Task Force</surname>
          </string-name>
          (IETF),
          <source>The OAuth 2</source>
          .0
          <string-name>
            <given-names>Authorization</given-names>
            <surname>Framework</surname>
          </string-name>
          ,
          <year>2012</year>
          . URL: https://datatracker.ietf.org/doc/html/rfc6749#
          <fpage>section</fpage>
          -
          <lpage>2</lpage>
          .1.
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>OWASP</given-names>
            <surname>Project</surname>
          </string-name>
          ,
          <article-title>Testing for OAuth Client Weaknesses</article-title>
          ,
          <year>2022</year>
          . URL: https://owasp.org/wwwproject-web
          <string-name>
            <surname>-</surname>
          </string-name>
          security
          <string-name>
            <surname>-</surname>
          </string-name>
          testing-guide/latest/4-Web_Application_Security_Testing/05- Authorization_Testing/05.2-Testing_for_OAuth_Client_Weaknesses.
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>C.</given-names>
            <surname>Bansal</surname>
          </string-name>
          ,
          <string-name>
            <given-names>K.</given-names>
            <surname>Bhargavan</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Delignat-Lavaud</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Maffeis</surname>
          </string-name>
          ,
          <article-title>Discovering concrete attacks on website authorization by formal analysis</article-title>
          , volume
          <volume>22</volume>
          of Journal of Computer Security (4th. ed.),
          <year>2014</year>
          , pp.
          <fpage>601</fpage>
          -
          <lpage>657</lpage>
          . doi:
          <volume>10</volume>
          .3233/JCS-140503.
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>M.</given-names>
            <surname>Ghasemisharif</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Ramesh</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Checkoway</surname>
          </string-name>
          ,
          <string-name>
            <given-names>C.</given-names>
            <surname>Kanich</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J.</given-names>
            <surname>Polakis</surname>
          </string-name>
          ,
          <string-name>
            <given-names>O Single</given-names>
            <surname>Sign-Off</surname>
          </string-name>
          ,
          <article-title>Where Art Thou? An Empirical Analysis of Single Sign-On Account Hijacking and Session Management on the Web</article-title>
          ,
          <source>in 27th USENIX Security Symposium (USENIX Security 18)</source>
          ,
          <year>2018</year>
          , pp.
          <fpage>1475</fpage>
          -
          <lpage>1492</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>T.</given-names>
            <surname>Lodderstedt</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J.</given-names>
            <surname>Bradley</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Labunets</surname>
          </string-name>
          , D. Fett, OAuth
          <volume>2</volume>
          .
          <article-title>0 Security Best Current Practice (draftietf-oauth-security-topics-16), Internet Engineering Task Force (IETF)</article-title>
          . URL: http://www.watersprings.org/pub/id/draft-ietf
          <article-title>-oauth-security-topics-06</article-title>
          .html.
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>Google</given-names>
            <surname>Internet Engineering Task</surname>
          </string-name>
          <article-title>Force (IETF), Proof Key for Code Exchange by OAuth Public Clients</article-title>
          . URL: https://datatracker.ietf.org/doc/html/rfc7636.
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>T.</given-names>
            <surname>Lodderstedt</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>McGloin</surname>
          </string-name>
          ,
          <string-name>
            <given-names>P.</given-names>
            <surname>Hunt</surname>
          </string-name>
          , RFC 6819:
          <article-title>OAuth 2.0 threat model and security considerations</article-title>
          ,
          <source>Internet Engineering Task Force (IETF)</source>
          ,
          <year>2013</year>
          , pp.
          <fpage>1</fpage>
          -
          <lpage>71</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <given-names>Android</given-names>
            <surname>Developers</surname>
          </string-name>
          <string-name>
            <surname>Documentation</surname>
          </string-name>
          ,
          <article-title>App security best practices</article-title>
          . URL: https://developer.android.com/topic/security/best-practices#
          <article-title>safe-data.</article-title>
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <given-names>Apple</given-names>
            <surname>Developers</surname>
          </string-name>
          <string-name>
            <surname>Documentation</surname>
          </string-name>
          ,
          <article-title>Encrypting Your App's Files. Protect the user's data in iOS by encrypting it on disk</article-title>
          . URL: https://developer.apple.com/documentation/uikit/protecting_
          <article-title>the_user_s_privacy/ encrypting_your_app_s_files.</article-title>
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          [10]
          <string-name>
            <given-names>Mozilla</given-names>
            <surname>Development</surname>
          </string-name>
          <string-name>
            <surname>Documentation</surname>
          </string-name>
          , Window.localStorage. URL: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage.
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          [11]
          <string-name>
            <given-names>OWASP</given-names>
            <surname>Community</surname>
          </string-name>
          ,
          <article-title>Cross Site Scripting (XSS)</article-title>
          . URL: https://owasp.org/www-community/attacks/xss/.
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          [12]
          <string-name>
            <given-names>Mozilla</given-names>
            <surname>Development</surname>
          </string-name>
          <string-name>
            <surname>Documentation</surname>
          </string-name>
          ,
          <article-title>Using HTTP cookies</article-title>
          . URL: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#security.
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          [13]
          <string-name>
            <given-names>Mozilla</given-names>
            <surname>Development</surname>
          </string-name>
          <string-name>
            <surname>Documentation</surname>
          </string-name>
          ,
          <article-title>Same Site cookies</article-title>
          . URL: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite.
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          [14]
          <string-name>
            <surname>Duende</surname>
            <given-names>Software</given-names>
          </string-name>
          ,
          <article-title>BFF Security Framework</article-title>
          . URL: https://docs.duendesoftware.com/identityserver/v5/bff/.
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          [15]
          <string-name>
            <surname>Microsoft</surname>
            <given-names>Documentation</given-names>
          </string-name>
          ,
          <string-name>
            <given-names>ASP.NET</given-names>
            <surname>Core</surname>
          </string-name>
          <article-title>Blazor</article-title>
          . URL: https://docs.microsoft.com/en-us/aspnet/core/blazor/?
          <source>view=aspnetcore-6</source>
          .0.
        </mixed-citation>
      </ref>
      <ref id="ref16">
        <mixed-citation>
          [16]
          <string-name>
            <given-names>A.</given-names>
            <surname>Chiarelli</surname>
          </string-name>
          ,
          <article-title>Building a Reverse Proxy in</article-title>
          .NET Core,
          <article-title>Auth0 Blog</article-title>
          . URL: https://auth0.com/blog/building
          <article-title>-a-reverse-proxy-in-dot-net-core/.</article-title>
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>