Friday, December 30, 2022

OWASP Security

 API Security

  1. Broken Object Level Authorization
    1. Aka IDOR (In-secured Direct Object Reference) - Accessing unauthorized objects using same token due to lack of authorization checks
    2. Mitigation
      • implement authorization checks with user policies and hierarchy
      • dont rely on IDs sent from client. Use IDs from session
      • Check authorization each time there is client request to access database
      • Use random non guessable IDs (UUIDs)
  2. Broken Authentication
    1. Due to Lack of best practices. 
    2. Mitigation
        • Check all possible ways to authenticate to all APIs 
          • Password reset APIs and one-time links also allow users to get authenticated and should be protected just as seriously 
            • Use standard authentication, token generation, password storage, MFA 
              • Use short-lived access tokens 
                • Authenticate your apps (so you know who is talking to you) 
                  • OAuth token is not authentication (hotel key analogy)
                    • Use stricter rate-limiting for authentication, implement lockout policies and weak password checks 
                1. Excessive Data Exposure
                  1. Exposing critical data to avoid regular updates ( eg. using * for db queries)
                  2. Mitigation:
                    • Never rely on client to filter data 
                    • Review all responses, only return what the API consumers really need 
                    • Define schemas of all the API responses 
                    • Don't forget about error responses 
                    • Identify all the sensitive or Pll info and justify its use 
                    • Enforce response checks to prevent accidental data and exception leaks 
                                1. Lack of Resources & Rate Limiting
                                  1. Denial of service to overwhelm the server
                                  2. Mitigation:
                                      • Rate limiting 
                                      • Payload size limits 
                                      • Rate limits specific to API methods, clients, addresses 
                                      • Checks on compression ratios 
                                      • Limits on container resources 
                                      • Check parsers on recursion vulnerabilities 
                                  3. Missing Function Level Authorization
                                    1. Similar to broken object level authorization
                                    2. Mitigation:
                                      • Don't rely on client app to enforce admin access 
                                      • Deny all access by default 
                                      • Only allow operation to users that belong to the appropriate group or role 
                                      • Properly design and test authorization
                                  4. Mass Assignment
                                  5. Security Misconfiguration
                                  6. Injection
                                  7. Improper Assets Management
                                  8. Insufficient Logging & Monitoring


                                  Saturday, November 26, 2022

                                  Code Review Best Practices

                                  Some hate it and some love it. It depends on style and intent of code review done by reviewer or understanding of reviewee. 

                                  A great code review can reduce overall development cycle by minimizing bug leaks to higher environments and lead to a high-quality final product. On the other hand, poor code reviewing strategy can add unnecessary latencies in development cycle without mitigating any bugs. 

                                  What is code review?

                                  A manual process of reviewing source code developed by a fellow programmer of a team. It can be performed by multiple people or be performed multiple times by the same person for a thorough analysis. Fews steps can be automated using code analysis tools available.

                                  Why do we need code review?

                                  The most apparent benefit is making sure bad code is not leaked to production. Other benefits of good code reviews are standardization, knowledge sharing, security checks, and building a sense of teamwork and collaboration.

                                  How-to do-good code reviews?

                                  There are several aspects of a great code review. It should cover design, security, maintainability, logic, and quality. Follow a checklist of questions while reviewing. Below are few important questions that should be verified:

                                  • Do I understand what the code is supposed to do?
                                  • Does the code do what it’s supposed to do?
                                  • Can this source code be simplified? Are there any redundancies?
                                  • Are the names easy to understand and descriptive?
                                  • Do the names follow our conventions?
                                  • Can I quickly discern the role of functions, classes, and methods?
                                  • Does the source code use encapsulation and modularization?
                                  • Is it reliant on old functionality or code?
                                  • Does it introduce vulnerabilities? How could I potentially exploit this code?
                                  • Does the code require any documentation?
                                  • Does it meet coding and style standards?


                                  Stick to small PR

                                  For best results, review no more than 400 lines of code at a time. Any more than that and you risk missing bugs, logic flaws, and other defects. 

                                  How to become better Reviewer

                                  Enhancing your techniques for code reviews can improve the quality of the code you’re reviewing as well as your own code. For better code reviews, show humility and focus on the code.

                                  Be Humble - 

                                  Senior developers shouldn’t be the only ones reviewing code. Entry-level developers can provide a fresh perspective and should be integrated into the process from the start. To improve your code reviews, take the attitude that you can learn something new from everyone on your team.

                                  Critique the Code

                                  Critiquing code is a bit of an art. You want to identify issues without making it sound like the author is the issue. The focus here should be on the code itself. Read: not the code writer. Avoid “you” and “should” statements.

                                  Good References - 
                                  https://google.github.io/eng-practices/review/
                                  https://stackoverflow.blog/2019/09/30/how-to-make-good-code-reviews-better/

                                  Tuesday, September 27, 2022

                                  Detect multiple tabs open in vanilla javascript

                                  <script>
                                      // Broadcast that you're opening a page.
                                      localStorage.openpages = Date.now();
                                      window.addEventListener('storage', function (e) {
                                          if(e.key == "openpages") {
                                              // Listen if anybody else is opening the same page!
                                              localStorage.page_available = Date.now();
                                          }
                                          if(e.key == "page_available") {
                                              alert("One more page already open");
                                          }
                                      }, false);
                                  </script>


                                  You might need to read the following steps 2 or 3 times to grab the concept properly.

                                  1. When you open the 1st tab, line # 3 will create a local storage value named “openpages”.
                                  2. Storage listener will NOT be called because the local storage value is updated from this tab.
                                  3. When you open the second tab, line # 3 will also create a local storage value named “openpages”.
                                  4. Storage listener from the 1st tab will be called because the local storage is updated from the 2nd tab.
                                  5. 1st tab will receive the value of “e.key” as “openpages”.
                                  6. So it will create another local storage value “page_available” at line # 7.
                                  7. Now this will call the storage listener from the 2nd tab. Because for the 2nd tab, it is called from the 1st tab.
                                  8. 2nd tab will receive the value of “e.key” as “page_available”, so it will display an alert message.

                                  Ref:  https://adnan-tech.com/detect-multiple-tabs-opened-at-same-time-javascript/

                                  Friday, September 9, 2022

                                  React project best practices and code snippets

                                  React Project Best Practices


                                  Code Snippets

                                  Functional components are far more efficient than class based components. There is also less code that is needed to be written to achieve the same goal. 

                                  Execute code on mount and unmount in functional components

                                  Answer is useEffect hook.

                                  If we pass an empty array as the second argument, it tells useEffect to fire on component load. This is the only time it will fire.

                                  import React, { useEffect } from 'react';
                                  const ComponentExample = () => {
                                      useEffect(() => {
                                          // Anything here is fired on component mount
                                      }, []);
                                  };


                                  If you add a return function inside the useEffect function, it is triggered when a component unmounts from the DOM.
                                   
                                  const ComponentExample2 = () => {
                                      useEffect(() => () => {
                                          // Anything here is fired on component unmount
                                      }, []);
                                  };



                                  You can use componentDidMount, and componentWillUnmount in the same useEffect function call. Dramatically reducing the amount of code needed to manage both life-cycle events.


                                  const ComponentExample3 = () => {
                                      useEffect(() => {
                                          // Anything in here is fired on component mount.
                                          return () => {
                                              // Anything in here is fired on component unmount.
                                          };
                                      }, []);
                                  };


                                  Now what about the dependency array passed to useEffect? We know from the documentation that:

                                  • It’s optional. If you don’t specify it, the effect runs after each render.
                                  • If it’s empty ([]), the effect runs once, after the initial render.
                                  • It must — or as we’ll see later, should — contain the list of values used in the effect. The effect runs after any of these values changes (and after the initial render).
                                  • The array of dependencies is not passed as argument to the effect function.
                                  The last point is important. It means that the array plays no direct role in ensuring that the effect runs with fresh values (the effect always runs with the value at the time the component is rendered, as we’ve just seen). The array only controls when the effect runs.


                                  Stop user from closing browser Tab/Window


                                  window.addEventListener('beforeunload', (ev) =>
                                  {
                                      ev.preventDefault();
                                      return ev.returnValue = 'Are you sure you want to close?';
                                  });


                                  Use Debouncing to handle multiple event fires on any action

                                  Ref - https://blog.logrocket.com/how-and-when-to-debounce-or-throttle-in-react/#:~:text=Its%20usage%20is%20similar%20to,object%20as%20the%20third%20argument.

                                  Why prefer connect over useSelector/useDispatch hook
                                  https://www.samdawson.dev/article/react-redux-use-selector-vs-connect

                                  React Boilerplate

                                  1. Setup VSCode
                                  2. Create new react project
                                  3. Setup package.json
                                  4. Setup Typescript
                                  5. Setup Webpack
                                  6. Setup folder Structure
                                    1. src
                                      1. APIs
                                      2. Assets
                                      3. Components
                                      4. Models
                                      5. Containers/Pages
                                      6. Hooks
                                      7. Redux/store
                                      8. Utils
                                      9. Wrappers (optional)
                                    2. tests
                                    3. configs

                                  Tuesday, August 2, 2022

                                  React Style Guide

                                   

                                  Naming

                                  • Extensions: Use .jsx extension for React components. eslint: react/jsx-filename-extension

                                  • Filename: Use PascalCase for filenames. E.g., ReservationCard.jsx.

                                  • Reference Naming: Use PascalCase for React components and camelCase for their instances.

                                  • Component Naming: Use the filename as the component name. For example, ReservationCard.jsx should have a reference name of ReservationCard. However, for root components of a directory, use index.jsx as the filename and use the directory name as the component name:


                                  // bad
                                  import Footer from './Footer/Footer';
                                    // bad 
                                    import Footer from './Footer/index'; 
                                    // good 
                                    import Footer from './Footer';

                                    • Always use camelCase for prop names, or PascalCase if the prop value is a React component.
                                    • Always define explicit defaultProps for all non-required props.
                                    • Why? propTypes are a form of documentation, and providing defaultProps means the reader of your code doesn’t have to assume as much. In addition, it can mean that your code can omit certain type checks.

                                      // bad
                                      function SFC({ foo, bar, children }) {
                                        return <div>{foo}{bar}{children}</div>;
                                      }
                                      SFC.propTypes = {
                                        foo: PropTypes.number.isRequired,
                                        bar: PropTypes.string,
                                        children: PropTypes.node,
                                      };
                                      
                                      // good
                                      function SFC({ foo, bar, children }) {
                                        return <div>{foo}{bar}{children}</div>;
                                      }
                                      SFC.propTypes = {
                                        foo: PropTypes.number.isRequired,
                                        bar: PropTypes.string,
                                        children: PropTypes.node,
                                      };
                                      SFC.defaultProps = {
                                        bar: '',
                                        children: null,
                                      };
                                    • Use spread props sparingly.
                                    Ref: https://github.com/airbnb/javascript/tree/master/react#table-of-contents

                                    Friday, July 29, 2022

                                    Git Strategies for developers

                                    Git is a version control system or VCS that is primarily employed for source code management and also for keeping track of changes made to a file or a set of files. It enables streamlining the individual processes of multiple developers working on the same project.

                                    What makes a Good Commit?

                                    Rule1- Keep your commits small
                                    Rule2- Keep related changes only in a commit
                                    Rule3- Write meaningful commit messages. 

                                    Try using Conventional Commit Messages - Developers working on real projects in teams, should prefer using conventional commit message standard for consistency and tracking. 


                                    Share Git Stash with another Dev or machine

                                    Create a patch

                                    The following git command will create a patch file that contains all the differences represented by the set of changes in the stash.


                                    git stash show "stash@{0}" -p > changes.patch


                                    The “stash@{0}” is the ref of the stash.
                                    If you want a different one just use $ git stash list to see your list of stashes and select which one you want to patch.

                                    Apply Patch

                                    Transfer/Send the patch file generated from one machine to the other and drop it into the root of your project directory.

                                    Then the following command will do all the magic!!! 

                                    git apply changes.patch
                                    // Reverse patch
                                    git apply changes.patch --reverse


                                    KEEP ON HACKING!!!

                                    The Git Merge Command

                                    The git merge command takes different lines of development created by the git branch and combines them into a single branch. 

                                    The Fast Forward Merge and the 3-way Merge

                                    fast-forward merge is when the Git moves the branch pointer to point at the incoming commit rather than constructing a merge commit. Although this typically happens when performing a git pull command without any local changes, it can also happen for a git merge command.

                                    Because all of the commits reachable from the target branch are now available through the current branch, the fast forward merge combines the histories of the two branches. A fast-forward merge, however, isn’t possible when the branches have diverged.

                                    Git combines two branches using the 3-way merge when there isn’t a linear path to the target branch. It uses a dedicated commit to tie the two histories together. It is called so because, in the 3-way merge, Git uses three commits to generate the merge commit; two branch tips and their common ancestor.

                                    Typically, the fast forward merge is used by developers for small features or bug fixes while the 3-way merge is reserved for integrating longer-running features.

                                    git merge vs. git merge --no-ff

                                    Usually, developers leverage the git merge command to merge two branches. The git command merges (combines) two or more commits into a single history. It’s general syntax is:

                                    git merge <branch>

                                    By default, the git merge command is a fast-forward merge. A fast-forward merge is possible when there is a linear path from the current branch tip to the target branch.

                                    In this scenario, rather than actually merging the two branches, Git integrates the histories, i.e., previous commits, that are to move the current branch tip up to the target branch tip.

                                    For scenarios that require a merge commit during a fast forward merge, we use the Git merge command with the --no-ff flag. The general syntax for this git command is:

                                    git merge --no-ff <branch>

                                    The Git merge --no-ff command merges the specified branch into the command in the current branch and ensures performing a merge commit even when it is a fast-forward merge. It helps in record-keeping of all performed merge commands in the concerning git repo.

                                    Using the --no-ff parameter prevents the Git merge command from performing a fast-forward merge when Git detects that the current HEAD is an ancestor of the commit that you’re trying to merge.

                                    No Fast-forward Merge

                                    At most times, the fast forward merge is preferred. Sometimes, however, there might be a requirement to prevent the fast-forward merge from happening. Typically, this is when maintaining a definite branch topology.

                                    For doing so, the --no-ff parameter can be passed with the git merge command. Resultantly, the git merge command will construct a commit merge rather than fast-forwarding.

                                    What if the git merge can’t fast-forward?

                                    What if you wish to perform the Git merge command for explicitly performing a fast-forward merge and need to withdraw if it can’t fast-forward? Is there some way to do so? Yes, there is.

                                    For doing so, instead of using the --no-ff parameter, you must use the --ff-only parameter. In such a scenario, you can go back and decide whether to merge or rebase if some error occurs during the process.

                                    How to Merge More Than 2 Branches?

                                    The git merge command provides support for a range of merging strategies. For merging more than two branches, two strategies are available:

                                    1. Octopus

                                    This Git merging strategy is mainly used for merging topic branch heads. It is the default merge strategy while pulling or merging more than a single branch. Hence, this is the strategy used when merging two branches.

                                    Although the octopus merge strategy is suitable for resolving cases with more than two heads, it can’t be used for performing a complex merge requiring manual resolution.

                                    2. Ours

                                    Ours merge strategy resolves any number of heads. The resulting tree of the merge, however, belongs to that of the current branch head and ignores all changes from the remaining branches. It is typically used to supplant the old development history of the side branches.

                                    Conclusion

                                    By now, you must be clear with the difference between the git merge and Git merge --no-ff commands. Understanding the difference is important to put both the git commands to the appropriate use.


                                    Ref: https://hackr.io/blog/difference-between-git-merge-and-git-merge-no-ff#:~:text=It%20is%20called%20so%20because,for%20integrating%20longer%2Drunning%20features.

                                    Cybersecurity Essential: OpenSSL

                                    In today’s digital landscape, securing data is paramount. Whether you’re building web applications, managing servers, or developing software...