Skip to content

Commit

Permalink
Adding frontend app security guide
Browse files Browse the repository at this point in the history
  • Loading branch information
Sagara Gunathunga committed Dec 10, 2024
1 parent 38fb5f2 commit 7305c95
Show file tree
Hide file tree
Showing 25 changed files with 605 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions en/asgardeo/docs/complete-guides/fesecurity/csrf.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
template: templates/complete-guide.html
heading: Cross-Site Request Forgery (CSRF)
read_time: 2 mins
---

Cross-Site Request Forgery (CSRF) is an attack where an attacker tricks a user into performing unwanted actions on a web application where they are authenticated. This can lead to unauthorized actions being executed on behalf of the user, such as changing account details or making transactions.


![CSRF Attack Flow]({{base_path}}/complete-guides/fesecurity/assets/img/image12.png){: width="800" style="display: block; margin: 0;"}


CSRF exploits the trust that a web application has in the user's browser. If an application relies solely on cookies for authentication, an attacker can craft a request to the application from a different site, using the authenticated user's credentials to perform malicious actions.


To mitigate CSRF attacks:

1. Include a unique, unpredictable token in each request, also referred to as CSRF token. The server should validate this token to ensure the request is legitimate.
2. Set cookies with the SameSite attribute to Strict or Lax to prevent them from being sent in cross-site requests.
89 changes: 89 additions & 0 deletions en/asgardeo/docs/complete-guides/fesecurity/insecure-tokens.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
template: templates/complete-guide.html
heading: Insecure token handling
read_time: 2 min
---

When handling tokens such as the ID tokens and access tokens that we looked at in the previous section, there’s a risk of manipulation, such as replaying or tampering with a JWT token to elevate privileges or exploiting JWT invalidation. Due to this reason, it’s important to validate the ID token before using any information from it or storing it in the browser. Let’s look at how you can validate the ID token here because we use the ID token to establish the logged-in user context at the application level.

The ID token is a JWT (JSON Web Token) consisting of a header, payload, and signature, each encoded in Base64 and separated by dots. Here's an example of a decoded JWT token:




```json

{
"x5t": "C2wu7Amo4wsyJgLt5Td1l7dpztc",
"kid": "OTMyNmUwMjAxNWE0ODFiZTI5NzIxYTJhOTgxYTI4NjA4ZmUzNWUyZDhlNWI4MzQ3ZWU5OTUxYTU3YTczNjcxMA_RS256",
"alg": "RS256"
}
{
...
"iss": "https://api.asgardeo.io/t/mifrazmurthaja/oauth2/token",
"sid": "eefd4513-e01c-44a3-ae8b-e59cc11c64e1",
"aud": "sq4ktPY4lnEDBj8u5kImfHi4nSca",
"nbf": 1724261085,
"azp": "sq4ktPY4lnEDBj8u5kImfHi4nSca",
"exp": 1724264685,
"iat": 1724261085,
...
}
{
<SIGNATURE>
}

```

The header typically contains certificate information and the signature algorithm, while the payload includes user attributes and other crucial data. To validate an ID token,

1. **Validate the signature of the ID token.**
2. **Verify key attributes such as issuer (iss), audience (aud), issued-at time (iat), and expiration time (exp).**

