---
# System prepended metadata

title: SafeSkein

---

# SafeSkein 

![](https://img.shields.io/badge/WIP-red?style=for-the-badge) 

![](https://img.shields.io/badge/Security_Vulnerability-black?logo=springsecurity) ![](https://img.shields.io/badge/Graphs_and_Algorithms-black?logo=diagramsdotnet) ![](https://img.shields.io/badge/npm-black?logo=npm) ![](https://img.shields.io/badge/yarn-black?logo=yarn) ![](https://img.shields.io/badge/Node.js-black?logo=nodedotjs)  ![](https://img.shields.io/badge/Bash-black?logo=gnubash)
 
![](https://img.shields.io/badge/Team-Arvind-red) ![](https://img.shields.io/badge/Submitter-Priyanshu-blue)

**Addressing Security Vulnerabilities in Yarn Package Dependencies**



## Problem Statement
> *`yarn` handles numerous packages and dependencies for projects and with an ever-growing number of packages and their associated transitive dependencies, ensuring the security of these packages has become a complex task.*

Security vulnerabilities in packages pose significant risks to projects, and manually detecting and mitigating these risks is laborious and prone to errors. Developers often need to **traverse complex dependency graphs to find the source of the vulnerability and identify the version changes needed across all dependent packages**. This process can be time-consuming, especially in large projects with numerous dependencies, and **there's a high risk of oversight**.


**The goal of this project:**
- [ ] **SafeSkein DevTool**: Develop an automated tool that accurately identifies vulnerable packages, suggests safe versions or patches *(when no safe version is possible)*, and actions to make the necessary changes quickly and efficiently. *This will aid in mitigating the existing vulnerabilities in our project*
- [ ] **SafeSkein CI/CD**: Add a pipeline job, which breaks the pipeline when any new vulnerability is introduced through the addition of a new vulnerable package (directly or transitively). *This will ensure future stability in our project*

***This project will not only mitigate security risks but also significantly save time and effort for developers, and keep it future proof as well.***

---

<details>
    <summary> 
        <b> Click here for implementation details </b><br/><br/>
    </summary>


- [SafeSkein DevTool](#SafeSkein-DevTool)
    - [Problem modelling - Identification of safe versions](#Problem-modelling---Identification-of-safe-versions)
    - [Third-party APIs for vulnerability database queries
](#Third-party-APIs-for-vulnerability-database-queries)
    - [Fetching all versions and dependencies](#Fetching-all-versions-and-dependencies)
- [SafeSkein CI/CD](#SafeSkein-CI/CD)
    
   
## SafeSkein DevTool

### Problem modelling - Identification of safe versions

> [color=#2c0093] We will model this problem as an directed graph (tree) $T_g(V,E)$
\
> [color=#2c0093] $v \in V(T_g)$, vertex $v$ represents a npm package $P_v$ with a fixed version and dependency chain, that is, a package coming from two different dependency chain even while having the same version, will be represented as two vertices or to simply put, shared dependencies are not considered.
\
> [color=#2c0093] $safeVersions[v]$ will hold safe versions of the current package which keeps itself and its dependencies safe as well.
\
> [color=#2c0093] $e \in E(T_g)$, $e(x,y)$ is an directed edge $V_x \to V_y$, represents package $P_x$ is dependent on $P_y$ that is importing $P_x$ will bring $P_y$ along with it.

![](https://hackmd.io/_uploads/B1QaqOiS2.png)

```pseudocode!=
## Pseudo code - Safe version identification

getDependentSafeVersions(v_c, v_p):
    // Requires safeVersions[v_c] to be computed before. 
    // Follow the semantic versioning rules for comparing versions here.
    // This essentially requires to check version of v_c in a given version of v_p.
    return: the versions of v_p that brings v_c with version lying in safeVersions[v_c]


computeSafeVersions(v, E):   
    // Post order traversal, recursively compute for children first
    for v_c in children(v, E):
        computeSafeVersions(v_c, E)

    // Initialize with safe versions of P_v itself
    // This info will be fetched from National Vulnerability Database (NVD) or Snyk APIs or GitHub Security Advisory API.
    // API responses must be cached to avoid redundant calls.
    // For `@sprinklr` prefixed packages, assume all versions are safe for initialization
    safeVersions[v] := vuln_db_api(P(v)) 

    // Traverse all childrens 
    for v_c in children(v, E):
        safeVersions[v] := 
            // Intersection of versions values
            intersection(
                safeVersions[v], 
                getDependentSafeVersions(v_c, v) 
            )
```

### Third-party APIs for vulnerability database queries

- [Snyk API Docs](https://snyk.docs.apiary.io/)
- [GitHub Security Advisory API](https://docs.github.com/en/graphql/reference/objects#securityadvisory)

### Fetching all versions and dependencies

- JSON fetched *(with header containing either `'Authorization': 'Basic username:password'` or authenticaion token)* from a npm registry *(should be configurable for private registry with fallback as: `https://registry.npmjs.org`)* can be parsed for the following information:
    - all versions of a package
    ```json
    /* Here's an mutated example of all react versions
    parsed from https://registry.npmjs.org/react */
  [ 
      ...
      "15.4.0-rc.1",
      "15.4.0-rc.2",
      "15.4.0-rc.3",
      "15.4.0-rc.4",
      "15.4.0",
      "15.4.1",
      "15.4.2",
      "16.0.0-alpha",
      "16.0.0-alpha.0",
      ...
   ]
    ```
    - all dependencies (with versions) of the package for a specific version
    ```json 
    /* Here's an mutated example of react version to dependency map
    parsed from https://registry.npmjs.org/react */
    {
      ...
      "0.2.2": {
        "eventemitter2": "~0.4.1",
        "sprintf": "~0.1.1",
        "ensure-array": "~0.0.2"
      },
      "0.2.3": {
        "eventemitter2": "~0.5.0",
        "sprintf": "^0.2.3",
      }
      ...
    }
    ```
## SafeSkein CI/CD

</details>

---
## Reading Material
- [About NPM audit reports](https://docs.npmjs.com/about-audit-reports)
- [Auditing package dependencies for security vulnerabilities
](https://docs.npmjs.com/auditing-package-dependencies-for-security-vulnerabilities)
- [`yarn why`](https://yarnpkg.com/cli/why)
- [Semantic Version (SemVer) ranges](https://classic.yarnpkg.com/lang/en/docs/dependency-versions/)