<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Web App Security - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Web App Security - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 24 May 2026 16:30:56 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/web-app-security/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up Social Media Web Authentication using Firebase ]]>
                </title>
                <description>
                    <![CDATA[ User authentication is extremely important in the context of web development. The way users log in affects their overall experience and engagement with an application. It also affects how they initially perceive it. Authentication techniques are cont... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/social-media-based-web-authentication-with-firebase/</link>
                <guid isPermaLink="false">66bb891dc32849d18c5cdca9</guid>
                
                    <category>
                        <![CDATA[ authentication ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Firebase ]]>
                    </category>
                
                    <category>
                        <![CDATA[ social media ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web App Security ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Jaja ]]>
                </dc:creator>
                <pubDate>Thu, 31 Aug 2023 00:12:32 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/08/Article-Cover--3.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>User authentication is extremely important in the context of web development. The way users log in affects their overall experience and engagement with an application. It also affects how they initially perceive it.</p>
<p>Authentication techniques are continually evolving as social media sites continue to grow in popularity. The ability to log into web apps using social network accounts is a helpful advance in this area.</p>
<p>This article discusses how you can enhance the user login process for web applications by employing social media authentication through Firebase. It goes into the benefits, setup methods, and integration approaches while offering helpful guidelines.</p>
<h2 id="heading-heres-what-well-cover">Here's what we'll cover:</h2>
<ol>
<li><a class="post-section-overview" href="#heading-why-use-social-media-authentication">Why Use Social Media Authentication?</a></li>
<li><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></li>
<li><a class="post-section-overview" href="#heading-what-is-firebase-and-why-use-it-for-authentication">What is Firebase and Why Use it for Authentication?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-set-up-firebase-for-social-media-authentication">How to Set Up Firebase for Social Media Authentication</a></li>
<li><a class="post-section-overview" href="#heading-how-to-set-up-your-react-app">How to Set Up Your React App</a></li>
<li><a class="post-section-overview" href="#heading-how-to-integrate-social-media-authentication-in-your-app">How to Integrate Social Media Authentication in Your App</a></li>
<li><a class="post-section-overview" href="#heading-striking-the-right-balance-offering-both-social-media-and-emailpassword-authentication">Offering Both Social Media and Email/Password Authentication</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ol>
<h2 id="heading-why-use-social-media-authentication">Why Use Social Media Authentication?</h2>
<p>I'm sure you've grown weary of the usual username-password routine when logging into a new platform. It often entails creating a new password on the spot or resorting to insecure password conventions that could grant unauthorized access to your many accounts.</p>
<p>Fortunately, social media authentication offers some advantages:</p>
<ol>
<li>Effortless User Experience: Social media login choices simplify the registration process, making it convenient for users to initiate their app usage.</li>
<li>Heightened Security: Social media platforms implement strong security measures that can bolster the safety of your app's users.</li>
<li>Elimination of Password Hassles: Through social media authentication, users are relieved from the burden of remembering numerous passwords, reducing the inconvenience of managing credentials.</li>
<li>Reduced Account Abandonment: Social media login prompts users to join and interact with your app, minimizing the chances of them leaving the registration process unfinished.</li>
<li>Access to Trustworthy User Information: Social media platforms provide substantial user information, which can be harnessed to personalize the experience offered by your app.</li>
<li>Streamlined Account Recovery: In instances of forgotten passwords, social media authentication presents a straightforward approach for users to regain entry to their accounts.</li>
</ol>
<p>In summary, social media authentication offers a convenient and secure method for users to join and use your app. It leads to an improved user experience, and decreased account abandonment, and grants you access to valuable user insights.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>This article is intended for those with a solid grasp of the following concepts:</p>
<ul>
<li>HTML, CSS, and JavaScript</li>
<li>React and React Routing</li>
<li>Fundamental familiarity with using Firebase</li>
</ul>
<h2 id="heading-what-is-firebase-and-why-use-it-for-authentication">What is Firebase and Why Use it for Authentication?</h2>
<p>Firebase serves as a comprehensive platform, providing developers with backend services and tools to create web and mobile applications. </p>
<p>One of its key offerings is an authentication service that streamlines the process of integrating authentication features into apps. </p>
<p>With <a target="_blank" href="https://firebase.google.com/">Firebase</a>, implementing authentication becomes more straightforward, thanks to its provision of pre-built user interface components, developer-friendly APIs, and support for various authentication methods.</p>
<h2 id="heading-how-to-set-up-firebase-for-social-media-authentication">How to Set Up Firebase for Social Media Authentication</h2>
<h3 id="heading-step-1-create-a-firebase-project">Step 1: Create a Firebase Project</h3>
<ol>
<li>Go to <a target="_blank" href="https://console.firebase.google.com/">the Firebase Console</a> and sign in with your Google account.</li>
<li>Click the "Add Project" button.</li>
<li>Enter a name for your project and select a location for your data storage.</li>
<li>Click the "Create" button.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Screenshot-2023-08-22-082447.png" alt="Image" width="600" height="400" loading="lazy">
<em>Firebase console homepage</em></p>
<h3 id="heading-step-2-register-a-web-app">Step 2: Register a Web app</h3>
<p>This feature enables you to register your web applications to access the features of Firebase via web apps.</p>
<ol>
<li>In the Firebase Console, click the "Web" (&lt;/&gt;) icon.</li>
<li>Click the "Add App" button.</li>
<li>Enter a name for your app and select the "Web" app type.</li>
<li>Click the "Register" button.</li>
</ol>
<p>After you have created a Firebase project and registered a web app, you can start using Firebase for social media authentication.</p>
<h3 id="heading-step-3-discover-social-media-sign-in-methods">Step 3: Discover Social Media Sign-In Methods</h3>
<p>To do this, once your project is created, you'll need to navigate to the "Authentication" section on the left-hand menu.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/2-Auth-side-bar-shown.png" alt="Image" width="600" height="400" loading="lazy">
<em>Showing the Authentication sidebar</em></p>
<p>Under the "Sign-in method" tab, you'll find a list of authentication providers from which you can choose one:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Screenshot-2023-08-22-082758.png" alt="Image" width="600" height="400" loading="lazy">
<em>Displaying various Authentication methods</em></p>
<h3 id="heading-step-4-configure-social-media-providers">Step 4: Configure Social Media Providers</h3>
<h4 id="heading-how-to-configure-google-auth">How to configure Google auth:</h4>
<p>To configure Google auth, simply add a support email, and you’re all set.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/google-enable.png" alt="Image" width="600" height="400" loading="lazy">
<em>Adding a support mail for google auth</em></p>
<h4 id="heading-how-to-configure-github-auth">How to configure GitHub auth:</h4>
<p>To configure GitHub auth, you'll need a Client ID and Client Secret. To get these, sign in to your <a target="_blank" href="https://github.com/">GitHub account</a> and go to Settings &gt; Developer settings.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/github--settings.png" alt="Image" width="600" height="400" loading="lazy">
<em>Github settings panel</em></p>
<p>Then, navigate to OAuth and create a new OAuth application.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Setting-up-Github-OAuth.png" alt="Image" width="600" height="400" loading="lazy">
<em>Creating a github OAuth application</em></p>
<p>In order to get the Authorization callback, go back to your Firebase console and copy the URL in the GitHub setup.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/github-callback-url.png" alt="Image" width="600" height="400" loading="lazy">
<em>GitHub callback URL</em></p>
<p>Note: To complete this process, you’d need to have your app already hosted or at least a URL to where your app is going to be hosted.</p>
<p>Next, you’ll be routed to a page where your app has been registered and you have your Client ID and Secret.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/3-Github-Client-ID-and-Secret-generated.png" alt="Image" width="600" height="400" loading="lazy">
<em>GitHub Client ID and secret Generated</em></p>
<p>Copy those details and use them to register GitHub as an auth service on Firebase.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/4-Filling-in-github-details-in-fb.png" alt="Image" width="600" height="400" loading="lazy">
<em>Filling GitHub details on Firebase</em></p>
<h4 id="heading-how-to-configure-twitter-auth">How to configure Twitter auth:</h4>
<p>Similar to Github, start by logging into your Twitter developer account. If you don’t have one, sign up with the <a target="_blank" href="https://developer.twitter.com/en/portal/petition/essential/basic-info">Twitter Developer Portal</a>. It looks something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Twitter-Developers-signup.png" alt="Image" width="600" height="400" loading="lazy">
<em>Twitter Developer Signup</em></p>
<p>After filling in the details, you’ll be routed to the homepage.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/5-twitter-dev-homepage.png" alt="Image" width="600" height="400" loading="lazy">
<em>Twitter Dev homepage</em></p>
<p>Click on your default app, and set up user authentication.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Twitter-user-auth-setup.png" alt="Image" width="600" height="400" loading="lazy">
<em>Twitter OAuth app setup</em></p>
<p>Don’t forget to get the callback URL from Firebase and set the Website URL to the URL where your app is hosted.</p>
<p>After setting it up, navigate to your project’s keys and tokens and generate new ones.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Screenshot-2023-08-25-164558.png" alt="Image" width="600" height="400" loading="lazy">
<em>Generating new App Key and Secret</em></p>
<p>Paste those details back in Firebase to set up Twitter auth. </p>
<p>And with that, your three social media platforms have be set up for authentication.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/All-auths-setup.png" alt="Image" width="600" height="400" loading="lazy">
<em>All Auth's set up</em></p>
<h2 id="heading-ia"> </h2>
<p>How to Set Up Your React App</p>
<p>Now we need to get your React app set up. You'll start by creating a new React app using <a target="_blank" href="https://vitejs.dev/guide/">Vite</a>.</p>
<p>Create a folder on your computer and open that folder with your preferred IDE. Open that IDE’s terminal and run this command:</p>
<pre><code class="lang-bash">npm create vite@latest
</code></pre>
<p>When the details load, select React and wait for the installation to complete.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Vite-React.png" alt="Image" width="600" height="400" loading="lazy">
<em>Creating a React App with Vite</em></p>
<p>You’ll be left with a handful of files and some boilerplate code that you can get rid of.</p>
<p>Next, run <code>npm run dev</code> in the terminal to start a development server on port <code>http://localhost:5173/</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Vit-setup.png" alt="Image" width="600" height="400" loading="lazy">
<em>React app running in browser</em></p>
<p>To use Firebase in your app, you must first define a Firebase config file. This file contains all the necessary data used to identify your Firebase app.</p>
<p>So create a folder in your <code>src</code> directory called <code>firebase</code>. Then nest a <code>config.js</code> file in that folder and paste the config file details from your Firebase console you saved earlier.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/6-firebase-config-in-vscode.png" alt="Image" width="600" height="400" loading="lazy">
<em>Firebase config details</em></p>
<p>Finally, install Firebase via your terminal to use its services in your app.</p>
<pre><code class="lang-bash">npm i firebase
</code></pre>
<h2 id="heading-how-to-integrate-social-media-authentication-in-your-app">How to Integrate Social Media Authentication in Your App</h2>
<p>Considering how large this section would be, it’ll be divided into several sub-sections.</p>
<ol>
<li>Setting up the UI logic for authentication</li>
<li>Setting up the Authentication logic</li>
<li>Implementing Global Authentication State</li>
<li>Creating a custom hook for Social Media Authentication</li>
<li>Creating Routes and Implementing Routing</li>
<li>Social Media Authentication</li>
<li>Route Guarding via the User State</li>
<li>Creating a useLogout hook</li>
<li>Testing the logout functionality</li>
</ol>
<h3 id="heading-how-to-set-up-the-ui-logic-for-authentication">How to set up the UI logic for authentication</h3>
<p>Create a folder (pages) in the <code>src</code> directory that houses the pages you want in your application.</p>
<p>For this implementation, there will be 2 files in the pages folder, <code>Auth.jsx</code> and <code>Home.jsx</code>. These files will act as the pages the user can see either when authenticated or not.</p>
<h3 id="heading-how-to-set-up-the-authentication-logic">How to set up the authentication logic</h3>
<p>Start by importing and initializing Firebase auth, as well as the social media platforms enabled on Firebase in your config.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> {
  getAuth,
  GoogleAuthProvider,
  GithubAuthProvider,
  TwitterAuthProvider,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"firebase/auth"</span>;

<span class="hljs-comment">// Initialize Firebase</span>
<span class="hljs-keyword">const</span> app = initializeApp(firebaseConfig);
<span class="hljs-keyword">const</span> auth = getAuth(app);

<span class="hljs-keyword">const</span> googleProvider = <span class="hljs-keyword">new</span> GoogleAuthProvider();
<span class="hljs-keyword">const</span> githubProvider = <span class="hljs-keyword">new</span> GithubAuthProvider();
<span class="hljs-keyword">const</span> twitterProvider = <span class="hljs-keyword">new</span> TwitterAuthProvider();
</code></pre>
<p>Then export these initialized functions to use them in other parts of your application.</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> { auth, googleProvider, githubProvider, twitterProvider };
</code></pre>
<h3 id="heading-how-to-implement-global-authentication-state">How to implement Global Authentication State</h3>
<p>To ensure a consistent authentication state throughout your application, consider using the React Context approach.</p>
<h4 id="heading-step-1-create-an-authcontext">Step 1: Create an AuthContext</h4>
<p>Start by generating a context folder within your src directory and then create an <code>AuthContext.jsx</code> file within it. In the <code>AuthContext</code> file, import essential hooks from React and Firebase.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { createContext, useReducer, useEffect, useContext } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { auth } <span class="hljs-keyword">from</span> <span class="hljs-string">"../firebase/config"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> AuthContext = createContext();
</code></pre>
<h4 id="heading-step-2-define-a-reducer-function">Step 2: Define a reducer function</h4>
<p>Construct a reducer function to manage state changes for authentication-related actions using the following code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> authReducer = <span class="hljs-function">(<span class="hljs-params">state, action</span>) =&gt;</span> {
  <span class="hljs-keyword">switch</span> (action.type) {
    <span class="hljs-comment">// When the action type is "LOGIN", update the state with the new user information</span>
    <span class="hljs-keyword">case</span> <span class="hljs-string">"LOGIN"</span>:
      <span class="hljs-keyword">return</span> { ...state, <span class="hljs-attr">user</span>: action.payload };

    <span class="hljs-comment">// When the action type is "LOGOUT", update the state to remove the user information</span>
    <span class="hljs-keyword">case</span> <span class="hljs-string">"LOGOUT"</span>:
      <span class="hljs-keyword">return</span> { ...state, <span class="hljs-attr">user</span>: <span class="hljs-literal">null</span> };

    <span class="hljs-comment">// When the action type is "AUTH_IS_READY", update the state with user information and</span>
    <span class="hljs-comment">// set a state to indicate that the authentication process is complete</span>
    <span class="hljs-keyword">case</span> <span class="hljs-string">"AUTH_IS_READY"</span>:
      <span class="hljs-keyword">return</span> { <span class="hljs-attr">user</span>: action.payload, <span class="hljs-attr">authIsReady</span>: <span class="hljs-literal">true</span> };

    <span class="hljs-comment">// For any other action type, return the current state without any changes</span>
    <span class="hljs-keyword">default</span>:
      <span class="hljs-keyword">return</span> state;
  }
};
</code></pre>
<h4 id="heading-step-3-create-authcontextprovider-component">Step 3: Create AuthContextProvider Component</h4>
<p>Create a provider component that wraps your entire App component, using the reducer for authentication state management.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useEffect, useReducer } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { onAuthStateChanged } <span class="hljs-keyword">from</span> <span class="hljs-string">"firebase/auth"</span>; 


<span class="hljs-comment">// Authentication context provider component</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> AuthContextProvider = <span class="hljs-function">(<span class="hljs-params">{ children }</span>) =&gt;</span> {
  <span class="hljs-comment">// Initialize authentication state using a reducer</span>
  <span class="hljs-keyword">const</span> [state, dispatch] = useReducer(authReducer, {
    <span class="hljs-attr">user</span>: <span class="hljs-literal">null</span>,
    <span class="hljs-attr">authIsReady</span>: <span class="hljs-literal">false</span>,
  });

  <span class="hljs-comment">// Effect to determine initial authentication state and update context</span>
  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Subscribe to authentication state changes</span>
    <span class="hljs-keyword">const</span> unsub = onAuthStateChanged(auth, <span class="hljs-function">(<span class="hljs-params">user</span>) =&gt;</span> {
      <span class="hljs-comment">// Dispatch an action to update the state with the user information</span>
      dispatch({ <span class="hljs-attr">type</span>: <span class="hljs-string">"AUTH_IS_READY"</span>, <span class="hljs-attr">payload</span>: user });

      <span class="hljs-comment">// Unsubscribe to avoid further unnecessary updates</span>
      unsub(); <span class="hljs-comment">// Unsubscribe once the initial auth state is determined</span>
    });
  }, []);

  <span class="hljs-comment">// Provide authentication state and dispatch function to children components</span>
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">AuthContext.Provider</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">...state</span>, <span class="hljs-attr">dispatch</span> }}&gt;</span>
      {children}
    <span class="hljs-tag">&lt;/<span class="hljs-name">AuthContext.Provider</span>&gt;</span></span>
  );
};
</code></pre>
<h4 id="heading-step-4-implement-useauthcontext-custom-hook">Step 4: Implement useAuthContext custom hook</h4>
<p>You can simplify access to the authentication context with a custom hook, like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useContext } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-comment">// Custom hook to access the authentication context</span>
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">useAuthContext</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// Get the authentication context from the nearest AuthContextProvider</span>
  <span class="hljs-keyword">const</span> context = useContext(AuthContext);

  <span class="hljs-comment">// Check if the context was successfully obtained</span>
  <span class="hljs-keyword">if</span> (!context) {
    <span class="hljs-keyword">throw</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"useAuthContext must be used inside an AuthContextProvider"</span>);
  }

  <span class="hljs-comment">// Return the authentication context object for use in components</span>
  <span class="hljs-keyword">return</span> context;
}
</code></pre>
<h4 id="heading-how-to-integrating-the-authcontextprovider">How to integrating the AuthContextProvider</h4>
<p>Finally, integrate the <code>AuthContextProvider</code> into your main application setup</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">"react-dom/client"</span>;
<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">"./App.jsx"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"./index.css"</span>;
<span class="hljs-keyword">import</span> { AuthContextProvider } <span class="hljs-keyword">from</span> <span class="hljs-string">"./context/AuthContext.jsx"</span>;