Refer to the Validate ID Tokens [documentation](https://wso2.com/asgardeo/docs/guides/authentication/oidc/validate-id-tokens){:target="_blank"} for more details on these attributes and the validation process.

Again you don’t need to attend the token validation by yourself, following the security best practices, the Asgardeo SDK enables ID token validation by default, using the JWKS (JSON Web Key Set) endpoint of Asgardeo to validate the signature. The SDK constructs the JWKS and other necessary endpoints based on the baseUrl, so providing the baseUrl is typically sufficient. To give you an idea about what happens behind the scenes, the Asgardeo React SDK retrieves the public key of your Asgardeo organization through the JWKS endpoint and uses it to verify whether the token has been signed by the private key of your Asgardeo organization. If required, you can modify the JWKS endpoint and other parameters.

```javascript title="src/main.jsx" hl_lines="9-11"

import { AuthProvider } from "@asgardeo/auth-react";

const authConfig = {
clientID: "YOUR_CLIENT_ID",
signInRedirectURL: "http://localhost:3000",
signOutRedirectURL: "http://localhost:3000",
baseUrl: "https://api.asgardeo.io/t/{org_name}",
scope: [ "openid","profile"],
endpoints: {jwksUri: "https://api.asgardeo.io/t/{org_name}/oauth2/token"}
validateIDToken: true,
clockTolerance: 60,
...
};


```

The Asgardeo React SDK also validates other attributes such as the issuer and expiration period, with a default clock tolerance of 60 seconds.

Once you have validated the ID token and the access token received from the IdP, it's crucial to store them securely in the browser making sure the token can not be stolen from the storage to maintain the user state.

There are several storage mechanisms available in the browser, such as Session Storage, Local Storage, Web Workers, and Browser Memory. By default, the Asgardeo SDK stores session information, including the access token, in Session Storage. However, this can be configured as per your requirements. Here is an example using Asgardeo React SDK.

```javascript title="src/main.jsx" hl_lines="9"
import { AuthProvider } from "@asgardeo/auth-react";

const authConfig = {
clientID: "YOUR_CLIENT_ID",
signInRedirectURL: "http://localhost:3000",
signOutRedirectURL: "http://localhost:3000",
baseUrl: "https://api.asgardeo.io/t/{org_name}",
scope: [ "openid","profile"],
storage: "sessionStorage"
...
};



```

The available storage options of Asgardeo React SDK includes localStorage, sessionStorage, webWorker, and browserMemory. WebWorker is the recommended storage option as it operates in a separate thread, providing better security by isolating the stored data from the main browser thread. This isolation makes it less vulnerable to cross-site scripting (XSS) attacks. However, the downside is that WebWorker storage is cleared when the page is reloaded, meaning the data doesn't persist across page reloads or browser sessions. As a result, the SDK will initiate a new authentication request to the IDP every time the page reloads. You may analyze the pros and cons of each storage type to determine the most suitable option for storing session information, including the access token. Striking a balance between user experience and security based on your application's needs is essential.
58 changes: 58 additions & 0 deletions en/asgardeo/docs/complete-guides/fesecurity/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
template: templates/complete-guide.html
heading: Introduction
read_time: 2 mins
---

## Securing Frontend Applications
Are you a front-end developer working with React, Angular, Vue or other JavaScript frameworks? If so, you know that implementing user login functionality is essential—not only to meet business requirements but also to ensure the security and compliance of your application. However, frontend applications face unique security challenges that require careful attention to safeguard user data and maintain trust. In this guide, we will explore key security concerns specific to front-end applications—particularly those built with React—and discuss practical strategies and best practices to address these risks effectively.




## Learning objectives

In this guide, you will:

* In-app vs IdP-based login
* Public clients
* Unverified tokens
* Insecure tokens
* Weak access control
* Unauthorized privilege gain
* Unauthorized account access
* Weak Multi-factor authentication
* Partial user logouts
* Product misconfiguration
* Outdated SDKs
* Cross-Site Scripting (XSS)
* Cross-Site Request Forgery (CSRF)



!!! tip "Tip"

If you're a **React developer**, check out these guides to learn how to easily add user login functionality to your React applications.

- [{{product_name}} React Quickstart Guide]({{base_path}}/quick-starts/react/)

- [{{product_name}} React Complete Guide]({{base_path}}/complete-guides/react/introduction/)

!!! tip "Tip"

If you're a **Angular developer**, check out these guides to learn how to easily add user login functionality to your React applications.

- [{{product_name}} React Quickstart Guide]({{base_path}}/quick-starts/angular/)

- [{{product_name}} React Complete Guide]({{base_path}}/complete-guides/angular/introduction/)











29 changes: 29 additions & 0 deletions en/asgardeo/docs/complete-guides/fesecurity/login-options.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
template: templates/complete-guide.html
heading: In-app vs IdP-based login
read_time: 30 secs
---

## In-app vs IdP-based login

Before we move further, let’s briefly look at two main options available for you to implement user login in your frontend app:

1. **Build In-app login:** This approach involves creating your own login mechanism, typically requiring you to store usernames and passwords in a database. While this may seem simple at first, adding features like multi-factor authentication (MFA), conditional logic, and account recovery can significantly increase complexity. Over time, you might find yourself building an entire Identity Provider (IdP), which can divert your focus from the core business requirements of your app.

![In-app login]({{base_path}}/complete-guides/fesecurity/assets/img/image1.png){: width="550" style="display: block; margin: 0;"}

2. **Integrate with an Identity Provider (IdP):** This option involves integrating your frontend app with an IdP, which can be deployed on your infrastructure or accessed as a cloud service. By using open standards like SAML 2.0 and OpenID Connect (OIDC), you can delegate authentication and authorization responsibilities to the IDP, thereby improving the scalability and flexibility of your authentication flow.

![In-app login]({{base_path}}/complete-guides/fesecurity/assets/img/image2.png){: width="800" style="display: block; margin: 0;"}

In this guide, we assume you have integrated your frontend app with an IdP using the OIDC protocol for user login. You can use a cloud IdP such as Asgardeo as the IdP or any OIDC-supported IdP such as WSO2 Identity Server. Integrating your frontend app with an IdP typically involves two main steps:

1. Add the OIDC SDK as a dependency to your app to simplify handling OIDC request-response flows and tokens. While you could implement OIDC flows on your own, using the SDK saves time and ensures you’re following the best practices. Although the security implications and solutions are common across all frontend technologies, this guide presents examples from [Asgardeo React SDK](https://wso2.com/identity-and-access-management/react/){:target="_blank"}.

2. Register your app with an Identity Provider (IdP) as a Relying Party (RP) and obtain the necessary credentials to integrate your app with the IdP. In Asgardeo you can achieve this by creating an application in the console.


For this guide, we'll use a sample application, [asgardeo-react-b2c-sample-app](https://github.com/wso2/asgardeo-react-b2c-sample-app?tab=readme-ov-file){:target="_blank"}. With Asgardeo successfully integrated, you should now have working login functionality within your application.

Now, let's discuss the security concerns present in the application and explore how to effectively mitigate them.

25 changes: 25 additions & 0 deletions en/asgardeo/docs/complete-guides/fesecurity/misconfiguration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
template: templates/complete-guide.html
heading: Product misconfiguration
read_time: 2 mins
---

During the development phase, applications often include debug logs in the browser console, use hardcoded values, or retain test configurations. These practices, while useful for debugging, can expose sensitive information or introduce security vulnerabilities if left in the production environment.


The SDKs are designed to be production-ready out of the box, requiring no additional changes. However, it's essential to review your application's design and code to ensure it's production-ready. This includes removing any debug logs from the browser console, eliminating hardcoded values, securing configurations, and conducting a thorough security audit to mitigate potential risks

Ensuring the ongoing security and efficiency of your application requires regular maintenance of the SDK and its components. Using outdated or vulnerable components can expose your application to security risks and hinder performance.


- **Vulnerable and Outdated Components:** Regularly check for SDK updates and other dependencies. Keeping components up to date minimizes security vulnerabilities. Tools like dependency checkers can help automate this process, ensuring that you’re always using the latest, most secure versions.

- **Minimization:** Remove any unused dependencies and code to reduce the attack surface of your application. This practice not only improves security but also enhances performance.

- **Continuous Review:** Incorporate a continuous review process into your CI/CD pipeline. This includes security testing, code quality checks, and dependency scanning to catch potential issues early and ensure that your application remains secure and efficient over time.

- **dditional Best Practices:** Beyond maintaining the SDK, ensure your application follows industry best practices. This includes implementing secure coding practices, using strong encryption methods, regularly conducting security audits, and ensuring that your CI/CD pipeline is secure and resilient against threats.

By continuously maintaining the SDK and adhering to these best practices, you can ensure that your application remains secure, performant, and ready for production.


29 changes: 29 additions & 0 deletions en/asgardeo/docs/complete-guides/fesecurity/next-steps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
template: templates/complete-guide.html
heading: Next Steps
read_time: 1 min
---

Now that your React application is secured with authentication features integrated, It is time to explore the additional features {{product_name}} offers to make the login flow more diverse and secure.

- [Multi factor authentication]({{base_path}}/guides/authentication/mfa/){:target="_blank"}
- [Passwordless authentication]({{base_path}}/guides/authentication/passwordless-login/){:target="_blank"}
- [Self registration]({{base_path}}/guides/user-accounts/configure-self-registration/){:target="_blank"}
- [Login UI customization]({{base_path}}/guides/branding/){:target="_blank"}


!!! tip "Tip"

If you're a **React developer**, check out these guides to learn how to easily add user login functionality to your React applications.

- [{{product_name}} React Quickstart Guide]({{base_path}}/quick-starts/react/)

- [{{product_name}} React Complete Guide]({{base_path}}/complete-guides/react/introduction/)

!!! tip "Tip"

If you're a **Angular developer**, check out these guides to learn how to easily add user login functionality to your React applications.

- [{{product_name}} React Quickstart Guide]({{base_path}}/quick-starts/angular/)

- [{{product_name}} React Complete Guide]({{base_path}}/complete-guides/angular/introduction/)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
template: templates/complete-guide.html
heading: Partial user logouts
read_time: 2 min
---

When a user logs out from a frontend application, it’s important to revoke the access token as soon as possible in addition to clearing the current user context at the frontend. The reason is that if the access token remains valid after logout, it could potentially be misused if intercepted, leading to unauthorized access. Additionally, the session identifier should not be reused after logout to prevent session hijacking, especially on shared devices.


{{product_name}} offers various types of [Token Binding]({{base_path}}/docs/references/app-settings/oidc-settings-for-app/#token-binding-type){:target="_blank"}, each designed to serve a specific purpose. For example, the "SSO-session" token binding ensures that tokens are linked to a particular session, preventing them from being misused in other contexts. For a more detailed explanation, you can refer to the OIDC Token Configurations.

When you create a Single-Page Application in {{product_name}}, the token binding type is set to SSO-session by default. This means that the access token is automatically revoked when the user logs out. You can verify and adjust this setting through the application configurations in the {{product_name}} Console.

Additionally, {{product_name}} doesn’t reuse session identifiers; instead, it generates a new session identifier for each new session, enhancing security.
Loading

0 comments on commit 7305c95

Please sign in to comment.