ReactDOM.createRoot(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"root"</span>)).render(
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">React.StrictMode</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">AuthContextProvider</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">AuthContextProvider</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">React.StrictMode</span>&gt;</span></span>
);
</code></pre>
<p>With that, all parts of your app can access the context values from the <code>AuthContext</code>.</p>
<h3 id="heading-how-to-create-a-custom-hook-for-social-media-authentication">How to create a custom hook for Social Media Authentication</h3>
<p>Firebase authentication processes are similar in pattern and code structure. So it's a good idea to follow the DRY principle and create a utility hook that performs authentication for all social media platforms. This allows you to reuse the same code for each platform, making your code more efficient and easier to maintain.</p>
<p>Here is the step-by-step process to follow to create a custom hook for social media authentication.</p>
<h4 id="heading-step-1-create-the-custom-hook">Step 1: Create the custom hook</h4>
<p>In your source directory, establish a hooks folder and within it, create a file named <code>useSocialSignup.jsx</code>.</p>
<h4 id="heading-step-2-import-dependencies">Step 2: Import dependencies</h4>
<p>Import the necessary functions from React and Firebase into your <code>useSocialSignup</code> file.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { signInWithPopup } <span class="hljs-keyword">from</span> <span class="hljs-string">"firebase/auth"</span>;
<span class="hljs-keyword">import</span> { auth } <span class="hljs-keyword">from</span> <span class="hljs-string">"../firebase/config"</span>;
<span class="hljs-keyword">import</span> { useAuthContext } <span class="hljs-keyword">from</span> <span class="hljs-string">"../context/AuthContext"</span>;
</code></pre>
<h4 id="heading-step-3-define-the-hook-function">Step 3: Define the hook function</h4>
<p>Develop the <code>useSocialSignup</code> function, which takes a provider as a parameter and returns an object containing an error state, pending state, and the sign-in function for the social provider.</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> useSocialSignup = <span class="hljs-function">(<span class="hljs-params">provider</span>) =&gt;</span> {
  <span class="hljs-comment">// State variables to manage sign-up process</span>
  <span class="hljs-keyword">const</span> [error, setError] = useState(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [isPending, setIsPending] = useState(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> [isCancelled, setIsCancelled] = useState(<span class="hljs-literal">false</span>);

  <span class="hljs-comment">// Accessing the authentication context's dispatch function</span>
  <span class="hljs-keyword">const</span> { dispatch } = useAuthContext();

  <span class="hljs-comment">// Function to initiate the social sign-up process</span>
  <span class="hljs-keyword">const</span> signInWithSocial = <span class="hljs-keyword">async</span> () =&gt; {
    setError(<span class="hljs-literal">null</span>);
    setIsPending(<span class="hljs-literal">true</span>);

    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> signInWithPopup(auth, provider);

      dispatch({ <span class="hljs-attr">type</span>: <span class="hljs-string">"LOGIN"</span>, <span class="hljs-attr">payload</span>: res.user });

      <span class="hljs-keyword">if</span> (!isCancelled) {
        setIsPending(<span class="hljs-literal">false</span>);
        setError(<span class="hljs-literal">null</span>);
      }
    } <span class="hljs-keyword">catch</span> (err) {
      setError(err.message);
      setIsPending(<span class="hljs-literal">false</span>);
    }
  };

  <span class="hljs-comment">// Effect hook to set isCancelled to true when component unmounts</span>
  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> setIsCancelled(<span class="hljs-literal">true</span>);
  }, []);

  <span class="hljs-comment">// Return values and functions for component usage</span>
  <span class="hljs-keyword">return</span> { error, isPending, signInWithSocial };
};
</code></pre>
<p>This hook encapsulates the process of signing in with social providers. It manages error, pending, and cancellation states, interacts with Firebase authentication, and utilizes the authentication context to dispatch actions.</p>
<h3 id="heading-how-to-create-routes-and-implementing-routing">How to create routes and implementing routing</h3>
<p>To ensure smooth navigation and user experience, setting up routes becomes crucial after implementing authentication logic. These well-organized steps guide you through the process.</p>
<h4 id="heading-step-1-install-react-router-dom">Step 1: Install react-router-dom</h4>
<p>Install <a target="_blank" href="https://www.npmjs.com/package/react-router-dom">the react-router-dom package</a>, a popular choice for managing routing in React applications.</p>
<pre><code class="lang-bash">npm i react-router-dom
</code></pre>
<h4 id="heading-step-2-import-dependencies-1">Step 2: Import dependencies</h4>
<p>In your <code>App.jsx</code> file, import necessary components and functions for routing.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { BrowserRouter, Navigate, Route, Routes } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-router-dom"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"./App.css"</span>;
<span class="hljs-keyword">import</span> Home <span class="hljs-keyword">from</span> <span class="hljs-string">"./pages/Home"</span>;
<span class="hljs-keyword">import</span> Auth <span class="hljs-keyword">from</span> <span class="hljs-string">"./pages/Auth"</span>;
</code></pre>
<h4 id="heading-step-3-define-routes">Step 3: Define routes</h4>
<p>Wrap your application content in a BrowserRouter component and use the Routes component to define your routes. Utilize the Route component to map each route path to its corresponding component.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">BrowserRouter</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Routes</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Home</span> /&gt;</span>} /&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/auth"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Auth</span> /&gt;</span>} /&gt;
      <span class="hljs-tag">&lt;/<span class="hljs-name">Routes</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">BrowserRouter</span>&gt;</span></span>
  );
}
</code></pre>
<p>At the moment, you can freely navigate between routes, like so:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Onauth-routing.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Moving between Routes without Auth</em></p>
<h3 id="heading-social-media-authentication">Social Media Authentication</h3>
<p>To ensure your efforts haven't been in vain, head over to the <code>Auth.jsx</code> to implement authentication.</p>
<h4 id="heading-step-1-import-dependencies">Step 1: Import dependencies</h4>
<p>In your <code>Auth.jsx</code> file, start by importing necessary providers, context, and the custom signup hook.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> {
  googleProvider,
  twitterProvider,
  githubProvider,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"../firebase/config"</span>;
<span class="hljs-keyword">import</span> { useSocialSignup } <span class="hljs-keyword">from</span> <span class="hljs-string">"../hooks/useSocialSignup"</span>;
<span class="hljs-keyword">import</span> {useEffect} <span class="hljs-keyword">from</span> ‘react’

<span class="hljs-keyword">import</span> {useAuthContext} <span class="hljs-keyword">from</span> “../context/AuthContext”
</code></pre>
<h4 id="heading-step-2-create-instances-of-the-hook">Step 2: Create instances of the hook</h4>
<p>Create instances of the <code>useSocialSignup</code> custom hook for each authentication provider.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> google = useSocialSignup(googleProvider);
<span class="hljs-keyword">const</span> twitter = useSocialSignup(twitterProvider);
<span class="hljs-keyword">const</span> github = useSocialSignup(githubProvider);
</code></pre>
<h4 id="heading-step-3-add-buttons-for-social-sign-up">Step 3: Add buttons for social sign-up</h4>
<p>Create buttons for each social sign-up option (Google, Twitter, GitHub) and attach onClick event handlers to call the <code>signInWithSocial</code> function from the respective hook.</p>
<pre><code class="lang-js"><span class="hljs-keyword">return</span> (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"utility__page"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Welcome to my Auth Page<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{google.signInWithSocial}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{GoogleIcon}</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">""</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Google<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{twitter.signInWithSocial}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{TwitterIcon}</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">""</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Twitter<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{github.signInWithSocial}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{GithubIcon}</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">""</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>GitHub<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
);
</code></pre>
<h4 id="heading-step-4-apply-styling">Step 4: Apply styling</h4>
<p>You can use the provided CSS below to style your components for a clean and organized appearance.</p>
<pre><code class="lang-css">* {
  <span class="hljs-attribute">box-sizing</span>: border-box;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
}

<span class="hljs-selector-tag">html</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">62.5%</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#121212</span>;
}

<span class="hljs-selector-class">.utility__page</span> {
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">100vh</span>;
  <span class="hljs-attribute">justify-content</span>: center;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">font-family</span>: <span class="hljs-string">"Segoe UI"</span>, Tahoma, Geneva, Verdana, sans-serif;
  <span class="hljs-attribute">row-gap</span>: <span class="hljs-number">2rem</span>;
  <span class="hljs-attribute">flex-direction</span>: column;
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#e2dbd9</span>;
}

<span class="hljs-selector-tag">h1</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">5rem</span>;
}

<span class="hljs-selector-tag">button</span> {
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">1rem</span> <span class="hljs-number">4rem</span>;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">2rem</span>;
  <span class="hljs-attribute">border</span>: none;
  <span class="hljs-attribute">cursor</span>: pointer;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">5px</span>;
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">justify-content</span>: center;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">gap</span>: <span class="hljs-number">1rem</span>;
}

<span class="hljs-selector-tag">button</span> <span class="hljs-selector-tag">img</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">20px</span>;
}

<span class="hljs-selector-class">.user</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">3rem</span>;
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">column-gap</span>: <span class="hljs-number">1rem</span>;
}

<span class="hljs-selector-class">.logout</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-built_in">rgb</span>(<span class="hljs-number">208</span>, <span class="hljs-number">84</span>, <span class="hljs-number">84</span>);
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
}

<span class="hljs-selector-class">.profile_img</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">5rem</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">5rem</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">50%</span>;
}
</code></pre>
<p>At the moment, your auth page looks something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Auth-page.png" alt="Image" width="600" height="400" loading="lazy">
<em>Auth page after applying styling</em></p>
<h4 id="heading-step-5-test-the-authentication">Step 5: Test the authentication</h4>
<p>To test authentication, import the user from your <code>AuthContext</code> and log it to the console using a <code>useEffect</code>.</p>
<pre><code class="lang-js">  <span class="hljs-keyword">const</span> { user } = useAuthContext();
  useEffect(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(user), [user]);
</code></pre>
<p>Testing the auth now gives the following:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/first-login-giffy.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Authentication confirmed in the console via the user object</em></p>
<p>As you can see, you’ve successfully logged a user in using Social Media Authentication. Kudos!</p>
<p>To confirm, head over to your Firebase auth page and check for valid users.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Valid-users-check.png" alt="Image" width="600" height="400" loading="lazy">
<em>Confirming signed up user on Firebase</em></p>
<p>Feel free to try other login methods as they all work the same.</p>
<h3 id="heading-route-gaurding-via-the-user-state">Route Gaurding via the User State</h3>
<p>To prevent unauthorized access, set up route guards that check the user's authentication state in your <code>App.jsx</code> file.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { user, authIsReady } = useAuthContext();

<span class="hljs-keyword">if</span> (!authIsReady) {
  <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; <span class="hljs-comment">// Return null while waiting for authIsReady</span>
}

<span class="hljs-keyword">return</span> (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">BrowserRouter</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Routes</span>&gt;</span>
      {user ? (
        <span class="hljs-tag">&lt;&gt;</span>
          {/* Authenticated routes */}
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Home</span> /&gt;</span>} /&gt;
          {/* Route guards */}
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"*"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Navigate</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/"</span> /&gt;</span>} /&gt;
        <span class="hljs-tag">&lt;/&gt;</span>
      ) : (
        <span class="hljs-tag">&lt;&gt;</span>
          {/* Authentication routes */}
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/auth"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Auth</span> /&gt;</span>} /&gt;
          {/* Route guards */}
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"*"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Navigate</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/auth"</span> /&gt;</span>} /&gt;
        <span class="hljs-tag">&lt;/&gt;</span></span>
      )}
    &lt;/Routes&gt;
  &lt;/BrowserRouter&gt;
);
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/plain-home-page-after-auth.png" alt="Image" width="600" height="400" loading="lazy">
<em>Routed to home page after adding route guards</em></p>
<p>As you can see, you’ve been routed to the home page, and even if you attempt to go the auth page, you’d be routed back here.</p>
<h4 id="heading-how-to-customize-the-home-page">How to customize the home page</h4>
<p>For the home page, fetch the user's details and display them if a user is authenticated.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useAuthContext } <span class="hljs-keyword">from</span> <span class="hljs-string">"../context/AuthContext"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { user } = useAuthContext();
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"utility__page "</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span> Home Page<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      {user &amp;&amp; (
        <span class="hljs-tag">&lt;&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"user"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span> You<span class="hljs-symbol">&amp;apos;</span>re logged in as: <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>{user.displayName} <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"profile_img"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{user.photoURL}</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">""</span>/&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
         <span class="hljs-tag">&lt;/&gt;</span></span>
      )}
    &lt;/div&gt;
  );
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Auth-showing-details.png" alt="Image" width="600" height="400" loading="lazy">
<em>Home page showing custom user details</em></p>
<p>And voilà! You’ve been able to fetch some details about that user based on the info on the social media they used to log in.</p>
<h3 id="heading-how-to-create-a-uselogout-hook">How to create a useLogout hook</h3>
<p>The final step to complete your authentication process is to provide users with the ability to log out of your application. Here's how to create a useLogout hook:</p>
<h4 id="heading-step-1-create-the-hook">Step 1: Create the hook</h4>
<p>Create a new file called useLogout.jsx in your hooks folder. Import the necessary hooks and functions.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { auth } <span class="hljs-keyword">from</span> <span class="hljs-string">"../firebase/config"</span>;
<span class="hljs-keyword">import</span> { signOut } <span class="hljs-keyword">from</span> <span class="hljs-string">"firebase/auth"</span>;
<span class="hljs-keyword">import</span> { useAuthContext } <span class="hljs-keyword">from</span> <span class="hljs-string">"../context/AuthContext"</span>;
</code></pre>
<h4 id="heading-step-2-create-the-hook-states">Step 2: Create the hook states</h4>
<p>Create states to manage the logout process, including error, pending, and cancellation states.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Error state for potential errors during logout </span>
<span class="hljs-keyword">const</span> [error, setError] = useState(<span class="hljs-literal">null</span>); 
<span class="hljs-comment">// State to indicate if logout is in progress </span>
<span class="hljs-keyword">const</span> [isPending, setIsPending] = useState(<span class="hljs-literal">false</span>); 
<span class="hljs-comment">// State to track if the operation is cancelled</span>
<span class="hljs-keyword">const</span> [isCancelled, setIsCancelled] = useState(<span class="hljs-literal">false</span>);
</code></pre>
<h4 id="heading-step-3-extract-the-dispatch-function-from-the-authentication-context">Step 3: Extract the dispatch function from the authentication context</h4>
<p>This function will be used to indicate a logout action has been called:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { dispatch } = useAuthContext();
</code></pre>
<h4 id="heading-step-4-create-the-hook-logic">Step 4: Create the hook logic</h4>
<p>Use a try-catch block create the logic of logging a user out:</p>
<pre><code class="lang-js"><span class="hljs-keyword">try</span> { 
<span class="hljs-comment">// Initiating the logout using Firebase's signOut function </span>
    <span class="hljs-keyword">await</span> signOut(auth); 
    dispatch({ <span class="hljs-attr">type</span>: <span class="hljs-string">"LOGOUT"</span> }); <span class="hljs-comment">// Dispatching a LOGOUT action </span>
<span class="hljs-comment">// If the operation wasn't cancelled, reset pending state and error </span>
   <span class="hljs-keyword">if</span> (!isCancelled) { 
       setIsPending(<span class="hljs-literal">false</span>); <span class="hljs-comment">// Resetting isPending after the asynchronous call completes </span>
       setError(<span class="hljs-literal">null</span>); <span class="hljs-comment">// Clearing any error that might have occurred </span>
     } 
   } <span class="hljs-keyword">catch</span> (err) { 
      <span class="hljs-comment">// Handling logout error </span>
     <span class="hljs-keyword">if</span> (!isCancelled) { 
        <span class="hljs-built_in">console</span>.log(err.message); <span class="hljs-comment">// Logging the error message</span>
        setError(err.message); <span class="hljs-comment">// Setting the error state in case of an error </span>
        setIsPending(<span class="hljs-literal">false</span>); <span class="hljs-comment">// Resetting pending state if an error occurs </span>
   } 
}
</code></pre>
<h4 id="heading-step-5-how-to-handle-unmounting">Step 5: How to handle unmounting</h4>
<p>In the case where the component is unmounted (the page closes or there’s a route change), you’ll want to handle that occurrence to prevent errors.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Effect hook to set isCancelled to true when component unmounts</span>
   useEffect(<span class="hljs-function">() =&gt;</span> { 
       <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> setIsCancelled(<span class="hljs-literal">true</span>); <span class="hljs-comment">// The cleanup function runs when the component unmounts }, []);</span>
</code></pre>
<h4 id="heading-step-5-exporting-values">Step 5: Exporting values</h4>
<p>Return the relevant values and functions for other components to use.</p>
<pre><code class="lang-js"> <span class="hljs-keyword">return</span> { logout, error, isPending };
</code></pre>
<p>For ease of accesibility, here’s the full useLogout hook.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Importing necessary hooks and functions</span>
<span class="hljs-keyword">import</span> { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { auth } <span class="hljs-keyword">from</span> <span class="hljs-string">"../firebase/config"</span>; <span class="hljs-comment">// Importing Firebase auth instance</span>
<span class="hljs-keyword">import</span> { signOut } <span class="hljs-keyword">from</span> <span class="hljs-string">"firebase/auth"</span>; <span class="hljs-comment">// Importing signOut function from Firebase</span>
<span class="hljs-keyword">import</span> { useAuthContext } <span class="hljs-keyword">from</span> <span class="hljs-string">"../context/AuthContext"</span>; <span class="hljs-comment">// Importing the custom hook to access the authentication context</span>

<span class="hljs-comment">// Custom hook for handling user logout</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> useLogout = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-comment">// State variables to manage logout process</span>
  <span class="hljs-keyword">const</span> [error, setError] = useState(<span class="hljs-literal">null</span>); <span class="hljs-comment">// Error state for potential errors during logout</span>
  <span class="hljs-keyword">const</span> [isPending, setIsPending] = useState(<span class="hljs-literal">false</span>); <span class="hljs-comment">// State to indicate if logout is in progress</span>
  <span class="hljs-keyword">const</span> [isCancelled, setIsCancelled] = useState(<span class="hljs-literal">false</span>); <span class="hljs-comment">// State to track if the operation is cancelled</span>
  <span class="hljs-keyword">const</span> { dispatch } = useAuthContext(); <span class="hljs-comment">// Accessing the authentication context's dispatch function</span>

  <span class="hljs-comment">// Function to initiate the logout process</span>
  <span class="hljs-keyword">const</span> logout = <span class="hljs-keyword">async</span> () =&gt; {
    setError(<span class="hljs-literal">null</span>); <span class="hljs-comment">// Clearing any previous errors</span>
    setIsPending(<span class="hljs-literal">true</span>); <span class="hljs-comment">// Indicating that the logout process is in progress</span>

    <span class="hljs-keyword">try</span> {
      <span class="hljs-comment">// Initiating the logout using Firebase's signOut function</span>
      <span class="hljs-keyword">await</span> signOut(auth);
      dispatch({ <span class="hljs-attr">type</span>: <span class="hljs-string">"LOGOUT"</span> }); <span class="hljs-comment">// Dispatching a LOGOUT action</span>

      <span class="hljs-comment">// If the operation wasn't cancelled, reset pending state and error</span>
      <span class="hljs-keyword">if</span> (!isCancelled) {
        setIsPending(<span class="hljs-literal">false</span>); <span class="hljs-comment">// Resetting isPending after the asynchronous call completes</span>
        setError(<span class="hljs-literal">null</span>); <span class="hljs-comment">// Clearing any error that might have occurred</span>
      }
    } <span class="hljs-keyword">catch</span> (err) {
      <span class="hljs-comment">// Handling logout error</span>
      <span class="hljs-keyword">if</span> (!isCancelled) {
        <span class="hljs-built_in">console</span>.log(err.message); <span class="hljs-comment">// Logging the error message</span>
        setError(err.message); <span class="hljs-comment">// Setting the error state in case of an error</span>
        setIsPending(<span class="hljs-literal">false</span>); <span class="hljs-comment">// Resetting pending state if an error occurs</span>
      }
    }
  };

  <span class="hljs-comment">// Effect hook to set isCancelled to true when component unmounts</span>
  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> setIsCancelled(<span class="hljs-literal">true</span>); <span class="hljs-comment">// The cleanup function runs when the component unmounts</span>
  }, []);

  <span class="hljs-comment">// Returning the relevant values and functions for component usage</span>
  <span class="hljs-keyword">return</span> { logout, error, isPending };
};
</code></pre>
<h3 id="heading-how-to-test-the-logout-functionality">How to test the logout functionality</h3>
<p>In your Home.jsx component, import the useLogout hook and extract the logout function. Attach the logout function to a button's <code>onClick</code> event to enable users to log out.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useLogout } <span class="hljs-keyword">from</span> <span class="hljs-string">"../hooks/useLogout"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { user } = useAuthContext();
  <span class="hljs-keyword">const</span> { logout } = useLogout(); <span class="hljs-comment">//logout function extracted</span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"utility__page "</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span> Home Page<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      {user &amp;&amp; (
        <span class="hljs-tag">&lt;&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"user"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span> You<span class="hljs-symbol">&amp;apos;</span>re logged in as: <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>{user.displayName} <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"profile_img"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{user.photoURL}</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">""</span> /&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
           //logout function used
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"logout"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{logout}</span>&gt;</span>
             Log out
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/&gt;</span></span>
      )}
    &lt;/div&gt;
  );
}
</code></pre>
<p>At the moment, your home page looks like this;</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/before-logout.png" alt="Image" width="600" height="400" loading="lazy">
<em>Home page before logging the user out</em></p>
<p>Click on the button and log out the user.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/login-out-and-in.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Testing the log in and log out functionality</em></p>
<p>With that, your authentication process is completely set up, congrats!</p>
<h2 id="heading-striking-the-right-balance-offering-both-social-media-and-emailpassword-authentication">Striking the Right Balance: Offering Both Social Media and Email/Password Authentication</h2>
<p>User authentication is a key part of the user experience on any web app. Social media authentication can offer a streamlined experience and enhanced security, but it's important to strike a balance by also offering the option for email/password authentication. This ensures inclusivity, caters to various user preferences, and addresses privacy concerns. </p>
<p>By offering both options, you create a versatile and user-centric authentication process that contributes to a positive user experience.</p>
<p>An example of an ideal authentication page can be seen below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Final-signup-page.png" alt="Image" width="600" height="400" loading="lazy">
<em>Standard Auth Page</em></p>
<h2 id="heading-guidelines-for-building-auth-pages">Guidelines for Building Auth Pages</h2>
<p>It is important to apply some basics best practices when building authentication pages, such as:</p>
<ol>
<li>Showing all the possible ways a user can get authenticated in a clear and concise manner.</li>
<li>Using authentic company icons to build trust. You can find free company SVGs on sites like <a target="_blank" href="https://fontawesome.com/">Font Awesome</a>, <a target="_blank" href="https://fonts.google.com/icons">Google icons</a>, and so on.</li>
<li>Use intuitive icons to label inputs such as envelope for mail and padlock for password.</li>
<li>Address privacy concerns by clearly communicating how user data will be used and protected during the authentication process.</li>
</ol>
<p>For ease of accessibility, here’s a link to the <a target="_blank" href="https://github.com/Daiveedjay/OAuth-Article">repo</a>.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In conclusion, using social media login with Firebase is a smart strategy. It brings together user-friendliness, safety, and privacy. </p>
<p>By offering various ways to log in, websites can accommodate different user choices, be more inclusive, and adapt to new trends. </p>
<p>Balancing authentication options like this makes users happy and builds trust. This is important for creating modern websites and ensuring smooth, user-focused logins.</p>
<h3 id="heading-contact-information">Contact Information</h3>
<p>Want to connect or contact me? Feel free to hit me up on the following:</p>
<ul>
<li>Twitter / X : <a target="_blank" href="https://twitter.com/JajaDavid8">@jajadavid8</a></li>
<li>LinkedIn: <a target="_blank" href="https://www.linkedin.com/in/david-jaja-8084251b4/">David Jaja</a></li>
<li>Email: Jajadavidjid@gmail.com</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Best Application Security Tools in 2020 ]]>
                </title>
                <description>
                    <![CDATA[ Software has become more and more ubiquitous. Open source libraries are widely used as they make it easy for developers to focus on the core features of the applications they’re building. Using these open source libraries provides tremendous producti... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/best-application-security-tools-in-2020ed/</link>
                <guid isPermaLink="false">66bb524324c949cee2fb6bcf</guid>
                
                    <category>
                        <![CDATA[ Web App Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Application Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ry Vee ]]>
                </dc:creator>
                <pubDate>Tue, 08 Sep 2020 16:56:39 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/09/corinne-kutz-tMI2_-r5Nfo-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Software has become more and more ubiquitous. Open source libraries are widely used as they make it easy for developers to focus on the core features of the applications they’re building.</p>
<p>Using these open source libraries provides tremendous productivity benefits. However, it also comes with disadvantages – namely in relation to security.</p>
<p>Cyber-criminals and hackers have been increasingly exploiting vulnerabilities in applications and IT systems. It has, therefore, become more and more important to ensure that code bases minimize or totally eliminate vulnerabilities.</p>
<p>However, keeping tabs on all the vulnerabilities, let alone updated ones, in projects can be very daunting. That’s why in this article we’ll take a look at eight tools that automate the detection and fixing of vulnerable spots in a project.</p>
<h2 id="heading-deepscan">DeepScan</h2>
<p><img src="https://lh5.googleusercontent.com/vuWbsmQMINLuAr1tebYQarvIebIladiOhTOGjsTUl1RD9uSXvB8Q970XMd_6IEcQTy6ubG61E79EZGC9fVa-EzOryvnhhfUP652kJBGXYxpAE29S1Ax1gllq8CM1VaUwKA" alt="Image" width="1287" height="552" loading="lazy"></p>
<p>DeepScan is a tool that analyzes JavaScript and TypeScript code. At its core, it not only inspects for code quality à la ESLint, but it also employs data-flow analysis and looks into the execution flow. Errors and quality issues are detected even without running the code.</p>
<p>DeepScan works with most JavaScript libraries such as React and Vue.js.</p>
<p>Teams can simply integrate their projects’ GitHub repository with DeepScan. Every time a push is made into a repository, DeepScan provides a real time report on test results. </p>
<p>One of the best things about this is that code quality standards are more enforceable. DeepScan motivates teams to write quality code by grading the project as Poor, Normal, or Good.</p>
<h2 id="heading-sonarqube">SonarQube</h2>
<p><img src="https://lh3.googleusercontent.com/SURJlYBtjoi0RD-3HI9GyI0JhQqgcNO9JZQJJyRTyYmyI0IorGp3IwYTQQL51mEkfLMhYHchedXdNtI4bzkViT2cDVGwzLXa4s-jplyxMyup7e3GWpzuy0T_nCVKYbu2mg" alt="Image" width="1210" height="647" loading="lazy"></p>
<p>SonarQube is an open-source platform that continuously inspects a project for code quality, bugs, code-smells and even security vulnerabilities.</p>
<p>It's a tool written in Java but has the ability to analyze other languages through the use of plugins. </p>
<p>Unlike most of the others in this list, SonarQube isn’t integrated into a project as a simple GitHub extension. It needs to be installed in the local machine for you to be able to use it.</p>
<p>It works by receiving the project’s files as input and then making the necessary analysis. It then generates data based on the analysis, stores that data in a database, and displays it in a dashboard.</p>
<h2 id="heading-dependabot">Dependabot</h2>
<p><img src="https://lh6.googleusercontent.com/qXWWBNa5LZVuRQl442r-KrFOWbQNNWsJbjqDAt4tv-UjAVTgVmiQ6mdNR0-WbiYRfZhPVXStmA7OV8WHVDzd6tbzSu_4O4PE-tBMEKpHg7D5FEX_YpD_t-kWVjZhWdBX0A" alt="Image" width="1052" height="581" loading="lazy"></p>
<p>Dependabot is a tool you use inside of GitHub that automatically creates pull requests upon detection of vulnerabilities.</p>
<p>This tool performs scans on all of a repository’s dependency files and searches for outdated or insecure dependencies. It then generates a single pull request for each outdated or insecure dependency. The developer can then check those pull requests and merge as necessary.</p>
<p>The great thing about Dependabot is that it’s owned by GitHub so that it can be seamlessly integrated into any repository. It performs constant monitoring and quickly updates users when there's a new vulnerability.</p>
<p>It can be very chaotic to receive daily notifications, so users can configure the frequency that the tool performs scans and creates pull requests.</p>
<h2 id="heading-sourceclear">SourceClear</h2>
<p><img src="https://lh6.googleusercontent.com/j7uvCW3rdbFP5gwvZKZ8fq9vUCSmLnsPtKKixXa3ShyZMd5Nvzr3OfNwmPrfvliO70EN5sdCYd6L9rL4KN1F9KND3DHdfo2vkTOeQMtkKyUNoB0_wE1zQIjhhXPEXV6Yhg" alt="Image" width="1192" height="469" loading="lazy"></p>
<p>SourceClear is a tool that helps developers understand more about the open source libraries they are using. SourceClear provides information on those libraries such as who created them, what they do, and which dependencies of such libraries have vulnerabilities.</p>
<p>SourceClear meshes well with a developer’s workflow and provides real-time reports on open-source code risks. It has machine-learning tools that makes it possible to provide such detailed information for each library used.</p>
<p>One of its main features is the prioritization of vulnerabilities that are directly in the code’s execution path. This can reduce remediation time for big projects by up to 90%.</p>
<h2 id="heading-spotbugs">SpotBugs</h2>
<p><img src="https://lh5.googleusercontent.com/udDfNTSn2DTsmNOESuK_KFK7J1SVE1upA-2IfQxJ4dBTTf6VSzyca1rGjD_PVsfQov2SW3f5c4Yq-ai7ZpAeA8ZafzbeATaBGnSYAWMLb-_A1RHZFe5q_o06ZrBtPFXxVw" alt="Image" width="1034" height="408" loading="lazy"></p>
<p>SpotBugs, a successor to FindBugs, is a static code analyzer for Java code bases. It can either be used as a stand-alone tool or integrated to other platforms/tools.</p>
<p>Most Java programs compile cleanly but are still buggy. Compilation captures mostly only syntax and references errors, among others. Usage of static analysis tools such as SpotBugs provides a more comprehensive solution in catching bugs and even vulnerabilities.</p>
<p>SpotBugs inspects Java bytecode (not the source code) and checks for bug patterns. It then classifies errors or potential errors based on how severe they are: Of Concern, Troubling, Scary, Scariest.</p>
<p>This tool is very good at identifying bug patterns (over 400).</p>
<h2 id="heading-arxan-application-protection">Arxan Application Protection</h2>
<p><img src="https://lh4.googleusercontent.com/T0tufco3sAC5q_EG_CfcKKXMS0XGyY-RQXrr52YSD_F51vtGuuAQDNnq4bxoIsOGFDowj0SmbE_5nagoFH86k8j_BAz5-kYBKu_48JEezinD6PbhAD7NjV1L-t-SGY7iLQ" alt="Image" width="1169" height="422" loading="lazy"></p>
<p>Arxan Application Protection is a total solution to “protect apps inside and out”. This tool’s main selling point - Protecting applications against reverse engineering.</p>
<p>A lot of today’s attacks such as <a target="_blank" href="https://en.wikipedia.org/wiki/Clickjacking">clickjacking</a> are engineered by cyber-criminals through hacking the app’s binary code and then creating a replica app. Users are then lured into trusting this fake app and giving away their data such as banking passwords.</p>
<p>Arxan protects an application from such attacks by “hardening” the application’s code by inserting “code guards” into them. These code guards are tiny security units which protect the application and each other against compromise and they detect attacks at runtime.</p>
<h2 id="heading-gitlab">GitLab</h2>
<p><img src="https://lh3.googleusercontent.com/eXpuwOc4PRGblwLr6qMK42LKuUv59By2wzb6ldd9h5PSUi_1_NSLK3M1L5qWiUh8OnNQSDgPVrPmqunzovYwa09Uu1fFPqiddGZEng6XYZ3YyLm0uHJy0McSwk8x4-YQtQ" alt="Image" width="1238" height="665" loading="lazy"></p>
<p>One of GitLab’s core value propositions to developers is that it is one of the most exquisite devops tools out there. Added to this is GitLab’s focus on secure deployment.</p>
<p>The platform has incorporated security in its already loaded devops arsenal. Developers can focus on coding while being confident that any security vulnerability will quickly be detected. This makes it very pleasant to use, as no additional tool or integration is necessary.</p>
<p>It employs what it calls the Secure Stage where all the security parts of devops are performed. This “stage” has a goal of identifying proactively any vulnerabilities before they can be exploited in production code.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Each tool has its own pros and cons and the choice to use one over the other depends on the particular taste of the developer. Often, some tools can even be used together. </p>
<p>The bottom line is that nowadays we are more equipped to handle security issues before they become big problems in our application projects.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ SQL injection and XSS: what white hat hackers know about trusting user input ]]>
                </title>
                <description>
                    <![CDATA[ Software developers have a lot on their minds. There are are myriad of questions to ask when it comes to creating a website or application: What technologies will we use? How will the architecture be set up? What functions do we need? What will the U... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/sql-injection-and-xss-what-white-hat-hackers-know-about-trusting-user-input/</link>
                <guid isPermaLink="false">66bd8f84ecf2a326d61fea94</guid>
                
                    <category>
                        <![CDATA[ Application Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ bug bounty ]]>
                    </category>
                
                    <category>
                        <![CDATA[ cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ethical Hacking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ information security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #infosec ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web App Security ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Victoria Drake ]]>
                </dc:creator>
                <pubDate>Tue, 03 Sep 2019 12:34:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/09/cover-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Software developers have a lot on their minds. There are are myriad of questions to ask when it comes to creating a website or application: <em>What technologies will we use? How will the architecture be set up? What functions do we need? What will the UI look like?</em> </p>
<p>Especially in a software market where shipping new apps seems more like a race for reputation than a well-considered process, one of the most important questions often falls to the bottom of the “Urgent” column: how will our product be secured?</p>
<p>If you’re using a robust, open-source framework for building your product (and if one is applicable and available, why wouldn’t you?) then some basic security concerns, like CSRF tokens and password encryption, may already be handled for you. </p>
<p>Still, fast-moving developers would be well served to brush up on their knowledge of common threats and pitfalls, if only to avoid some embarrassing rookie mistakes. Usually, the weakest point in the security of your software is <em>you.</em></p>
<p>I’ve recently become more interested in information security in general, and practicing ethical hacking in particular. An ethical hacker, sometimes called a “white hat” hacker, and sometimes just a “hacker,” is someone who searches for possible security vulnerabilities and responsibly (privately) reports them to project owners. </p>
<p>By contrast, a malicious or “black hat” hacker, also called a “cracker,” is someone who exploits these vulnerabilities for amusement or personal gain. </p>
<p>Both white hat and black hat hackers might use the same tools and resources, and generally try to get into places they aren’t supposed to be. But white hats do this with permission, and with the intention of fortifying defences instead of destroying them. Black hats are the bad guys.</p>
<p>When it comes to learning how to find security vulnerabilities, it should come as no surprise that I’ve been devouring whatever information I can get my hands on. This post is a distillation of some key areas that are specifically helpful to developers when handling user input. These lessons have been collectively gleaned from these excellent resources:</p>
<ul>
<li>The <a target="_blank" href="https://www.owasp.org/index.php/Main_Page">Open Web Application Security Project</a> guides</li>
<li>The Hacker101 playlist from <a target="_blank" href="https://www.youtube.com/channel/UCsgzmECky2Q9lQMWzDwMhYw/">HackerOne’s YouTube channel</a></li>
<li><a target="_blank" href="https://leanpub.com/web-hacking-101">Web Hacking 101</a> by Peter Yaworski</li>
<li><a target="_blank" href="https://brutelogic.com.br/blog/">Brute Logic’s blog</a></li>
<li>The <a target="_blank" href="https://www.youtube.com/channel/UC9-y-6csu5WGm29I7JiwpnA">Computerphile</a> YouTube channel</li>
<li>Videos featuring Jason Haddix (<a target="_blank" href="https://github.com/jhaddix/">@jhaddix</a>) and Tom Hudson (<a target="_blank" href="https://github.com/tomnomnom/">@tomnomnom</a>) (two accomplished ethical hackers with different, but both effective, methodologies)</li>
</ul>
<p>You may be familiar with the catchphrase, “sanitize your inputs!” However, as I hope this post demonstrates, developing an application with robust security isn’t quite so straightforward. </p>
<p>I suggest an alternate phrase: pay attention to your inputs. Let’s elaborate by examining the most common attacks that take advantage of vulnerabilities in this area: SQL injection and cross site scripting.</p>
<h1 id="heading-sql-injection-attacks">SQL injection attacks</h1>
<p>If you’re not yet familiar with SQL (Structured Query Language) injection attacks, or SQLi, here is a great <a target="_blank" href="https://www.youtube.com/watch?v=_jKylhJtPmI">explain-like-I’m-five video on SQLi</a>. You may already know of this attack from <a target="_blank" href="https://xkcd.com/327/">xkcd’s Little Bobby Tables</a>. </p>
<p>Essentially, malicious actors may be able to send SQL commands that affect your application through some input on your site, like a search box that pulls results from your database. Sites coded in PHP can be especially susceptible to these, and a successful SQL attack can be devastating for software that relies on a database (as in, your Users table is now a pot of petunias).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/11/sqli.png" alt="A monitor with an SQL Select command that gets all your base" width="600" height="400" loading="lazy">
<em>You have no chance to survive make your time.</em></p>
<p>You can test your own site to see if you’re susceptible to this kind of attack. (Please only test sites that you own, since running SQL injections where you don’t have permission to be doing so is, possibly, illegal in your locality; and definitely, universally, not very funny.) The following payloads can be used to test inputs:</p>
<ul>
<li><code>' OR 1='1</code> evaluates to a constant true, and when successful, returns all rows in the table.</li>
<li><code>' AND 0='1</code> evaluates to a constant false, and when successful, returns no rows.</li>
</ul>
<p><a target="_blank" href="https://www.youtube.com/watch?v=ciNHn38EyRc">This video demonstrates the above tests</a>, and does a great job of showing how impactful an SQL injection attack can be.</p>
<p>Thankfully, there are ways to mitigate SQL injection attacks, and they all boil down to one basic concept: don’t trust user input.</p>
<h1 id="heading-sql-injection-mitigation">SQL injection mitigation</h1>
<p>In order to effectively mitigate SQL injections, developers must prevent users from being able to successfully submit raw SQL commands to any part of the site.</p>
<p>Some frameworks will do most of the heavy lifting for you. For example, Django implements the concept of <a target="_blank" href="https://en.wikipedia.org/wiki/Object-relational_mapping">Object-Relational Mapping</a>, or ORM, with its use of <a target="_blank" href="https://docs.djangoproject.com/en/2.2/topics/db/queries/">QuerySets</a>. We can think of these as wrapper functions that help your application query the database using pre-defined methods that avoid the use of raw SQL.</p>
<p>Being able to use a framework, however, is never a guarantee. When dealing directly with a database, there are other methods we can use to safely abstract our SQL queries from user input, though they vary in efficacy. These are, by order of most to least preferred, and with links to relevant examples:</p>
<ol>
<li>Prepared statements with variable binding (or <a target="_blank" href="https://cheatsheetseries.owasp.org/cheatsheets/Query_Parameterization_Cheat_Sheet.html">parameterized queries</a>),</li>
<li><a target="_blank" href="https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html#defense-option-2-stored-procedures">Stored procedures</a>; and</li>
<li><a target="_blank" href="https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html#defense-option-3-whitelist-input-validation">Whitelisting</a> or <a target="_blank" href="https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html#defense-option-4-escaping-all-user-supplied-input">escaping</a> user input.</li>
</ol>
<p>If you want to implement the above techniques, the linked cheatsheets are a great starting point for digging deeper. Suffice to say, the use of these techniques to obtain data instead of using raw SQL queries helps to minimize the chances that SQL will be processed by any part of your application that takes input from users, thus mitigating SQL injection attacks.</p>
<p>The battle, however, is only half won…</p>
<h1 id="heading-cross-site-scripting-xss-attacks">Cross Site Scripting (XSS) attacks</h1>
<p>If you’re a malicious coder, JavaScript is pretty much your best friend. The right commands will do anything a legitimate user could do (and even some things they aren’t supposed to be able to) on a web page, sometimes without any interaction on the part of an actual user. </p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Cross-site_scripting">Cross Site Scripting</a> attacks, or XSS, occur when JavaScript code is injected into a web page and changes that page’s behavior. Its effects can range from prank nuisance occurrences to more severe authentication bypasses or credential stealing. <a target="_blank" href="https://blogs.apache.org/infra/entry/apache_org_04_09_2010">This incident report from Apache in 2010</a> is a good example of how XSS can be chained in a larger attack to take over accounts and machines.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/11/xss-1.png" alt="An HTML dance party with a little JS cutting in" width="600" height="400" loading="lazy">
<em>The annual DOM dance-off receives an unexpected guest</em></p>
<p>XSS can occur on the server or on the client side, and generally comes in three flavors: DOM (<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction">Document Object Model</a>) based, stored, and reflected XSS. The differences amount to where the attack payload is injected into the application.</p>
<h2 id="heading-dom-based-xss">DOM based XSS</h2>
<p><a target="_blank" href="https://owasp.org/www-project-web-security-testing-guide/v41/4-Web_Application_Security_Testing/11-Client_Side_Testing/01-Testing_for_DOM-based_Cross_Site_Scripting">DOM based XSS</a> occurs when a JavaScript payload affects the structure, behavior, or content of the web page the user has loaded in their browser. These are most commonly executed through modified URLs, such as in phishing.</p>
<p>To see how easy it would be for injected JavaScript to manipulate a page, we can create a working example with an HTML web page. Try creating a file on your local system called <code>xss-test.html</code> (or whatever you like) with the following HTML and JavaScript code:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>My XSS Example<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"greeting"</span>&gt;</span>Hello there!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
                <span class="hljs-keyword">var</span> name = <span class="hljs-keyword">new</span> URLSearchParams(<span class="hljs-built_in">document</span>.location.search).get(<span class="hljs-string">'name'</span>);
                <span class="hljs-keyword">if</span> (name !== <span class="hljs-string">'null'</span>) {
                    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'greeting'</span>).innerHTML = <span class="hljs-string">'Hello '</span> + name + <span class="hljs-string">'!'</span>;
                }
            </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>This web page will display the title “Hello there!” unless it receives a <a target="_blank" href="https://en.wikipedia.org/wiki/Query_string">URL parameter from a query string</a> with a value for <code>name</code>. To see the script work, open the page in a browser with an appended URL parameter, like so:</p>
<p><code>file:///path/to/file/xss-test.html?name=Victoria</code></p>
<p>Fun, right? Our insecure (in the safety sense, not the emotional one) page takes the URL parameter value for <code>name</code> and displays it in the DOM. The page is expecting the value to be a nice friendly string, but what if we change it to something else? Since the page is owned by us and only exists on our local system, we can test it all we like. What happens if we change the <code>name</code> parameter to, say, <code>&lt;img+src+onerror=alert("pwned")&gt;</code>?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/11/pwned.png" alt="A screenshot of the XSS page example" width="600" height="400" loading="lazy"></p>
<p>This is just one example, largely based on one from <a target="_blank" href="https://brutelogic.com.br/blog/dom-based-xss-the-3-sinks/">Brute’s post</a>, that demonstrates how an XSS attack could be executed. Funny pop-up alerts may be amusing, but JavaScript can do a lot of harm, including helping malicious attackers steal passwords and personal information.</p>
<h2 id="heading-stored-and-reflected-xss">Stored and reflected XSS</h2>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Cross-site_scripting#Persistent_(or_stored)">Stored XSS</a> occurs when the attack payload is stored on the server, such as in a database. The attack affects a victim whenever that stored data is retrieved and rendered in the browser. For example, instead of using a URL query string, an attacker might update their profile page on a social site to include a hidden script in, say, their “About Me” section. The script, improperly stored on the site’s server, would successfully execute at a later time when another user views the attacker’s profile.</p>
<p>One of the most famous examples of this is the <a target="_blank" href="https://en.wikipedia.org/wiki/Samy_(computer_worm)">Samy worm</a> that all but took over MySpace in 2005. It propogated by sending HTTP requests that replicated it onto a victim’s profile page whenever an infected profile was viewed. Within just 20 hours, it had spread to over a million users.</p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Cross-site_scripting#Non-persistent_(reflected)">Reflected XSS</a> similarly occurs when the injected payload travels to the server, however, the malicious code does not end up stored in a database. It is instead immediately returned to the browser by the web application. </p>
<p>An attack like this might be executed by luring the victim to click a malicious link that sends a request to the vulnerable website’s server. The server would then send a response to the attacker as well as the victim, which may result in the attacker being able to obtain passwords, or perpetrate actions that appear to originate from the victim.</p>
<h1 id="heading-xss-attack-mitigation">XSS attack mitigation</h1>
<p>In all of these cases, XSS attacks can be mitigated with two key strategies: validating form fields, and avoiding the direct injection of user input on the web page.</p>
<h2 id="heading-validating-form-fields">Validating form fields</h2>
<p>Frameworks can again help us out when it comes to making sure that user-submitted forms are on the up-and-up. One example is <a target="_blank" href="https://docs.djangoproject.com/en/2.2/ref/forms/fields/#built-in-field-classes">Django’s built-in <code>Field</code> classes</a>, which provide fields that validate to some commonly used types and also specify sane defaults. Django’s <code>EmailField</code>, for instance, uses a set of rules to determine if the input provided is a valid email. If the submitted string has characters in it that are not typically present in email addresses, or if it doesn’t imitate the common format of an email address, then Django won’t consider the field valid and the form will not be submitted.</p>
<p>If relying on a framework isn’t an option, we can implement our own input validation. This can be accomplished with a few different techniques, including <a target="_blank" href="https://en.wikipedia.org/wiki/Type_conversion">type conversion</a>, for example, ensuring that a number is of type <code>int()</code>; checking minimum and maximum range values for numbers and lengths for strings; using a pre-defined array of choices that avoids arbitrary input, for example, months of the year; and checking data against strict <a target="_blank" href="https://en.wikipedia.org/wiki/Regular_expression">regular expressions</a>.</p>
<p>Thankfully, we needn’t start from scratch. Open source resources are available to help, such as the <a target="_blank" href="https://www.owasp.org/index.php/OWASP_Validation_Regex_Repository">OWASP Validation Regex Repository</a>, which provides patterns to match against for some common forms of data. Many programming languages offer validation libraries specific to their syntax, and we can find <a target="_blank" href="https://github.com/search?q=validation+library">plenty of these on GitHub</a>. Additionally, the <a target="_blank" href="https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet">XSS Filter Evasion Cheat Sheet</a> has a couple suggestions for test payloads we can use to test our existing applications.</p>
<p>While it may seem tedious, properly implemented input validation can protect our application from being susceptible to XSS.</p>
<h2 id="heading-avoiding-direct-injection">Avoiding direct injection</h2>
<p>Elements of an application that directly return user input to the browser may not, on a casual inspection, be obvious. We can determine areas of our application that may be at risk by exploring a few questions:</p>
<ul>
<li>How does data flow through our application?</li>
<li>What does a user expect to happen when they interact with this input?</li>
<li>Where on our page does data appear? Does it become embedded in a string or an attribute?</li>
</ul>
<p>Here are some sample payloads that we can play with in order to test inputs on our site (again, only our own site!) courtesy of <a target="_blank" href="https://www.hacker101.com/">Hacker101</a>. The successful execution of any of these samples can indicate a possible XSS vulnerability due to direct injection.</p>
<ul>
<li><code>"&gt;&lt;h1&gt;test&lt;/h1&gt;</code></li>
<li><code>'+alert(1)+'</code></li>
<li><code>"onmouserover="alert(1)</code></li>
<li><code>http://"onmouseover="alert(1)</code></li>
</ul>
<p>As a general rule, if you are able to design around directly injecting input, do so. Alternatively, be sure to completely understand the effect of the methods you choose; for example, using <code>innerText</code> instead of <code>innerHTML</code> in JavaScript will ensure that content will be set as plain text instead of (potentially vulnerable) HTML.</p>
<h1 id="heading-pay-attention-to-your-inputs">Pay attention to your inputs</h1>
<p>Software developers are at a marked disadvantage when it comes to competing with black hat, or malicious, hackers. For all the work we do to secure each and every input that could potentially compromise our application, an attacker need only find the one we missed. It’s like installing deadbolts on all the doors, but leaving a window open!</p>
<p>By learning to think along the same lines as an attacker, however, we can better prepare our software to stand up against bad actors. Exciting as it may be to ship features as quickly as possible, we’ll avoid racking up a lot of security debt if we take the time beforehand to think through our application’s flow, follow the data, and pay attention to our inputs.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Story of requesting twice - CORS ]]>
                </title>
                <description>
                    <![CDATA[ By Lusan Das The story of requesting twice, allow me to explain how it all began. While working on a feature, I decided to look at the network tab and observed that the first request was sent with method OPTIONS, and the following request after it wa... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-story-of-requesting-twice-cors/</link>
                <guid isPermaLink="false">66d45e09d1ffc3d3eb89ddbf</guid>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CORS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ REST API ]]>
                    </category>
                
                    <category>
                        <![CDATA[ web ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web App Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 13 Jun 2019 06:25:10 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/06/priscilla-du-preez-234144-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Lusan Das</p>
<p>The story of requesting twice, allow me to explain how it all began.</p>
<p>While working on a feature, I decided to look at the network tab and observed that the first request was sent with method OPTIONS, and the following request after it was the request with the correct method eg GET, POST etc, which is returning the expected payload. Basically two calls for the same request.</p>
<p>Here take a look at the screen shots below</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*W7g8e0J9fwocmwX_Ce6VWA.png" alt="Image" width="1600" height="625" loading="lazy"></p>
<p><em>Request with OPTIONS method</em></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*JgwOpH3t9oTrL8Q_UM01mw.png" alt="Image" width="1600" height="712" loading="lazy"></p>
<p><em>Request with GET method</em></p>
<p>After digging few docs, I realised it was an expected behaviour. It is related to the concept of HTTP access control (CORS).</p>
<p>To understand it better, let me explain a bit about CORS and requests.</p>
<h3 id="heading-http-access-control-cors">HTTP access control (CORS)</h3>
<p>Cross-Origin Resource Sharing (<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/CORS">CORS</a>) is a mechanism that uses additional <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/HTTP">HTTP</a> headers to let a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/user_agent">user agent</a> gain permission to access selected resources from a server on a different origin (domain) than the site currently in use.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*wnTTrWj5tn6VCQJHk9PHKQ.png" alt="Image" width="925" height="643" loading="lazy"></p>
<p><em>Cross-Origin Resource Sharing (</em><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/CORS"><em>CORS</em></a><em>)</em></p>
<p>Let us understand the above image above to get a better understanding of CORS.</p>
<ol>
<li><p><strong>Same Origin Request:</strong> We have opened <strong>domain-a.com</strong>, where we are requesting a <strong>blue image</strong> hosted in web server <strong>domain-a.com.</strong> Since we are performing our requests in the same domain, it is called a Same-origin request.</p>
</li>
<li><p><strong>Cross Origin Request:</strong> We have opened <strong>domain-a.com</strong>, where we are requesting a <strong>red image</strong> hosted in web server <strong>domain-b.com.</strong> Since we are performing our requests in different domains, it is called a Cross-origin Request.</p>
</li>
</ol>
<h3 id="heading-simple-requests"><strong>Simple requests</strong></h3>
<p>These are requests that doesn't send it’s first request as method OPTIONS. It is fired only once.</p>
<p>Surely it begs the question, why will the first request have method OPTIONS if we are not sending it, please have patience it will be explained below in preflight section ☺</p>
<p>But before that let us understand what are the points that make request simple.</p>
<ol>
<li>The only allowed methods in simple request are:</li>
</ol>
<ul>
<li><p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET">GET</a></p>
</li>
<li><p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD">HEAD</a></p>
</li>
<li><p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST">POST</a></p>
</li>
</ul>
<ol start="2">
<li>Apart from the headers set automatically by the user agent (for example, connection , <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent">User-Agent</a>, or any of the other headers with names defined in the Fetch spec as a “forbidden header name”), the only headers which are allowed to be manually set are <a target="_blank" href="https://fetch.spec.whatwg.org/#cors-safelisted-request-header">those which the Fetch spec defines as being a “CORS-safelisted request-header”</a>, which are:</li>
</ol>
<ul>
<li><p>Accept</p>
</li>
<li><p>Accept-Language</p>
</li>
<li><p>Content-Language</p>
</li>
<li><p>Content-Type</p>
</li>
<li><p>DPR</p>
</li>
<li><p>Downlink</p>
</li>
<li><p>Save-Data</p>
</li>
<li><p>Viewport-Width</p>
</li>
<li><p>Width</p>
</li>
</ul>
<ol start="3">
<li>The only allowed values for the Content-Type header are:</li>
</ol>
<ul>
<li><p>application/x-www-form-urlencoded</p>
</li>
<li><p>multipart/form-data</p>
</li>
<li><p>text/plain</p>
</li>
</ul>
<ol start="4">
<li><p>No event listeners are registered on any XMLHttpRequestUpload object used in the request.</p>
</li>
<li><p>No ReadableStream object is used in the request.</p>
</li>
</ol>
<h3 id="heading-preflighted-requests">Preflighted requests</h3>
<p>Preflighted request is a type of request which sends an HTTP request by the OPTIONS method to the resource on the other domain, in order to determine whether the actual request is safe to send. Cross-site requests are preflighted like this since they may have implications to user data. It is evident from the screenshots above.</p>
<p>For requests like PUT, DELETE, PATCH etc, preflight requests are sent.</p>
<p>Below flowchart summarises really well how it works.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*cYI52Rb-fWjSFiQPoCF9pQ.png" alt="Image" width="1534" height="1770" loading="lazy"></p>
<p><em>Image Courtesy html5rocks</em></p>
<p>This flowchart opens up a door to a whole new knowledge. Couldn’t help but appreciate how good it is!</p>
<blockquote>
<p><em>Strangely enough even GET request was observed to have preflights which for my case was due to presence of custom header Authorization, which can be seen from the screenshot below</em></p>
</blockquote>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*W7g8e0J9fwocmwX_Ce6VWA.png" alt="Image" width="1600" height="625" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*JgwOpH3t9oTrL8Q_UM01mw.png" alt="Image" width="1600" height="712" loading="lazy"></p>
<h4 id="heading-is-preflight-request-bad">Is Preflight request bad?</h4>
<p>It is a small request without a body, but I always felt it as a bother. It is still a request, and each request is a cost, no matter how small that request is, so I definitely recommend to try and avoid having such cases.</p>
<h4 id="heading-how-do-we-avoid-it">How do we avoid it?</h4>
<p>Well the easiest solution is avoid CORS, try to keep our resources and APIs in the same domain. It is really that simple.</p>
<h4 id="heading-conclusion">Conclusion</h4>
<p>It is always good to be armed with knowledge of how requests work. Even if the cost is very low, it still matters. Saving small requests can make our application really fast in the long run. Well I believe in the future, which is fast and furious.</p>
<blockquote>
<p><em>Follow me on</em> <a target="_blank" href="https://twitter.com/daslusan"><strong>twitter</strong></a> to get more updates regarding new articles and to stay updated in latest frontend developments. Also <strong>share</strong> this article on twitter to help others know about it. Sharing is caring <strong>^_^</strong></p>
</blockquote>
<h3 id="heading-some-helpful-resources">Some helpful resources</h3>
<p>Below are some of the links that inspired this article</p>
<ol>
<li><p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS">https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS</a></p>
</li>
<li><p><a target="_blank" href="https://stackoverflow.com/questions/24704638/options-request-makes-application-2x-slower">https://stackoverflow.com/questions/24704638/options-request-makes-application-2x-slower</a></p>
</li>
<li><p><a target="_blank" href="https://stackoverflow.com/questions/29954037/why-is-an-options-request-sent-and-can-i-disable-it/29954326">https://stackoverflow.com/questions/29954037/why-is-an-options-request-sent-and-can-i-disable-it/29954326</a></p>
</li>
<li><p><a target="_blank" href="https://www.html5rocks.com/en/tutorials/cors/">https://www.html5rocks.com/en/tutorials/cors/</a></p>
</li>
</ol>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Here’s how I could’ve ridden for free with Uber ]]>
                </title>
                <description>
                    <![CDATA[ By AppSecure Summary This post is about a critical bug on Uber which could have been used by hackers to get unlimited free Uber rides anywhere in the world. This post also explains few best practices while integrating payment gateways. Description Ub... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-anyone-could-have-used-uber-to-ride-for-free-36cdee5ea854/</link>
                <guid isPermaLink="false">66c34cce0fa3812cdd5ea9e4</guid>
                
                    <category>
                        <![CDATA[ bug bounty ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ uber ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web App Security ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 26 Jan 2018 10:43:53 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*cK-cejMVQq51oIX9C7M60A.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By AppSecure</p>
<h3 id="heading-summary">Summary</h3>
<p>This post is about a critical bug on Uber which could have been used by hackers to get unlimited free Uber rides anywhere in the world. This post also explains few best practices while integrating payment gateways.</p>
<h3 id="heading-description">Description</h3>
<p>Uber Technologies Inc. is an online transportation network company, headquartered in San Francisco, California, with operations in 528 cities worldwide. Users can create their account on Uber.com and book a ride. When the ride is completed a user can either pay cash or charge it to their credit/debit card.</p>
<p>But, by specifying an invalid payment method (for example, abc, xyz, and so on), I was able to ride Uber for free.</p>
<p>To demonstrate the bug, I got permission from the Uber Team and took a free ride in India. I wasn’t charged for any of my rides, using the invalid payment method.</p>
<h3 id="heading-vulnerable-request">Vulnerable request:</h3>
<blockquote>
<p>POST /api/dial/v2/requests HTTP/1.1 Host: dial.uber.com {“start_latitude”:12.925151699999999,”start_longitude”:77.6657536,<br> “product_id”:”db6779d6-d8da-479f-8ac7–8068f4dade6f”,”payment_method_id”:”xyz”}</p>
</blockquote>
<h3 id="heading-steps-to-reproduce">Steps to reproduce:</h3>
<ol>
<li>Replayed the above request with random characters as payment_method_id.</li>
<li>Ride was free.</li>
</ol>
<h4 id="heading-video-poc">Video POC:</h4>
<p>Thanks to Uber Security team for fixing this quickly.</p>
<h3 id="heading-the-timeline">The timeline</h3>
<p>Aug 22nd 2016: Vulnerability Report to Uber.</p>
<p>Aug 26th 2016: Uber requested more information about the bug.</p>
<p>Aug 26th 2016: Took a free ride and replied with ride details</p>
<p>Aug 27th 2016: Vulnerability fixed by Uber.</p>
<p>Sep 10th 2016: Rewarded with $5000 bounty by Uber.</p>
<h3 id="heading-takeaways">Takeaways</h3>
<p>As a developer, you should always take care of the below test cases when integrating payments:</p>
<p>a) Verify if the payment was success or failure by doing a server to server request to payment gateway or verifying checksum to the payment gateway provider.</p>
<p>b) Always validate the amount of the item with the amount which was paid by the user to the payment gateway.</p>
<p>c) Validate currency in the payment API calls. For example, the attacker can pay 50 IDR for a 50 USD item.</p>
<p>d) If you are storing credit cards/debit card information, then always check for authorisation if an identifier is being passed in one of the API requests.</p>
<blockquote>
<p><a target="_blank" href="https://appsecure.in"><strong>AppSecure</strong></a> is a specialised cyber security company with years of skill acquired and meticulous expertise. We are here to safeguard your business and critical data from online and offline threats or vulnerabilities.</p>
<p>Contact us: <strong>hello@appsecure.in</strong></p>
</blockquote>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
