From 22796689b4e98c2df8d6ee5aa8c9fac1b1af9382 Mon Sep 17 00:00:00 2001 From: nasfernane Date: Tue, 16 Sep 2025 11:39:40 +0200 Subject: [PATCH 01/12] feat: base markdown conversion --- blog/JS-X-Ray-6.0.html | 165 ++++++++++ blog/announcing-nodesecure-vuln-era.html | 158 ++++++++++ ...u-need-to-know-about-package-managers.html | 290 ++++++++++++++++++ blog/index.html | 26 ++ blog/securizing-your-github-org.html | 183 +++++++++++ index.html | 4 + package.json | 3 +- src/build-articles.js | 145 +++++++++ 8 files changed, 973 insertions(+), 1 deletion(-) create mode 100644 blog/JS-X-Ray-6.0.html create mode 100644 blog/announcing-nodesecure-vuln-era.html create mode 100644 blog/everything-you-need-to-know-about-package-managers.html create mode 100644 blog/index.html create mode 100644 blog/securizing-your-github-org.html create mode 100644 src/build-articles.js diff --git a/blog/JS-X-Ray-6.0.html b/blog/JS-X-Ray-6.0.html new file mode 100644 index 0000000..7884560 --- /dev/null +++ b/blog/JS-X-Ray-6.0.html @@ -0,0 +1,165 @@ + + + + + + + JS-X-Ray-6.0 + + + + +
+ ← Retour Γ  l'accueil +
+
+
+

--- +title: JS-X-Ray 6.0 +author: Thomas.G +date: 16/01/2023 +--- + +Hello πŸ‘‹ + +It's been a while since the last article on JS-X-Ray 😲! + +{% link https://dev.to/nodesecure/js-x-ray-3-0-0-3ddn %} + +In this article I will present you the latest major version πŸ‘€. I didn't do an article on version 4 and 5 because they didn't introduce new features (only breaking changes on the API). + +

πŸ“’ What is JS-X-Ray ?

+ +If you are new in town, JS-X-Ray is an open source JavaScript SAST (Static Application Security Testing). The tool analyzes your JavaScript sources for patterns that may affect the security and quality of your project 😎. + +Among the notable features: + +- Retrieving dependencies (CJS & ESM support) and detecting suspicious import/require. +- Detecting unsafe RegEx. +- Detecting obfuscated source (and provide hints on the tool used). + +As well as a lot of other detections. + +

Major release 4 and 5

+ +These versions introduced changes on warnings (and we improved how we manage them in the codebase). We added new descriptors for each of them: + +- i18n (for translation in CI or CLI). +- experimental +- severity (Information, Warning, Critical) + +Those information are visible in the NodeSecure CLI interface: + +!NodeSecure + +

Major release 6

+ +🐬 Ok, let's dive into this major release to discover the surprises πŸŽ‰ it has in store for us. + +

πŸš€ Introducing VariableTracer

+ +Almost a year of work on this new mechanism / class that brings a whole new dimension to JS-X-Ray. + +
js
+const tracer = new VariableTracer()
+  .enableDefaultTracing()
+  .trace("crypto.createHash", {
+    followConsecutiveAssignment: true, moduleName: "crypto"
+  });
+
+tracer.walk(node);
+
+ +This class is able to follow all declarations, assignments and patterns (and those even through very obscure patterns). + +
js
+const aA = Function.prototype.call;
+const bB = require;
+
+const crypto = aA.call(bB, bB, "crypto");
+const cr = crypto.createHash;
+cr("md5"); // weak-crypto warning is throw here
+
+ +This allows us to implement Probes in a much simpler way (which makes maintenance and testing much easier). + +Here an example with the `isWeakCrypto` probe: + +
js
+function validateNode(node, { tracer }) {
+  const id = getCallExpressionIdentifier(node);
+  if (id === null || !tracer.importedModules.has("crypto")) {
+    return [false];
+  }
+
+  const data = tracer.getDataFromIdentifier(id);
+
+  return [
+    data !== null &&
+    data.identifierOrMemberExpr === "crypto.createHash"
+  ];
+}
+
+ +By default the Tracer follows all ways of `requiring` dependencies with CJS and also usage of `eval` or `Function`. + + +

🚧 Removing unsafe-assign warning

+ +This warning was required at the beginning of the project because it was difficult for me to correctly identify some malicious patterns. + +!NodeSecure + +However, with the introduction of the new Tracer, which is very complete and precise, this warning no longer makes sense has it only generates unnecessary noise and false positives. + +

πŸ“œ Better ESM source parsing

+ +We previously had a lot of `parsing-error` warnings because the NodeSecure scanner failed to detect if the file was using either CJS or ESM. + +That new version will automatically retry with ESM enabled if it fails with CJS. + +

πŸ“‰ Reducing false positives

+ +To continue the momentum of the previous sections. This version drops a lot of warnings and significantly improves others. + +- Reducing false positives for `encoded-literal` warning by introducing new way of detecting safe values. +- Improve `short-identifiers` by also storing ClassDeclaration, MethodDefinition and Function parameters. + +We are also introducing a new `suspicious-file` warning when a file contain more than 10 encoded-literal warnings to avoid having file with hundreds or thousands of warnings. + +Of the 500 most popular NPM packages, we previously had 24k warnings with version 5. The latest version brings that number down to approximatively 5k warnings. + +

πŸ”¬ Improving coverage

+ +A lot of work has been done to add unit tests on all the probes of the project. We are near 100% of coverage πŸ’ͺ. + +!NodeSecure + +Thanks to the amazing work of our contributors: + +- Vincent DHENNIN - @kawacrepe +- Pierre DEMAILLY +- Mathieu KA +- M4gie + +

πŸ‘€ What's next ?

+ +Here what I'm working for the next major release: + +- Adding support of TypeScript sources (probably by allowing a customization of the parser). +- A new API that allows to dynamically extend the SAST with new custom probes (and custom warnings). +- Introducing new built-in detections and warnings (unsafe URL etc). + +I will continue to work to reduce the number of false positives and keep improving obfuscated codes detection. + +--- + +Please think to drop a star on github ❀️! + +That's it for today! Thanks for reading me πŸ˜‰ +

+
+
+ + + \ No newline at end of file diff --git a/blog/announcing-nodesecure-vuln-era.html b/blog/announcing-nodesecure-vuln-era.html new file mode 100644 index 0000000..3aea69d --- /dev/null +++ b/blog/announcing-nodesecure-vuln-era.html @@ -0,0 +1,158 @@ + + + + + + + announcing-nodesecure-vuln-era + + + + +
+ ← Retour Γ  l'accueil +
+
+
+

--- +title: NodeSecure Vuln-era +author: Thomas.G +date: 21/07/2022 +--- + +Hello πŸ‘‹, + +Back for a little article about the rebranding of one of the NodeSecure tools: Vulnera (previously vuln, the vuln-era has begun!). + +An opportunity for me to also write about this wonderful project that was born with the redesign of the back-end less than a year ago ⌚. If you don't remember I wrote an article: + +{% link https://dev.to/fraxken/announcing-new-node-secure-back-end-1dp9 %} + +Don't wait and dive in 🌊 with me to discover this tool πŸ’ƒ. + +

What is Vulnera ? πŸ‘€

+ +Vulnera is a package that allows you to programmatically fetch your Node.js project vulnerabilities from multiple sources or strategies: + +- NPM Audit (Github Advisory Database) +- Sonatype OSS Index +- `deprecated` Node.js Security WG Database +- Snyk + +> πŸ“’ Feel free to push new sources (we have a guide on how to add/contribute one). + +The code was originally designed for vulnerability management within the Scanner. Yet, its API is evolving with the objective of making it a full-fledged project. + +
js
+import * as vulnera from "@nodesecure/vulnera";
+
+const def = await vulnera.setStrategy(
+  vulnera.strategies.NPM_AUDIT
+);
+
+const vulnerabilities = await def.getVulnerabilities(process.cwd(), {
+  useStandardFormat: true
+});
+console.log(vulnerabilities);
+
+ +

Standard vulnerability format πŸ‘―

+ +We have created a standard format to reconcile the different sources. + +
ts
+export interface StandardVulnerability {
+  / Unique identifier for the vulnerability /
+  id?: string;
+  / Vulnerability origin, either Snyk, NPM or NodeSWG /
+  origin: Origin;
+  / Package associated with the vulnerability /
+  package: string;
+  / Vulnerability title /
+  title: string;
+  / Vulnerability description /
+  description?: string;
+  / Vulnerability link references on origin's website /
+  url?: string;
+  / Vulnerability severity levels given the strategy /
+  severity?: Severity;
+  / Common Vulnerabilities and Exposures dictionary */
+  cves?: string[];
+  / Common Vulnerability Scoring System (CVSS) /
+  cvssVector?: string;
+  / CVSS Score /
+  cvssScore?: number;
+  / The range of vulnerable versions */
+  vulnerableRanges: string[];
+  / The set of versions that are vulnerable /
+  vulnerableVersions: string[];
+  / The set of versions that are patched /
+  patchedVersions?: string;
+  / Overview of available patches /
+  patches?: Patch[];
+}
+
+ +You can always use the original formats of each source of course 😊. We have implemented and exposed TypeScript interfaces for each of them. + +!NodeSecure types + +

Usage in Scanner πŸ”¬

+ +On the scanner we have all the necessary information because we go through the dependency tree πŸŽ„. At the end of the process, we recover all vulnerabilities by iterating spec by spec within the hydratePayloadDependencies strategy method. + +
js
+const {
+  hydratePayloadDependencies,
+  strategy
+} = await vulnera.setStrategy(
+  userStrategyName // SNYK for example
+);
+await hydratePayloadDependencies(dependencies, {
+  useStandardFormat: true,
+  path: location
+});
+
+payload.vulnerabilityStrategy = strategy;
+
+ +The following diagram explains the overall behavior and interactions between the Scanner and Vulnera. +!NodeSecure + +If you want to learn more about the Payload you can check the TypeScript interface here. + +

What's next ? πŸš€

+ +Some sources are more difficult to exploit than others (for NPM we use Arborist which simplifies our lives). + +
js
+const { vulnerabilities } = (await arborist.audit()).toJSON();
+
+ +However, we have to think and create mechanics to exploit sources like Sonatype 😨. This is required for API like `getVulnerabilities()`. + +Among the major subjects and ideas we are working on: +- Create a private database to benchmark the sources between them (see #29). +- Merging multiple sources in one (see #25). +- Fetch vulnerabilities of a given remote package (with support for private registry like verdaccio). At the moment we only support the analysis of a local manifest or a payload of the scanner. + +

Credits πŸ™‡

+ +This project owes much to our core collaborator Antoine COULON who invested a lot of energy to improve it πŸ’ͺ. + +> Fun fact: its first contribution 🐀 on NodeSecure was also on the old version of the code Scanner that managed vulnerabilities. + +But I don't forget individual contributions πŸ‘ +- Mathieu Kahlaoui for adding the getVulnerabilities() API +- Oleh Sych for adding Snyk strategy +- Medhi for his work on the logo + +--- + +Thanks πŸ™ for reading me and see you soon for another article! +

+
+
+ + + \ No newline at end of file diff --git a/blog/everything-you-need-to-know-about-package-managers.html b/blog/everything-you-need-to-know-about-package-managers.html new file mode 100644 index 0000000..b06006d --- /dev/null +++ b/blog/everything-you-need-to-know-about-package-managers.html @@ -0,0 +1,290 @@ + + + + + + + everything-you-need-to-know-about-package-managers + + + + +
+ ← Retour Γ  l'accueil +
+
+
+

--- +title: Everything you need to know: package managers +author: Antoine.C +date: 18/10/2022 +--- + +Welcome everyone! This article is the first one of the Everything you need to know, a Software Engineering series. + +In this series, I will try to give you a solid basic understanding about Software Engineering concepts I consider important. + +All modern computer systems include tools that automate the process of installing, uninstalling and updating software. + +This responsibility is that of a package manager and several can intervene within the same computer system. + +

Operating system

+ +The majority of Unix-based operating systems embed a package manager as standard, providing a multitude of different packages very simply. + +If you have ever used a Linux distribution such as Ubuntu or Debian, you've probably used a package manager before. If I say `apt-get update` does that ring a bell? + +This command tells APT to update all versions of packages installed. APT (Advanced Packaging Tool)) is a package manager embedded very widely as standard on Linux operating systems. To install a package, you can for example enter the command `apt-get install `. + +

Programming language

+ +Most programming languages ​​can embed their own with package managers, either natively or provided within their respective ecosystem. + +Take for example npm, the default package manager for Node.js. We can also mention pip for Python, NuGet for C#, Composer for PHP, etc. Similar to APT, npm makes it easy to install packages using the `npm install ` command. + +> For this article, I decided to take npm as an example. +> npm is indeed a very good support to highlight the advantages but also the disadvantages that a package manager can have. +> The advantages and disadvantages listed in the following part are valid for all package managers. + +> npm is installed alongside Node.js. To reproduce these examples, [you only need to install Node.js here]. + +In four parts, we will see what are the main reasons for such an expansion of package managers to all layers of a computer system. + +1. Ease of use and maintenance of packages + +The main interest of a package manager is obviously to simplify the installation of dependencies external to our application. Before the rise of npm in January 2010, the dependencies of a JavaScript application were mostly installed manually. By "manual installation" I mean: +- downloading a zip archive from a remote server +- unzipping the archive in the project +- manual referencing of the installed version, and this with each update of a dependency. + +With a package manager like npm, we therefore benefit from: +- Simplified installation of a package `npm install ` +- The simplified update of a package `npm update ` +- The simplified removal of a package `npm uninstall ` + +The packages are installed in a __node_modules__ folder adjacent to the application and which is entirely managed by npm. All packages located in the node_modules folder can be directly imported from the application. + +> In general, each programming language natively embeds its own module resolution management mechanism. + +1.1. Install + +In order for a package to be installed, we first need a name which is in most cases used as a unique identifier. Naming conventions can differ from one ecosystem to another. + +
bash
+$ npm install rxjs 
+
+ +With this command, the package manager will search within the registry for a package that has the name rxjs. When the version is not specified, the package manager will usually install the latest available version. + +1.2. Use + +
javascript
+// ECMAScript Modules (ESM)
+import { of } from "rxjs";
+// CommonJS
+const { of } = require("rxjs");
+
+ +The module systems integrated into the programming languages ​​make it possible to import a library installed locally and sometimes remotely (like Go or Deno for example). In this case with Node.js, the package must be installed locally in a node_modules folder. With Node.js, the module resolution algorithm allows the dependency to be in a node_modules folder either adjacent to the source code or in a parent folder (which sometimes leads to an unexpected behavior). + +

2. Managing the consistency of installed packages

+ +Now, let's dive into a little more detail on one very important aspect that a package manager must manage: state consistency between installed packages. So far, installing a package looks like a trivial task, which is just to automate downloading a package of a certain version and making it available in a conventional folder that the application has access to. + +However this management of consistency between packages turns out to be relatively difficult and the way of modeling the dependency tree varies according to the ecosystems. Most of the time, we talk about a dependency tree, but we can also talk about a dependency graph, in particular a directed graph. + +If you are not familiar with the concept of directed graphs, I invite you to read the series of articles I wrote about it on dev.to with examples in JavaScript. + +The implementations of these data structures can be drastically different depending on the ecosystem of a package manager, but also between package managers of the same ecosystem (npm, yarn, pnpm for Node.js for example). + +> How to ensure that all developers share the same dependencies and therefore the same versions of each underlying library? + +Still in the context of npm, let's take for example a very simple list of dependencies, expressed as an object in the _package.json_ file: + +package.json + +
json
+{ 
+  "dependencies": {
+    "myDependencyA": "<0.1.0"
+  }
+}
+
+ +This object describes a dependency of our project on the _myDependencyA_ library downloadable from the npm registry. Semantic Versioning here constrains the version of the library to be installed (here lower than 0.1.0). + +> Semantic version management (commonly known as SemVer) is the application of a very precise specification to characterize the version of software. For more information on this subject, I invite you to take a look at the official specification https://semver.org/lang/fr/ + +In our case, by remaining on the classic `..` scheme, we express the possibility of installing all the versions of _myDependencyA_ from "0.0.1" to "0.0.9". This therefore means that any version of the dependency that respects the range is considered valid. On the other hand, this also means that if a developer A installs the dependency at 2 p.m. and a developer B installs the dependency at 5 p.m., they may both not have the same dependency tree if ever a new version of _myDependencyA_ is released in the meantime. + +The npm dependency resolution algorithm will by default favor the installation of the most recent dependency that respects the semantic management described in the _package.json_. By specifying `npm install myDependencyA`, the most recent version of _myDependencyA_ will be installed respecting the constraint "<1.0.0" (version strictly lower than "1.0.0"). + +The major problem with this approach is the lack of stability and reproducibility of the dependency tree from one computer to another, for example between developers or even on the machine used in production. Imagine that version 0.0.9 of _myDependencyA_ has just been released with a bug and your production machine is about to do an `npm install` on Friday at 5:59 PM… + +!Production deployment on friday night + +The very simple example is often referred as `version drift`. This is why a single description file (in this case package.json) cannot be enough to guarantee an identical and reproducible representation of a dependency tree. + +Other reasons include: + +- using a different version of the package manager whose dependency installation algorithm may change. +- publishing a new version of an indirect dependency (the dependencies of the dependencies we list in the package.json here), which would result in the new version therefore being uploaded and updated. +- the use of a different registry which for the same version of a dependency exposes two different libraries at a time T. + +Lockfiles to the rescue + +To ensure the reproducibility of a dependency tree, we therefore need more information that would ideally describe the current state of our dependency tree. This is exactly what lockfiles do. These are files created and updated when the dependencies of a project are modified. + +A lockfile is generally written in _JSON_ or _YAML_ format to simplify the readability and understanding of the dependency tree by a human. A lockfile makes it possible to describe the dependency tree in a very precise way and therefore to make it deterministic and reproducible from one environment to another. So it's important to commit this file to Git and make sure everyone is sharing the same lockfile. + +package-lock.json + +
json
+{
+  "name": "myProject",
+  "version": "1.0.0",
+  "dependencies": {
+    "myDependencyA": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/myDependencyA/-/myDependencyA-0.0.5.tgz",
+      "integrity": "sha512-DeAdb33F+"
+      "dependencies": {
+        "B": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/B/-/B-0.0.1.tgz",
+          "integrity": "sha512-DeAdb33F+"
+          "dependencies": {
+            // dependencies of B
+          }
+        }
+      }
+    }
+  }
+}
+
+ +For npm, the basic lockfile is called _package-lock.json_. In the snippet above, we can precisely see several important information: +- The version of myDependencyA is fixed at "0.0.5" so even if a new version is released, npm will install "0.0.5" no matter what. +- Each indirect dependency describes its set of dependencies with versions that also describe their own versioning constraints. +- In addition to the version, the contents of the dependencies can be checked with the comparison of hashes which can vary according to the registers used. + +A lockfile therefore tries to accurately describes the dependency tree, which allows it to remain consistent and reproducible over time at each installation. + +⚠️ But... + +Lockfiles don't solve all inconsistency problems! Package managers implementations of the dependency graph can sometimes lead to inconsistencies. For a long time, npm's implementation introduced Phantom Dependencies and also NPM doppelgangers which are very well explained on the Rush.js documentation website (advanced topics that are out of the scope of this blog post). + +

3. Provision of distributed and transparent databases via open-source

+ +Distributed registries + +A package manager is a client that acts as a gateway to a distributed database (often called a registry). This allows in particular to share an infinite number of open-source libraries around the world. It is also possible to define company-wide private registries in a secured network, within which libraries would be accessible. + +> Verdaccio allows to setup a private proxy registry for Node.js + +The availability of registries has greatly changed the way software is developed by facilitating access to millions of libraries. + +Transparent access to resources + +The other benefit of open-source package managers is that they most often expose platforms or tools that allow browsing through published packages. Accessing source code and documentation has been trivialized and made very transparent. It is therefore possible for each developer to have an overview or even to fully investigate the code base of a published library. + +

4. Security and integrity

+ +Using open-source registries with millions of publicly exposed libraries is pretty convenient, but what about _security_? + +It is true that open-source registries represent ideal targets for hackers: all you have to do is take control of a widely used library (downloaded millions of times a week) and inject malicious code into it, and no one will realize! + +In this part, we will see the solutions implemented by package managers and registries to deal with these attacks and limit the risks. + +Integrity safety for each installed package + +Given that a package can be installed from any registry, it is important to implement verification mechanisms at the level of the content of the downloaded package, to ensure that no malicious code has been injected during the download, regardless of its origin. + +For this, integrity metadata is associated with each installed package. For example with npm, an integrity property is associated with each package in the lockfile. This property contains a cryptographic hash which is used to accurately represent the resource the user expects to receive. This allows any program to verify that the content of the resource matches what was downloaded. For example for `@babel/core`, this is how integrity is represented in package-lock.json: + +
json
+"@babel/core": {
+   "version": "7.16.10",
+   "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.10.tgz",  
+   "integrity": "sha512 pbiIdZbCiMx/MM6toR+OfXarYix3uz0oVsnNtfdAGTcCTu3w/JGF8JhirevXLBJUu0WguSZI12qpKnx7EeMyLA=="
+}
+
+ +Let's take a closer look at how integrity can drastically reduce the risk of injecting malicious code by hashing source code. + +As a reminder: + +> We call hash function, a particular function which, from a datum supplied as input, calculates a digital fingerprint used to quickly identify the initial datum, in the same way as a signature to identify a person. Wikipedia + +Let's take for example a simple case: + +
javascript
+// my-library
+function someJavaScriptCode() {
+  addUser();
+}
+
+ +Let's imagine that this JavaScript code represents a resource that a user might want to download. Using the _SHA1_ hash function, we get the hash `7677152af4ef8ca57fcb50bf4f71f42c28c772be`. +If ever malicious code is injected, the library's fingerprint will by definition change because the input (source code here) to the hash function will have changed: + +
javascript
+// my-library
+function someJavaScriptCode() {
+  processMaliciousCode(); // this is injected, the user is not  expecting that
+  addUser();
+}
+
+ +After injecting the malicious code, still using the same _SHA1_ hash function, we obtain `28d32d30caddaaaafbde0debfcd8b3300862cc24` as the digital fingerprint. +So we get as results: +- Original code = `7677152af4ef8ca57fcb50bf4f71f42c28c772be` +- Malicious code = `28d32d30caddaaaafbde0debfcd8b3300862cc24` + +All package managers implement strict specifications on this approach to integrity. For example, npm respects the W3C's "Subresource Integrity or SRI" specification, which describes the mechanisms to be implemented to reduce the risk of malicious code injection. +You can jump directly here to the specification document if you want to dig deeper. + +Security constraints at the author level + +To strengthen security at the level of open-source packages, more and more constraints are emerging on the side of project authors and maintainers. Recently, GitHub, which owns npm, announced that it is forcing two-factor authentication (2FA) for contributors to the 100 most popular packages. The main idea around these actions is to secure resources upstream by limiting write access to open-source packages and identifying people more precisely. + +It's important to also mention that there are tools that can be used to perform automatically scans and audits continuously. + +Built-in tools + +In order to automate the detection of vulnerabilities, many package managers natively integrate tools allowing to scan the installed libraries. Typically, these package managers communicate with databases that list all known and referenced vulnerabilities. For example, GitHub Advisory Database is an open-source database that references thousands of vulnerabilities across multiple ecosystems (Go, Rust, Maven, NuGet, etc) e.g. `npm audit` command uses this database. + +Third-party tools + +NodeSecure + +At NodeSecure we are building free open source tools to secure the Node.js & JavaScript ecosystem. Our biggest area of expertise is in package and code analysis. + +Here are some example of the available tools: + +- @nodesecure/cli, a CLI that allow you to deeply analyze the dependency tree of a given package or local Node.js project +- @nodesecure/js-x-ray, a SAST scanner (A static analyser for detecting most common malicious patterns) +- @nodesecure/vulnera, a Software Component Analysis (SCA) tool +- @nodesecure/ci, a tool allowing to run SAST, SCA and many more analysis in CI/CDs or in a local environment + +Snyk + +Snyk is the most popular all-around solution for securing applications or cloud-based infrastructures. Snyk offers a free-tier with SAST and SCA analysis. + +To ensure continuous detection of vulnerabilities, it is recommended to run scans each time packages are installed/modified. + +Conclusion + +There you go, you now know what issues are addressed and solved by package managers! + +Package managers are complex tools that aim to make life easier for us as developers, but can quickly become problematic if misused. + +It is therefore important to understand the issues they deal with and the solutions provided in order to be able to put into perspective several package managers of the same ecosystem. In the end, it's a tool like any other and it must mobilize thinking in the same way as when libraries/frameworks/programming languages ​​are used. + +Don't also forget to take into account security issues and use automated tools which can drastically reduce the attack surface! +

+
+
+ + + \ No newline at end of file diff --git a/blog/index.html b/blog/index.html new file mode 100644 index 0000000..31edebb --- /dev/null +++ b/blog/index.html @@ -0,0 +1,26 @@ + + + + + + + Blog - NodeSecure + + + + +
+ ← Retour Γ  l'accueil +

Articles de blog

+
+
+ +
+ + + \ No newline at end of file diff --git a/blog/securizing-your-github-org.html b/blog/securizing-your-github-org.html new file mode 100644 index 0000000..1cfd108 --- /dev/null +++ b/blog/securizing-your-github-org.html @@ -0,0 +1,183 @@ + + + + + + + securizing-your-github-org + + + + +
+ ← Retour Γ  l'accueil +
+
+
+

--- +title: Securizing your GitHub org +author: Thomas.G +date: 19/02/2023 +--- + +Hello πŸ‘‹ + +I started open source a bit naively (like everyone I guess 😊). + +But the more I progress and the more important/popular some of my projects become 😎. That's great, but at some point you have to deal with a lot of things related to security (like Vulnerability disclosure). + +You start to hear and see a lot of scary stories around you 😱. Not to mention all the acronyms where you don't understand anything at first 😡 (VMT, CVE, SAST, SCA, CNA ...). + +As I was working on an open source security project, I put pressure on myself to be ready. Also as a member of the Node.js Security WG I thought it was an interesting topic and that I was probably not the only one who was worried about not being up to the task πŸ˜–. + +So I rolled up my sleeves and tackled the problem πŸ’ͺ. Here is my feedback/journey on how I improved the security of my NodeSecure GitHub organization. + +> πŸ‘€ We use Node.js and JavaScript (but most recommendations are valid for other ecosystems). + +

Security Policy and Vulnerability Disclosure

+ +Adding a root `SECURITY.md` file explaining how developers and security researchers should report vulnerability is important. You don't want a security threat to be turned into a public issue (This gives you time to analyze and possibly fix before disclosure). + +> ⚠️ If you are a developer, never report a security threat using a public GitHub issue. This is a serious mistake. This could even put your business/team at risk. + +I don't want to bullshit you, so let me share with you the OpenSSF guide that helped me set up my first reporting strategy: Guide to implementing a coordinated vulnerability disclosure process for open source projects. + +I started from scratch by reading this guide and taking inspiration from their templates 🐀. As a small open source team we don't especially have DNS or mail servers (not even a defined Vulnerability Management Team A.K.A VMT). + +I was a bit puzzled to put my personal email as I'm not alone 😟. + +I quickly learned that Github added a new feature to report/create private security issue 😍. You can enable it in the `Security` tab (I think it's also now possible to enable it on every repositories at once). + +And this is what it finally looks like: +!NodeSecure SECURITY.md + +

Use OpenSSF scorecard

+ +!scorecard + +The OSSF scorecard initiative is really good to assess your project against security best practices. I am not the first to write about this. + +You can easily setup the GitHub action workflow by following those instructions. + +Once configured, you will have a set of alerts available in the `Security` tab. + +!Scorecard scanning alerts + +This will give you an overview of the different subjects to improve (workflows, dependencies etc). Each of these alerts contains a full description of the actions to be taken to fix the problem. + +!OSSF Scorecard + +I have personally used these recommendations to dig and train myself. The next chapters will help you improve your score. + +> πŸ“’ By the way NodeSecure CLI has a first-class support of the scorecard. + +

πŸ”“ Enable branch protection

+I am a bad student 😳. Almost all of my projects had no branch protection on the `main` / `master` branch πŸ™ˆ. + +> To set up the protection, go to `Settings` > `Branches` and edit your main branch. + +GitHub has quite a few options on the subject 😡. If you don't know what to choose in terms of options, don't check anything (it's ok to begin βœ”οΈ). + +If you want to be more restrictive, be careful because it could block you (some options are only viable in projects with many contributors/reviewers). + +As far as I am concerned I often choose: +- Require a pull request before merging +- Require conversation resolution before merging +- Require status checks to pass before merging + +

🐲 Workflows Hardening

+I fell down when I saw all that it was necessary to know to secure workflows with GitHub actions 😲. + +- You must pay attention to the permissions granted to your jobs / GITHUB_TOKEN +- Ensure your GitHub Actions are pinned to a SHA +- Hardening the runner (see the StepSecurity HardenRunner) +- Probably a lot of other stuff I haven't had time to see yet πŸ˜† + +Fortunately there is a great free online tool that help you by doing all the hard work (it will open a pull-request and automatically fix issues). + +{% tweet https://twitter.com/fraxken/status/1617557370728767488 %} + +The tool was created by StepSecurity. I had the opportunity to talk with the CEO and they listen to the maintainers which is really cool. +Thanks to them ❀️! + +

Configure Dependabot

+ +It is recommended to use Dependabot for updating your dependencies and GitHub actions (yes, it also supports updating workflows in a secure way 😍). + +You only need to add a `.github/dependabot.yml` config file. Personally I recommend a weekly interval (with a lot of projects daily is a bit horrible). + +
yml
+version: 2
+updates:
+  - package-ecosystem: github-actions
+    directory: /
+    schedule:
+      interval: weekly
+
+  - package-ecosystem: npm
+    directory: /
+    schedule:
+      interval: weekly
+
+ +The StepSecurity tool we have seen in the previous chapter is also capable of doing it πŸš€. + +--- + +Also, think to enable Dependabot alerts in the `Security` tab. This will allow the bot to open pull-request to fix known vulnerabilities by looking at your dependencies (referenced in package.json or others). + +

πŸ”¬ Adding CodeQL scanning

+ +To enhance security even more you can add a SAST tool like CodeQL. Like scorecard it will report security scanning alert but for your codebase. + +Here an example: +!prototype-pollution + +A great way to make sure that newly added code does not contain vulnerabilities that were obvious to detect. + +> πŸ‘€ Note that once again StepSecurity can set up the workflow for you. + +

πŸ“œ Enable Security advisories (and others)

+ +Github Security tab as a lot of cool features that help you maintain the security of your project. If you have followed all my previous chapters, most of them should be enabled now. + +Make sure to also enable `Secret scanning alerts`. + +!Github Security + +For an organization many of these parameters can be forced on all repositories. Go to `Settings` > `Code security and analysis`. You will have the options to enable/disable all. + +!Github Security + +

πŸ’‘ OpenSSF Best Pratices program

+ +Previously known as CII-Best-Practices, this program indicates that the project uses a set of security-focused best development practices for open source software. + +So I registered my first project on the website. It was a good surprise because it allowed me to question the quality of my documentation and tests 😬. + +Seeing the different levels and questions really helps you think about what you're missing (and possibly learn about the concepts you don't know about yet.. Like SBOM). + +!CII-Best-Practices + +I am still working on completing the first step/badge for the CLI project which now has a score of 8.7 out of 10 πŸŽ‰ on the OpenSSF scorecard. + +

🎯 Conclusion

+ +That's it for this article. I've covered what I've done/learned in the last couple of months. Here are some really cool additional links πŸ’ƒ: + +- Concise Guide for Evaluating Open Source Software 2023-01-03 +- Concise Guide for Developing More Secure Software 2023-01-03 + +If you work with NPM, I invite you to read our latest article about package managers: + +{% link https://dev.to/nodesecure/everything-you-need-to-know-package-managers-286c %} + +Obviously, I probably still have a lot to learn. But I hope this will help other maintainers/developers ❀️. + +πŸ™ Thanks for reading me πŸ™ +

+
+
+ + + \ No newline at end of file diff --git a/index.html b/index.html index a53ccd9..51e0edb 100644 --- a/index.html +++ b/index.html @@ -41,6 +41,10 @@

style="width:28px;height:28px;filter:invert(1) brightness(2);"> Join Discord + + Blog + Visit Blog + diff --git a/package.json b/package.json index cd737b0..f70fd00 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "scripts": { "dev": "vite", "build": "vite build", - "preview": "vite preview" + "preview": "vite preview", + "build:articles": "node src/build-articles.js" }, "repository": { "type": "git", diff --git a/src/build-articles.js b/src/build-articles.js new file mode 100644 index 0000000..cf09009 --- /dev/null +++ b/src/build-articles.js @@ -0,0 +1,145 @@ +// Import Node.js Dependencies +import fs from "node:fs"; +import path from "node:path"; + +const inputDir = "./articles"; +const outputDir = "./blog"; + +function markdownToHtml(markdown) { + let html = markdown; + + // headers + html = html.replace(/^### (.*$)/gim, "

$1

"); + html = html.replace(/^## (.*$)/gim, "

$1

"); + html = html.replace(/^# (.*$)/gim, "

$1

"); + + // bold text + html = html.replace(/\*\*(.*?)\*\*/g, "$1"); + + // italic text + html = html.replace(/\*(.*?)\*/g, "$1"); + + // links [text](url) + html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1'); + + // code inline `code` + // html = html.replace(/`([^`]+)`/g, "$1"); + + // code blocks ``` + html = html.replace(/```([\s\S]*?)```/g, "
$1
"); + + // line breaks + html = html.replace(/\n\n/g, "

"); + html = "

" + html + "

"; + + // empty paragraphs + // html = html.replace(/

<\/p>/g, ""); + + return html; +} + +function generateBlogPost(markdownFile) { + const content = fs.readFileSync(markdownFile, "utf8"); + const fileName = path.basename(markdownFile, ".md"); + + // extract title from first # header or use filename + const titleMatch = content.match(/^# (.*)$/m); + const title = titleMatch ? titleMatch[1] : fileName; + + const htmlContent = markdownToHtml(content); + + const template = ` + + + + + + ${title} + + + + +

+ ← Retour Γ  l'accueil +
+
+
+ ${htmlContent} +
+
+ + + `; + + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); + } + + const outputPath = path.join(outputDir, `${fileName}.html`); + fs.writeFileSync(outputPath, template); + + console.log(`articled generated: ${outputPath}`); + + return outputPath; +} + +// processes all markdown files in articles directory +function convertAllMarkdownArticles() { + if (!fs.existsSync(inputDir)) { + console.log(`Directory ${inputDir} does not exist`); + + return; + } + + const files = fs.readdirSync(inputDir) + .filter((file) => file.endsWith(".md")); + + files.forEach((file) => { + const filePath = path.join(inputDir, file); + generateBlogPost(filePath, outputDir); + }); + + // Generate index page + generateBlogIndex(files, outputDir); +} + +function generateBlogIndex(markdownFiles, outputDir) { + const articles = markdownFiles.map((file) => { + const fileName = path.basename(file, ".md"); + + return `
  • ${fileName}
  • `; + }).join("\n "); + + const indexTemplate = ` + + + + + + Blog - NodeSecure + + + + +
    + ← Retour Γ  l'accueil +

    Articles de blog

    +
    +
    + +
    + + + `; + + const indexPath = path.join(outputDir, "index.html"); + fs.writeFileSync(indexPath, indexTemplate); + console.log(`blog index generated: ${indexPath}`); +} + +(() => { + convertAllMarkdownArticles(); +})(); + From 57dbf276a50e33cb6654bca81920763920516f6c Mon Sep 17 00:00:00 2001 From: nasfernane Date: Tue, 16 Sep 2025 23:53:14 +0200 Subject: [PATCH 02/12] feat: implementing blog --- .gitignore | 1 + articles/JS-X-Ray-6.0.md | 2 +- articles/announcing-nodesecure-vuln-era.md | 4 +- ...you-need-to-know-about-package-managers.md | 2 +- articles/securizing-your-github-org.md | 2 +- blog/JS-X-Ray-6.0.html | 271 +++++----- blog/announcing-nodesecure-vuln-era.html | 242 ++++----- blog/article-base-template.html | 59 +++ ...u-need-to-know-about-package-managers.html | 482 ++++++++---------- blog/index-base-template.html | 60 +++ blog/index.html | 174 ++++++- blog/securizing-your-github-org.html | 313 ++++++------ index.html | 12 +- package-lock.json | 13 + package.json | 3 +- public/css/blog.css | 202 ++++++++ public/css/index.css | 39 +- public/css/reset.css | 4 +- src/build-articles.js | 235 +++++---- vite.config.js | 31 +- 20 files changed, 1342 insertions(+), 809 deletions(-) create mode 100644 blog/article-base-template.html create mode 100644 blog/index-base-template.html create mode 100644 public/css/blog.css diff --git a/.gitignore b/.gitignore index 1170717..37d13a0 100644 --- a/.gitignore +++ b/.gitignore @@ -134,3 +134,4 @@ dist .yarn/build-state.yml .yarn/install-state.gz .pnp.* + diff --git a/articles/JS-X-Ray-6.0.md b/articles/JS-X-Ray-6.0.md index 19082da..dc66124 100644 --- a/articles/JS-X-Ray-6.0.md +++ b/articles/JS-X-Ray-6.0.md @@ -1,6 +1,6 @@ --- title: JS-X-Ray 6.0 -author: Thomas.G +author: Thomas date: 16/01/2023 --- diff --git a/articles/announcing-nodesecure-vuln-era.md b/articles/announcing-nodesecure-vuln-era.md index 05847c3..fa211ec 100644 --- a/articles/announcing-nodesecure-vuln-era.md +++ b/articles/announcing-nodesecure-vuln-era.md @@ -1,6 +1,6 @@ --- title: NodeSecure Vuln-era -author: Thomas.G +author: Thomas date: 21/07/2022 --- @@ -20,7 +20,7 @@ Vulnera is a package that allows you to **programmatically** fetch your Node.js - NPM Audit ([Github Advisory Database](https://github.com/advisories)) - [Sonatype OSS Index](https://ossindex.sonatype.org/) -- `deprecated` [Node.js Security WG Database](https://github.com/nodejs/security-wg/tree/main/vuln) +- deprecated [Node.js Security WG Database](https://github.com/nodejs/security-wg/tree/main/vuln) - Snyk > πŸ“’ Feel free to push new sources (we have [a guide](https://github.com/NodeSecure/vuln/blob/main/docs/adding_new_strategy.md) on how to add/contribute one). diff --git a/articles/everything-you-need-to-know-about-package-managers.md b/articles/everything-you-need-to-know-about-package-managers.md index 5834ec4..8f6797c 100644 --- a/articles/everything-you-need-to-know-about-package-managers.md +++ b/articles/everything-you-need-to-know-about-package-managers.md @@ -1,6 +1,6 @@ --- title: Everything you need to know: package managers -author: Antoine.C +author: Antoine date: 18/10/2022 --- diff --git a/articles/securizing-your-github-org.md b/articles/securizing-your-github-org.md index e11497a..4264bb6 100644 --- a/articles/securizing-your-github-org.md +++ b/articles/securizing-your-github-org.md @@ -1,6 +1,6 @@ --- title: Securizing your GitHub org -author: Thomas.G +author: Thomas date: 19/02/2023 --- diff --git a/blog/JS-X-Ray-6.0.html b/blog/JS-X-Ray-6.0.html index 7884560..ceb9586 100644 --- a/blog/JS-X-Ray-6.0.html +++ b/blog/JS-X-Ray-6.0.html @@ -1,165 +1,160 @@ - - - - - - - JS-X-Ray-6.0 - - - - -
    - ← Retour Γ  l'accueil -
    -
    -
    -

    --- -title: JS-X-Ray 6.0 -author: Thomas.G -date: 16/01/2023 ---- - -Hello πŸ‘‹ - -It's been a while since the last article on JS-X-Ray 😲! - -{% link https://dev.to/nodesecure/js-x-ray-3-0-0-3ddn %} - -In this article I will present you the latest major version πŸ‘€. I didn't do an article on version 4 and 5 because they didn't introduce new features (only breaking changes on the API). - + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +

    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    JS-X-Ray 6.0

    +

    Hello πŸ‘‹

    +

    It's been a while since the last article on JS-X-Ray 😲!

    +

    {% link https://dev.to/nodesecure/js-x-ray-3-0-0-3ddn %}

    +

    In this article I will present you the latest major version πŸ‘€. I didn't do an article on version 4 and 5 because they didn't introduce new features (only breaking changes on the API).

    πŸ“’ What is JS-X-Ray ?

    - -If you are new in town, JS-X-Ray is an open source JavaScript SAST (Static Application Security Testing). The tool analyzes your JavaScript sources for patterns that may affect the security and quality of your project 😎. - -Among the notable features: - -- Retrieving dependencies (CJS & ESM support) and detecting suspicious import/require. -- Detecting unsafe RegEx. -- Detecting obfuscated source (and provide hints on the tool used). - -As well as a lot of other detections. - +

    If you are new in town, JS-X-Ray is an open source JavaScript SAST (Static Application Security Testing). The tool analyzes your JavaScript sources for patterns that may affect the security and quality of your project 😎.

    +

    Among the notable features:

    +
      +
    • Retrieving dependencies (CJS & ESM support) and detecting suspicious import/require.
    • +
    • Detecting unsafe RegEx.
    • +
    • Detecting obfuscated source (and provide hints on the tool used).
    • +
    +

    As well as a lot of other detections.

    Major release 4 and 5

    - -These versions introduced changes on warnings (and we improved how we manage them in the codebase). We added new descriptors for each of them: - -- i18n (for translation in CI or CLI). -- experimental -- severity (Information, Warning, Critical) - -Those information are visible in the NodeSecure CLI interface: - -!NodeSecure - +

    These versions introduced changes on warnings (and we improved how we manage them in the codebase). We added new descriptors for each of them:

    +
      +
    • i18n (for translation in CI or CLI).
    • +
    • experimental
    • +
    • severity (Information, Warning, Critical)
    • +
    +

    Those information are visible in the NodeSecure CLI interface:

    +

    NodeSecure

    Major release 6

    - -🐬 Ok, let's dive into this major release to discover the surprises πŸŽ‰ it has in store for us. - +

    🐬 Ok, let's dive into this major release to discover the surprises πŸŽ‰ it has in store for us.

    πŸš€ Introducing VariableTracer

    - -Almost a year of work on this new mechanism / class that brings a whole new dimension to JS-X-Ray. - -
    js
    -const tracer = new VariableTracer()
    +

    Almost a year of work on this new mechanism / class that brings a whole new dimension to JS-X-Ray.

    +
    const tracer = new VariableTracer()
       .enableDefaultTracing()
    -  .trace("crypto.createHash", {
    -    followConsecutiveAssignment: true, moduleName: "crypto"
    +  .trace("crypto.createHash", {
    +    followConsecutiveAssignment: true, moduleName: "crypto"
       });
     
     tracer.walk(node);
     
    - -This class is able to follow all declarations, assignments and patterns (and those even through very obscure patterns). - -
    js
    -const aA = Function.prototype.call;
    +

    This class is able to follow all declarations, assignments and patterns (and those even through very obscure patterns).

    +
    const aA = Function.prototype.call;
     const bB = require;
     
    -const crypto = aA.call(bB, bB, "crypto");
    +const crypto = aA.call(bB, bB, "crypto");
     const cr = crypto.createHash;
    -cr("md5"); // weak-crypto warning is throw here
    +cr("md5"); // weak-crypto warning is throw here
     
    - -This allows us to implement Probes in a much simpler way (which makes maintenance and testing much easier). - -Here an example with the `isWeakCrypto` probe: - -
    js
    -function validateNode(node, { tracer }) {
    +

    This allows us to implement Probes in a much simpler way (which makes maintenance and testing much easier).

    +

    Here an example with the isWeakCrypto probe:

    +
    function validateNode(node, { tracer }) {
       const id = getCallExpressionIdentifier(node);
    -  if (id === null || !tracer.importedModules.has("crypto")) {
    +  if (id === null || !tracer.importedModules.has("crypto")) {
         return [false];
       }
     
       const data = tracer.getDataFromIdentifier(id);
     
       return [
    -    data !== null &&
    -    data.identifierOrMemberExpr === "crypto.createHash"
    +    data !== null &&
    +    data.identifierOrMemberExpr === "crypto.createHash"
       ];
     }
     
    - -By default the Tracer follows all ways of `requiring` dependencies with CJS and also usage of `eval` or `Function`. - - +

    By default the Tracer follows all ways of requiring dependencies with CJS and also usage of eval or Function.

    🚧 Removing unsafe-assign warning

    - -This warning was required at the beginning of the project because it was difficult for me to correctly identify some malicious patterns. - -!NodeSecure - -However, with the introduction of the new Tracer, which is very complete and precise, this warning no longer makes sense has it only generates unnecessary noise and false positives. - +

    This warning was required at the beginning of the project because it was difficult for me to correctly identify some malicious patterns.

    +

    NodeSecure

    +

    However, with the introduction of the new Tracer, which is very complete and precise, this warning no longer makes sense has it only generates unnecessary noise and false positives.

    πŸ“œ Better ESM source parsing

    - -We previously had a lot of `parsing-error` warnings because the NodeSecure scanner failed to detect if the file was using either CJS or ESM. - -That new version will automatically retry with ESM enabled if it fails with CJS. - +

    We previously had a lot of parsing-error warnings because the NodeSecure scanner failed to detect if the file was using either CJS or ESM.

    +

    That new version will automatically retry with ESM enabled if it fails with CJS.

    πŸ“‰ Reducing false positives

    - -To continue the momentum of the previous sections. This version drops a lot of warnings and significantly improves others. - -- Reducing false positives for `encoded-literal` warning by introducing new way of detecting safe values. -- Improve `short-identifiers` by also storing ClassDeclaration, MethodDefinition and Function parameters. - -We are also introducing a new `suspicious-file` warning when a file contain more than 10 encoded-literal warnings to avoid having file with hundreds or thousands of warnings. - -Of the 500 most popular NPM packages, we previously had 24k warnings with version 5. The latest version brings that number down to approximatively 5k warnings. - +

    To continue the momentum of the previous sections. This version drops a lot of warnings and significantly improves others.

    +
      +
    • Reducing false positives for encoded-literal warning by introducing new way of detecting safe values.
    • +
    • Improve short-identifiers by also storing ClassDeclaration, MethodDefinition and Function parameters.
    • +
    +

    We are also introducing a new suspicious-file warning when a file contain more than 10 encoded-literal warnings to avoid having file with hundreds or thousands of warnings.

    +

    Of the 500 most popular NPM packages, we previously had 24k warnings with version 5. The latest version brings that number down to approximatively 5k warnings.

    πŸ”¬ Improving coverage

    - -A lot of work has been done to add unit tests on all the probes of the project. We are near 100% of coverage πŸ’ͺ. - -!NodeSecure - -Thanks to the amazing work of our contributors: - -- Vincent DHENNIN - @kawacrepe -- Pierre DEMAILLY -- Mathieu KA -- M4gie - -

    πŸ‘€ What's next ?

    - -Here what I'm working for the next major release: - -- Adding support of TypeScript sources (probably by allowing a customization of the parser). -- A new API that allows to dynamically extend the SAST with new custom probes (and custom warnings). -- Introducing new built-in detections and warnings (unsafe URL etc). - -I will continue to work to reduce the number of false positives and keep improving obfuscated codes detection. - ---- - -Please think to drop a star on github ❀️! - -That's it for today! Thanks for reading me πŸ˜‰ -

    -
    -
    - - - \ No newline at end of file +

    A lot of work has been done to add unit tests on all the probes of the project. We are near 100% of coverage πŸ’ͺ.

    +

    NodeSecure

    +

    Thanks to the amazing work of our contributors:

    + +

    πŸ‘€ What's next ?

    +

    Here what I'm working for the next major release:

    +
      +
    • Adding support of TypeScript sources (probably by allowing a customization of the parser).
    • +
    • A new API that allows to dynamically extend the SAST with new custom probes (and custom warnings).
    • +
    • Introducing new built-in detections and warnings (unsafe URL etc).
    • +
    +

    I will continue to work to reduce the number of false positives and keep improving obfuscated codes detection.

    +
    +

    Please think to drop a star on github ❀️!

    +

    That's it for today! Thanks for reading me πŸ˜‰

    + + +
    +
    + + + + + \ No newline at end of file diff --git a/blog/announcing-nodesecure-vuln-era.html b/blog/announcing-nodesecure-vuln-era.html index 3aea69d..3f744de 100644 --- a/blog/announcing-nodesecure-vuln-era.html +++ b/blog/announcing-nodesecure-vuln-era.html @@ -1,50 +1,77 @@ - - - - - - - announcing-nodesecure-vuln-era - - - - -
    - ← Retour Γ  l'accueil -
    -
    -
    -

    --- -title: NodeSecure Vuln-era -author: Thomas.G -date: 21/07/2022 ---- - -Hello πŸ‘‹, - -Back for a little article about the rebranding of one of the NodeSecure tools: Vulnera (previously vuln, the vuln-era has begun!). - -An opportunity for me to also write about this wonderful project that was born with the redesign of the back-end less than a year ago ⌚. If you don't remember I wrote an article: - -{% link https://dev.to/fraxken/announcing-new-node-secure-back-end-1dp9 %} - -Don't wait and dive in 🌊 with me to discover this tool πŸ’ƒ. - + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +

    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    NodeSecure Vuln-era

    +

    Hello πŸ‘‹,

    +

    Back for a little article about the rebranding of one of the NodeSecure tools: Vulnera (previously vuln, the vuln-era has begun!).

    +

    An opportunity for me to also write about this wonderful project that was born with the redesign of the back-end less than a year ago ⌚. If you don't remember I wrote an article:

    +

    {% link https://dev.to/fraxken/announcing-new-node-secure-back-end-1dp9 %}

    +

    Don't wait and dive in 🌊 with me to discover this tool πŸ’ƒ.

    What is Vulnera ? πŸ‘€

    - -Vulnera is a package that allows you to programmatically fetch your Node.js project vulnerabilities from multiple sources or strategies: - -- NPM Audit (Github Advisory Database) -- Sonatype OSS Index -- `deprecated` Node.js Security WG Database -- Snyk - -> πŸ“’ Feel free to push new sources (we have a guide on how to add/contribute one). - -The code was originally designed for vulnerability management within the Scanner. Yet, its API is evolving with the objective of making it a full-fledged project. - -
    js
    -import * as vulnera from "@nodesecure/vulnera";
    +

    Vulnera is a package that allows you to programmatically fetch your Node.js project vulnerabilities from multiple sources or strategies:

    + +
    +

    πŸ“’ Feel free to push new sources (we have a guide on how to add/contribute one).

    +
    +

    The code was originally designed for vulnerability management within the Scanner. Yet, its API is evolving with the objective of making it a full-fledged project.

    +
    import * as vulnera from "@nodesecure/vulnera";
     
     const def = await vulnera.setStrategy(
       vulnera.strategies.NPM_AUDIT
    @@ -55,54 +82,44 @@ 

    What is Vulnera ? πŸ‘€

    }); console.log(vulnerabilities);
    -

    Standard vulnerability format πŸ‘―

    - -We have created a standard format to reconcile the different sources. - -
    ts
    -export interface StandardVulnerability {
    -  / Unique identifier for the vulnerability /
    +

    We have created a standard format to reconcile the different sources.

    +
    export interface StandardVulnerability {
    +  /** Unique identifier for the vulnerability **/
       id?: string;
    -  / Vulnerability origin, either Snyk, NPM or NodeSWG /
    +  /** Vulnerability origin, either Snyk, NPM or NodeSWG **/
       origin: Origin;
    -  / Package associated with the vulnerability /
    +  /** Package associated with the vulnerability **/
       package: string;
    -  / Vulnerability title /
    +  /** Vulnerability title **/
       title: string;
    -  / Vulnerability description /
    +  /** Vulnerability description **/
       description?: string;
    -  / Vulnerability link references on origin's website /
    +  /** Vulnerability link references on origin's website **/
       url?: string;
    -  / Vulnerability severity levels given the strategy /
    +  /** Vulnerability severity levels given the strategy **/
       severity?: Severity;
    -  / Common Vulnerabilities and Exposures dictionary */
    +  /** Common Vulnerabilities and Exposures dictionary */
       cves?: string[];
    -  / Common Vulnerability Scoring System (CVSS) /
    +  /** Common Vulnerability Scoring System (CVSS) **/
       cvssVector?: string;
    -  / CVSS Score /
    +  /** CVSS Score **/
       cvssScore?: number;
    -  / The range of vulnerable versions */
    +  /** The range of vulnerable versions */
       vulnerableRanges: string[];
    -  / The set of versions that are vulnerable /
    +  /** The set of versions that are vulnerable **/
       vulnerableVersions: string[];
    -  / The set of versions that are patched /
    +  /** The set of versions that are patched **/
       patchedVersions?: string;
    -  / Overview of available patches /
    +  /** Overview of available patches **/
       patches?: Patch[];
     }
     
    - -You can always use the original formats of each source of course 😊. We have implemented and exposed TypeScript interfaces for each of them. - -!NodeSecure types - +

    You can always use the original formats of each source of course 😊. We have implemented and exposed TypeScript interfaces for each of them.

    +

    NodeSecure types

    Usage in Scanner πŸ”¬

    - -On the scanner we have all the necessary information because we go through the dependency tree πŸŽ„. At the end of the process, we recover all vulnerabilities by iterating spec by spec within the hydratePayloadDependencies strategy method. - -
    js
    -const {
    +

    On the scanner we have all the necessary information because we go through the dependency tree πŸŽ„. At the end of the process, we recover all vulnerabilities by iterating spec by spec within the hydratePayloadDependencies strategy method.

    +
    const {
       hydratePayloadDependencies,
       strategy
     } = await vulnera.setStrategy(
    @@ -115,44 +132,39 @@ 

    Usage in Scanner πŸ”¬

    payload.vulnerabilityStrategy = strategy;
    - -The following diagram explains the overall behavior and interactions between the Scanner and Vulnera. -!NodeSecure - -If you want to learn more about the Payload you can check the TypeScript interface here. - -

    What's next ? πŸš€

    - -Some sources are more difficult to exploit than others (for NPM we use Arborist which simplifies our lives). - -
    js
    -const { vulnerabilities } = (await arborist.audit()).toJSON();
    +

    The following diagram explains the overall behavior and interactions between the Scanner and Vulnera. +NodeSecure

    +

    If you want to learn more about the Payload you can check the TypeScript interface here.

    +

    What's next ? πŸš€

    +

    Some sources are more difficult to exploit than others (for NPM we use Arborist which simplifies our lives).

    +
    const { vulnerabilities } = (await arborist.audit()).toJSON();
     
    - -However, we have to think and create mechanics to exploit sources like Sonatype 😨. This is required for API like `getVulnerabilities()`. - -Among the major subjects and ideas we are working on: -- Create a private database to benchmark the sources between them (see #29). -- Merging multiple sources in one (see #25). -- Fetch vulnerabilities of a given remote package (with support for private registry like verdaccio). At the moment we only support the analysis of a local manifest or a payload of the scanner. - +

    However, we have to think and create mechanics to exploit sources like Sonatype 😨. This is required for API like getVulnerabilities().

    +

    Among the major subjects and ideas we are working on:

    +
      +
    • Create a private database to benchmark the sources between them (see #29).
    • +
    • Merging multiple sources in one (see #25).
    • +
    • Fetch vulnerabilities of a given remote package (with support for private registry like verdaccio). At the moment we only support the analysis of a local manifest or a payload of the scanner.
    • +

    Credits πŸ™‡

    - -This project owes much to our core collaborator Antoine COULON who invested a lot of energy to improve it πŸ’ͺ. - -> Fun fact: its first contribution 🐀 on NodeSecure was also on the old version of the code Scanner that managed vulnerabilities. - -But I don't forget individual contributions πŸ‘ -- Mathieu Kahlaoui for adding the getVulnerabilities() API -- Oleh Sych for adding Snyk strategy -- Medhi for his work on the logo - ---- - -Thanks πŸ™ for reading me and see you soon for another article! -

    -
    -
    - - - \ No newline at end of file +

    This project owes much to our core collaborator Antoine COULON who invested a lot of energy to improve it πŸ’ͺ.

    +
    +

    Fun fact: its first contribution 🐀 on NodeSecure was also on the old version of the code Scanner that managed vulnerabilities.

    +
    +

    But I don't forget individual contributions πŸ‘

    + +
    +

    Thanks πŸ™ for reading me and see you soon for another article!

    + + +
    +
    + + + + + \ No newline at end of file diff --git a/blog/article-base-template.html b/blog/article-base-template.html new file mode 100644 index 0000000..dcecaad --- /dev/null +++ b/blog/article-base-template.html @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    +
    +
    + + + + + \ No newline at end of file diff --git a/blog/everything-you-need-to-know-about-package-managers.html b/blog/everything-you-need-to-know-about-package-managers.html index b06006d..3480cd8 100644 --- a/blog/everything-you-need-to-know-about-package-managers.html +++ b/blog/everything-you-need-to-know-about-package-managers.html @@ -1,159 +1,157 @@ - - - - - - - everything-you-need-to-know-about-package-managers - - - - -
    - ← Retour Γ  l'accueil -
    -
    -
    -

    --- -title: Everything you need to know: package managers -author: Antoine.C -date: 18/10/2022 ---- - -Welcome everyone! This article is the first one of the Everything you need to know, a Software Engineering series. - -In this series, I will try to give you a solid basic understanding about Software Engineering concepts I consider important. - -All modern computer systems include tools that automate the process of installing, uninstalling and updating software. - -This responsibility is that of a package manager and several can intervene within the same computer system. - + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +

    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    Everything you need to know: package managers

    +

    Welcome everyone! This article is the first one of the Everything you need to know, a Software Engineering series.

    +

    In this series, I will try to give you a solid basic understanding about Software Engineering concepts I consider important.

    +

    All modern computer systems include tools that automate the process of installing, uninstalling and updating software.

    +

    This responsibility is that of a package manager and several can intervene within the same computer system.

    Operating system

    - -The majority of Unix-based operating systems embed a package manager as standard, providing a multitude of different packages very simply. - -If you have ever used a Linux distribution such as Ubuntu or Debian, you've probably used a package manager before. If I say `apt-get update` does that ring a bell? - -This command tells APT to update all versions of packages installed. APT (Advanced Packaging Tool)) is a package manager embedded very widely as standard on Linux operating systems. To install a package, you can for example enter the command `apt-get install `. - +

    The majority of Unix-based operating systems embed a package manager as standard, providing a multitude of different packages very simply.

    +

    If you have ever used a Linux distribution such as Ubuntu or Debian, you've probably used a package manager before. If I say apt-get update does that ring a bell?

    +

    This command tells APT to update all versions of packages installed. APT (Advanced Packaging Tool) is a package manager embedded very widely as standard on Linux operating systems. To install a package, you can for example enter the command apt-get install <package>.

    Programming language

    - -Most programming languages ​​can embed their own with package managers, either natively or provided within their respective ecosystem. - -Take for example npm, the default package manager for Node.js. We can also mention pip for Python, NuGet for C#, Composer for PHP, etc. Similar to APT, npm makes it easy to install packages using the `npm install ` command. - -> For this article, I decided to take npm as an example. -> npm is indeed a very good support to highlight the advantages but also the disadvantages that a package manager can have. -> The advantages and disadvantages listed in the following part are valid for all package managers. - -> npm is installed alongside Node.js. To reproduce these examples, [you only need to install Node.js here]. - -In four parts, we will see what are the main reasons for such an expansion of package managers to all layers of a computer system. - -1. Ease of use and maintenance of packages - -The main interest of a package manager is obviously to simplify the installation of dependencies external to our application. Before the rise of npm in January 2010, the dependencies of a JavaScript application were mostly installed manually. By "manual installation" I mean: -- downloading a zip archive from a remote server -- unzipping the archive in the project -- manual referencing of the installed version, and this with each update of a dependency. - -With a package manager like npm, we therefore benefit from: -- Simplified installation of a package `npm install ` -- The simplified update of a package `npm update ` -- The simplified removal of a package `npm uninstall ` - -The packages are installed in a __node_modules__ folder adjacent to the application and which is entirely managed by npm. All packages located in the node_modules folder can be directly imported from the application. - -> In general, each programming language natively embeds its own module resolution management mechanism. - -1.1. Install - -In order for a package to be installed, we first need a name which is in most cases used as a unique identifier. Naming conventions can differ from one ecosystem to another. - -
    bash
    -$ npm install rxjs 
    +

    Most programming languages ​​can embed their own with package managers, either natively or provided within their respective ecosystem.

    +

    Take for example npm, the default package manager for Node.js. We can also mention pip for Python, NuGet for C#, Composer for PHP, etc. Similar to APT, npm makes it easy to install packages using the npm install <package> command.

    +
    +

    For this article, I decided to take npm as an example. +npm is indeed a very good support to highlight the advantages but also the disadvantages that a package manager can have. +The advantages and disadvantages listed in the following part are valid for all package managers.

    +
    +
    +

    npm is installed alongside Node.js. To reproduce these examples, [you only need to install Node.js here].

    +
    +

    In four parts, we will see what are the main reasons for such an expansion of package managers to all layers of a computer system.

    +

    1. Ease of use and maintenance of packages

    +

    The main interest of a package manager is obviously to simplify the installation of dependencies external to our application. Before the rise of npm in January 2010, the dependencies of a JavaScript application were mostly installed manually. By "manual installation" I mean:

    +
      +
    • downloading a zip archive from a remote server
    • +
    • unzipping the archive in the project
    • +
    • manual referencing of the installed version, and this with each update of a dependency.
    • +
    +

    With a package manager like npm, we therefore benefit from:

    +
      +
    • Simplified installation of a package npm install <package>
    • +
    • The simplified update of a package npm update <package>
    • +
    • The simplified removal of a package npm uninstall <package>
    • +
    +

    The packages are installed in a node_modules folder adjacent to the application and which is entirely managed by npm. All packages located in the node_modules folder can be directly imported from the application.

    +
    +

    In general, each programming language natively embeds its own module resolution management mechanism.

    +
    +

    1.1. Install

    +

    In order for a package to be installed, we first need a name which is in most cases used as a unique identifier. Naming conventions can differ from one ecosystem to another.

    +
    $ npm install rxjs 
     
    - -With this command, the package manager will search within the registry for a package that has the name rxjs. When the version is not specified, the package manager will usually install the latest available version. - -1.2. Use - -
    javascript
    -// ECMAScript Modules (ESM)
    -import { of } from "rxjs";
    +

    With this command, the package manager will search within the registry for a package that has the name rxjs. When the version is not specified, the package manager will usually install the latest available version.

    +

    1.2. Use

    +
    // ECMAScript Modules (ESM)
    +import { of } from "rxjs";
     // CommonJS
    -const { of } = require("rxjs");
    +const { of } = require("rxjs");
     
    - -The module systems integrated into the programming languages ​​make it possible to import a library installed locally and sometimes remotely (like Go or Deno for example). In this case with Node.js, the package must be installed locally in a node_modules folder. With Node.js, the module resolution algorithm allows the dependency to be in a node_modules folder either adjacent to the source code or in a parent folder (which sometimes leads to an unexpected behavior). - +

    The module systems integrated into the programming languages ​​make it possible to import a library installed locally and sometimes remotely (like Go or Deno for example). In this case with Node.js, the package must be installed locally in a node_modules folder. With Node.js, the module resolution algorithm allows the dependency to be in a node_modules folder either adjacent to the source code or in a parent folder (which sometimes leads to an unexpected behavior).

    2. Managing the consistency of installed packages

    - -Now, let's dive into a little more detail on one very important aspect that a package manager must manage: state consistency between installed packages. So far, installing a package looks like a trivial task, which is just to automate downloading a package of a certain version and making it available in a conventional folder that the application has access to. - -However this management of consistency between packages turns out to be relatively difficult and the way of modeling the dependency tree varies according to the ecosystems. Most of the time, we talk about a dependency tree, but we can also talk about a dependency graph, in particular a directed graph. - -If you are not familiar with the concept of directed graphs, I invite you to read the series of articles I wrote about it on dev.to with examples in JavaScript. - -The implementations of these data structures can be drastically different depending on the ecosystem of a package manager, but also between package managers of the same ecosystem (npm, yarn, pnpm for Node.js for example). - -> How to ensure that all developers share the same dependencies and therefore the same versions of each underlying library? - -Still in the context of npm, let's take for example a very simple list of dependencies, expressed as an object in the _package.json_ file: - -package.json - -
    json
    -{ 
    -  "dependencies": {
    -    "myDependencyA": "<0.1.0"
    +

    Now, let's dive into a little more detail on one very important aspect that a package manager must manage: state consistency between installed packages. So far, installing a package looks like a trivial task, which is just to automate downloading a package of a certain version and making it available in a conventional folder that the application has access to.

    +

    However this management of consistency between packages turns out to be relatively difficult and the way of modeling the dependency tree varies according to the ecosystems. Most of the time, we talk about a dependency tree, but we can also talk about a dependency graph, in particular a directed graph.

    +

    If you are not familiar with the concept of directed graphs, I invite you to read the series of articles I wrote about it on dev.to with examples in JavaScript.

    +

    The implementations of these data structures can be drastically different depending on the ecosystem of a package manager, but also between package managers of the same ecosystem (npm, yarn, pnpm for Node.js for example).

    +
    +

    How to ensure that all developers share the same dependencies and therefore the same versions of each underlying library?

    +
    +

    Still in the context of npm, let's take for example a very simple list of dependencies, expressed as an object in the package.json file:

    +

    package.json

    +
    { 
    +  "dependencies": {
    +    "myDependencyA": "<0.1.0"
       }
     }
     
    - -This object describes a dependency of our project on the _myDependencyA_ library downloadable from the npm registry. Semantic Versioning here constrains the version of the library to be installed (here lower than 0.1.0). - -> Semantic version management (commonly known as SemVer) is the application of a very precise specification to characterize the version of software. For more information on this subject, I invite you to take a look at the official specification https://semver.org/lang/fr/ - -In our case, by remaining on the classic `..` scheme, we express the possibility of installing all the versions of _myDependencyA_ from "0.0.1" to "0.0.9". This therefore means that any version of the dependency that respects the range is considered valid. On the other hand, this also means that if a developer A installs the dependency at 2 p.m. and a developer B installs the dependency at 5 p.m., they may both not have the same dependency tree if ever a new version of _myDependencyA_ is released in the meantime. - -The npm dependency resolution algorithm will by default favor the installation of the most recent dependency that respects the semantic management described in the _package.json_. By specifying `npm install myDependencyA`, the most recent version of _myDependencyA_ will be installed respecting the constraint "<1.0.0" (version strictly lower than "1.0.0"). - -The major problem with this approach is the lack of stability and reproducibility of the dependency tree from one computer to another, for example between developers or even on the machine used in production. Imagine that version 0.0.9 of _myDependencyA_ has just been released with a bug and your production machine is about to do an `npm install` on Friday at 5:59 PM… - -!Production deployment on friday night - -The very simple example is often referred as `version drift`. This is why a single description file (in this case package.json) cannot be enough to guarantee an identical and reproducible representation of a dependency tree. - -Other reasons include: - -- using a different version of the package manager whose dependency installation algorithm may change. -- publishing a new version of an indirect dependency (the dependencies of the dependencies we list in the package.json here), which would result in the new version therefore being uploaded and updated. -- the use of a different registry which for the same version of a dependency exposes two different libraries at a time T. - -Lockfiles to the rescue - -To ensure the reproducibility of a dependency tree, we therefore need more information that would ideally describe the current state of our dependency tree. This is exactly what lockfiles do. These are files created and updated when the dependencies of a project are modified. - -A lockfile is generally written in _JSON_ or _YAML_ format to simplify the readability and understanding of the dependency tree by a human. A lockfile makes it possible to describe the dependency tree in a very precise way and therefore to make it deterministic and reproducible from one environment to another. So it's important to commit this file to Git and make sure everyone is sharing the same lockfile. - -package-lock.json - -
    json
    -{
    -  "name": "myProject",
    -  "version": "1.0.0",
    -  "dependencies": {
    -    "myDependencyA": {
    -      "version": "0.0.5",
    -      "resolved": "https://registry.npmjs.org/myDependencyA/-/myDependencyA-0.0.5.tgz",
    -      "integrity": "sha512-DeAdb33F+"
    -      "dependencies": {
    -        "B": {
    -          "version": "0.0.1",
    -          "resolved": "https://registry.npmjs.org/B/-/B-0.0.1.tgz",
    -          "integrity": "sha512-DeAdb33F+"
    -          "dependencies": {
    +

    This object describes a dependency of our project on the myDependencyA library downloadable from the npm registry. Semantic Versioning here constrains the version of the library to be installed (here lower than 0.1.0).

    +
    +

    Semantic version management (commonly known as SemVer) is the application of a very precise specification to characterize the version of software. For more information on this subject, I invite you to take a look at the official specification https://semver.org/lang/fr/

    +
    +

    In our case, by remaining on the classic <major>.<minor>.<patch> scheme, we express the possibility of installing all the versions of myDependencyA from "0.0.1" to "0.0.9". This therefore means that any version of the dependency that respects the range is considered valid. On the other hand, this also means that if a developer A installs the dependency at 2 p.m. and a developer B installs the dependency at 5 p.m., they may both not have the same dependency tree if ever a new version of myDependencyA is released in the meantime.

    +

    The npm dependency resolution algorithm will by default favor the installation of the most recent dependency that respects the semantic management described in the package.json. By specifying npm install myDependencyA, the most recent version of myDependencyA will be installed respecting the constraint "<1.0.0" (version strictly lower than "1.0.0").

    +

    The major problem with this approach is the lack of stability and reproducibility of the dependency tree from one computer to another, for example between developers or even on the machine used in production. Imagine that version 0.0.9 of myDependencyA has just been released with a bug and your production machine is about to do an npm install on Friday at 5:59 PM…

    +

    Production deployment on friday night

    +

    The very simple example is often referred as version drift. This is why a single description file (in this case package.json) cannot be enough to guarantee an identical and reproducible representation of a dependency tree.

    +

    Other reasons include:

    +
      +
    • using a different version of the package manager whose dependency installation algorithm may change.
    • +
    • publishing a new version of an indirect dependency (the dependencies of the dependencies we list in the package.json here), which would result in the new version therefore being uploaded and updated.
    • +
    • the use of a different registry which for the same version of a dependency exposes two different libraries at a time T.
    • +
    +

    Lockfiles to the rescue

    +

    To ensure the reproducibility of a dependency tree, we therefore need more information that would ideally describe the current state of our dependency tree. This is exactly what lockfiles do. These are files created and updated when the dependencies of a project are modified.

    +

    A lockfile is generally written in JSON or YAML format to simplify the readability and understanding of the dependency tree by a human. A lockfile makes it possible to describe the dependency tree in a very precise way and therefore to make it deterministic and reproducible from one environment to another. So it's important to commit this file to Git and make sure everyone is sharing the same lockfile.

    +

    package-lock.json

    +
    {
    +  "name": "myProject",
    +  "version": "1.0.0",
    +  "dependencies": {
    +    "myDependencyA": {
    +      "version": "0.0.5",
    +      "resolved": "https://registry.npmjs.org/myDependencyA/-/myDependencyA-0.0.5.tgz",
    +      "integrity": "sha512-DeAdb33F+"
    +      "dependencies": {
    +        "B": {
    +          "version": "0.0.1",
    +          "resolved": "https://registry.npmjs.org/B/-/B-0.0.1.tgz",
    +          "integrity": "sha512-DeAdb33F+"
    +          "dependencies": {
                 // dependencies of B
               }
             }
    @@ -162,129 +160,93 @@ 

    2. Managing the consistency of installed packages

    } }
    - -For npm, the basic lockfile is called _package-lock.json_. In the snippet above, we can precisely see several important information: -- The version of myDependencyA is fixed at "0.0.5" so even if a new version is released, npm will install "0.0.5" no matter what. -- Each indirect dependency describes its set of dependencies with versions that also describe their own versioning constraints. -- In addition to the version, the contents of the dependencies can be checked with the comparison of hashes which can vary according to the registers used. - -A lockfile therefore tries to accurately describes the dependency tree, which allows it to remain consistent and reproducible over time at each installation. - -⚠️ But... - -Lockfiles don't solve all inconsistency problems! Package managers implementations of the dependency graph can sometimes lead to inconsistencies. For a long time, npm's implementation introduced Phantom Dependencies and also NPM doppelgangers which are very well explained on the Rush.js documentation website (advanced topics that are out of the scope of this blog post). - +

    For npm, the basic lockfile is called package-lock.json. In the snippet above, we can precisely see several important information:

    +
      +
    • The version of myDependencyA is fixed at "0.0.5" so even if a new version is released, npm will install "0.0.5" no matter what.
    • +
    • Each indirect dependency describes its set of dependencies with versions that also describe their own versioning constraints.
    • +
    • In addition to the version, the contents of the dependencies can be checked with the comparison of hashes which can vary according to the registers used.
    • +
    +

    A lockfile therefore tries to accurately describes the dependency tree, which allows it to remain consistent and reproducible over time at each installation.

    +

    ⚠️ But...

    +

    Lockfiles don't solve all inconsistency problems! Package managers implementations of the dependency graph can sometimes lead to inconsistencies. For a long time, npm's implementation introduced Phantom Dependencies and also NPM doppelgangers which are very well explained on the Rush.js documentation website (advanced topics that are out of the scope of this blog post).

    3. Provision of distributed and transparent databases via open-source

    - -Distributed registries - -A package manager is a client that acts as a gateway to a distributed database (often called a registry). This allows in particular to share an infinite number of open-source libraries around the world. It is also possible to define company-wide private registries in a secured network, within which libraries would be accessible. - -> Verdaccio allows to setup a private proxy registry for Node.js - -The availability of registries has greatly changed the way software is developed by facilitating access to millions of libraries. - -Transparent access to resources - -The other benefit of open-source package managers is that they most often expose platforms or tools that allow browsing through published packages. Accessing source code and documentation has been trivialized and made very transparent. It is therefore possible for each developer to have an overview or even to fully investigate the code base of a published library. - +

    Distributed registries

    +

    A package manager is a client that acts as a gateway to a distributed database (often called a registry). This allows in particular to share an infinite number of open-source libraries around the world. It is also possible to define company-wide private registries in a secured network, within which libraries would be accessible.

    +
    +

    Verdaccio allows to setup a private proxy registry for Node.js

    +
    +

    The availability of registries has greatly changed the way software is developed by facilitating access to millions of libraries.

    +

    Transparent access to resources

    +

    The other benefit of open-source package managers is that they most often expose platforms or tools that allow browsing through published packages. Accessing source code and documentation has been trivialized and made very transparent. It is therefore possible for each developer to have an overview or even to fully investigate the code base of a published library.

    4. Security and integrity

    - -Using open-source registries with millions of publicly exposed libraries is pretty convenient, but what about _security_? - -It is true that open-source registries represent ideal targets for hackers: all you have to do is take control of a widely used library (downloaded millions of times a week) and inject malicious code into it, and no one will realize! - -In this part, we will see the solutions implemented by package managers and registries to deal with these attacks and limit the risks. - -Integrity safety for each installed package - -Given that a package can be installed from any registry, it is important to implement verification mechanisms at the level of the content of the downloaded package, to ensure that no malicious code has been injected during the download, regardless of its origin. - -For this, integrity metadata is associated with each installed package. For example with npm, an integrity property is associated with each package in the lockfile. This property contains a cryptographic hash which is used to accurately represent the resource the user expects to receive. This allows any program to verify that the content of the resource matches what was downloaded. For example for `@babel/core`, this is how integrity is represented in package-lock.json: - -
    json
    -"@babel/core": {
    -   "version": "7.16.10",
    -   "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.10.tgz",  
    -   "integrity": "sha512 pbiIdZbCiMx/MM6toR+OfXarYix3uz0oVsnNtfdAGTcCTu3w/JGF8JhirevXLBJUu0WguSZI12qpKnx7EeMyLA=="
    +

    Using open-source registries with millions of publicly exposed libraries is pretty convenient, but what about security?

    +

    It is true that open-source registries represent ideal targets for hackers: all you have to do is take control of a widely used library (downloaded millions of times a week) and inject malicious code into it, and no one will realize!

    +

    In this part, we will see the solutions implemented by package managers and registries to deal with these attacks and limit the risks.

    +

    Integrity safety for each installed package

    +

    Given that a package can be installed from any registry, it is important to implement verification mechanisms at the level of the content of the downloaded package, to ensure that no malicious code has been injected during the download, regardless of its origin.

    +

    For this, integrity metadata is associated with each installed package. For example with npm, an integrity property is associated with each package in the lockfile. This property contains a cryptographic hash which is used to accurately represent the resource the user expects to receive. This allows any program to verify that the content of the resource matches what was downloaded. For example for @babel/core, this is how integrity is represented in package-lock.json:

    +
    "@babel/core": {
    +   "version": "7.16.10",
    +   "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.10.tgz",  
    +   "integrity": "sha512 pbiIdZbCiMx/MM6toR+OfXarYix3uz0oVsnNtfdAGTcCTu3w/JGF8JhirevXLBJUu0WguSZI12qpKnx7EeMyLA=="
     }
     
    - -Let's take a closer look at how integrity can drastically reduce the risk of injecting malicious code by hashing source code. - -As a reminder: - -> We call hash function, a particular function which, from a datum supplied as input, calculates a digital fingerprint used to quickly identify the initial datum, in the same way as a signature to identify a person. Wikipedia - -Let's take for example a simple case: - -
    javascript
    -// my-library
    +

    Let's take a closer look at how integrity can drastically reduce the risk of injecting malicious code by hashing source code.

    +

    As a reminder:

    +
    +

    We call hash function, a particular function which, from a datum supplied as input, calculates a digital fingerprint used to quickly identify the initial datum, in the same way as a signature to identify a person. Wikipedia

    +
    +

    Let's take for example a simple case:

    +
    // my-library
     function someJavaScriptCode() {
       addUser();
     }
     
    - -Let's imagine that this JavaScript code represents a resource that a user might want to download. Using the _SHA1_ hash function, we get the hash `7677152af4ef8ca57fcb50bf4f71f42c28c772be`. -If ever malicious code is injected, the library's fingerprint will by definition change because the input (source code here) to the hash function will have changed: - -
    javascript
    -// my-library
    +

    Let's imagine that this JavaScript code represents a resource that a user might want to download. Using the SHA1 hash function, we get the hash 7677152af4ef8ca57fcb50bf4f71f42c28c772be. +If ever malicious code is injected, the library's fingerprint will by definition change because the input (source code here) to the hash function will have changed:

    +
    // my-library
     function someJavaScriptCode() {
       processMaliciousCode(); // this is injected, the user is not  expecting that
       addUser();
     }
     
    - -After injecting the malicious code, still using the same _SHA1_ hash function, we obtain `28d32d30caddaaaafbde0debfcd8b3300862cc24` as the digital fingerprint. -So we get as results: -- Original code = `7677152af4ef8ca57fcb50bf4f71f42c28c772be` -- Malicious code = `28d32d30caddaaaafbde0debfcd8b3300862cc24` - -All package managers implement strict specifications on this approach to integrity. For example, npm respects the W3C's "Subresource Integrity or SRI" specification, which describes the mechanisms to be implemented to reduce the risk of malicious code injection. -You can jump directly here to the specification document if you want to dig deeper. - -Security constraints at the author level - -To strengthen security at the level of open-source packages, more and more constraints are emerging on the side of project authors and maintainers. Recently, GitHub, which owns npm, announced that it is forcing two-factor authentication (2FA) for contributors to the 100 most popular packages. The main idea around these actions is to secure resources upstream by limiting write access to open-source packages and identifying people more precisely. - -It's important to also mention that there are tools that can be used to perform automatically scans and audits continuously. - -Built-in tools - -In order to automate the detection of vulnerabilities, many package managers natively integrate tools allowing to scan the installed libraries. Typically, these package managers communicate with databases that list all known and referenced vulnerabilities. For example, GitHub Advisory Database is an open-source database that references thousands of vulnerabilities across multiple ecosystems (Go, Rust, Maven, NuGet, etc) e.g. `npm audit` command uses this database. - -Third-party tools - -NodeSecure - -At NodeSecure we are building free open source tools to secure the Node.js & JavaScript ecosystem. Our biggest area of expertise is in package and code analysis. - -Here are some example of the available tools: - -- @nodesecure/cli, a CLI that allow you to deeply analyze the dependency tree of a given package or local Node.js project -- @nodesecure/js-x-ray, a SAST scanner (A static analyser for detecting most common malicious patterns) -- @nodesecure/vulnera, a Software Component Analysis (SCA) tool -- @nodesecure/ci, a tool allowing to run SAST, SCA and many more analysis in CI/CDs or in a local environment - -Snyk - -Snyk is the most popular all-around solution for securing applications or cloud-based infrastructures. Snyk offers a free-tier with SAST and SCA analysis. - -To ensure continuous detection of vulnerabilities, it is recommended to run scans each time packages are installed/modified. - -Conclusion - -There you go, you now know what issues are addressed and solved by package managers! - -Package managers are complex tools that aim to make life easier for us as developers, but can quickly become problematic if misused. - -It is therefore important to understand the issues they deal with and the solutions provided in order to be able to put into perspective several package managers of the same ecosystem. In the end, it's a tool like any other and it must mobilize thinking in the same way as when libraries/frameworks/programming languages ​​are used. - -Don't also forget to take into account security issues and use automated tools which can drastically reduce the attack surface! -

    -
    -
    - - - \ No newline at end of file +

    After injecting the malicious code, still using the same SHA1 hash function, we obtain 28d32d30caddaaaafbde0debfcd8b3300862cc24 as the digital fingerprint. +So we get as results:

    +
      +
    • Original code = 7677152af4ef8ca57fcb50bf4f71f42c28c772be
    • +
    • Malicious code = 28d32d30caddaaaafbde0debfcd8b3300862cc24
    • +
    +

    All package managers implement strict specifications on this approach to integrity. For example, npm respects the W3C's "Subresource Integrity or SRI" specification, which describes the mechanisms to be implemented to reduce the risk of malicious code injection. +You can jump directly here to the specification document if you want to dig deeper.

    +

    Security constraints at the author level

    +

    To strengthen security at the level of open-source packages, more and more constraints are emerging on the side of project authors and maintainers. Recently, GitHub, which owns npm, announced that it is forcing two-factor authentication (2FA) for contributors to the 100 most popular packages. The main idea around these actions is to secure resources upstream by limiting write access to open-source packages and identifying people more precisely.

    +

    It's important to also mention that there are tools that can be used to perform automatically scans and audits continuously.

    +

    Built-in tools

    +

    In order to automate the detection of vulnerabilities, many package managers natively integrate tools allowing to scan the installed libraries. Typically, these package managers communicate with databases that list all known and referenced vulnerabilities. For example, GitHub Advisory Database is an open-source database that references thousands of vulnerabilities across multiple ecosystems (Go, Rust, Maven, NuGet, etc) e.g. npm audit command uses this database.

    +

    Third-party tools

    +

    NodeSecure

    +

    At NodeSecure we are building free open source tools to secure the Node.js & JavaScript ecosystem. Our biggest area of expertise is in package and code analysis.

    +

    Here are some example of the available tools:

    +
      +
    • @nodesecure/cli, a CLI that allow you to deeply analyze the dependency tree of a given package or local Node.js project
    • +
    • @nodesecure/js-x-ray, a SAST scanner (A static analyser for detecting most common malicious patterns)
    • +
    • @nodesecure/vulnera, a Software Component Analysis (SCA) tool
    • +
    • @nodesecure/ci, a tool allowing to run SAST, SCA and many more analysis in CI/CDs or in a local environment
    • +
    +

    Snyk

    +

    Snyk is the most popular all-around solution for securing applications or cloud-based infrastructures. Snyk offers a free-tier with SAST and SCA analysis.

    +

    To ensure continuous detection of vulnerabilities, it is recommended to run scans each time packages are installed/modified.

    +

    Conclusion

    +

    There you go, you now know what issues are addressed and solved by package managers!

    +

    Package managers are complex tools that aim to make life easier for us as developers, but can quickly become problematic if misused.

    +

    It is therefore important to understand the issues they deal with and the solutions provided in order to be able to put into perspective several package managers of the same ecosystem. In the end, it's a tool like any other and it must mobilize thinking in the same way as when libraries/frameworks/programming languages ​​are used.

    +

    Don't also forget to take into account security issues and use automated tools which can drastically reduce the attack surface!

    + + +
    +
    + + + + + \ No newline at end of file diff --git a/blog/index-base-template.html b/blog/index-base-template.html new file mode 100644 index 0000000..b70dbbd --- /dev/null +++ b/blog/index-base-template.html @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/blog/index.html b/blog/index.html index 31edebb..3c273a7 100644 --- a/blog/index.html +++ b/blog/index.html @@ -1,26 +1,150 @@ + + + + + + + + + + + + + + NodeSecure - Blog + - - - - - - Blog - NodeSecure - - - - -
    - ← Retour Γ  l'accueil -

    Articles de blog

    -
    -
    - -
    - - - \ No newline at end of file + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    + +
    + +
    + +
    +
    +
    + + Thomas + +
    + Thomas + 21/07/2022 +
    +
    + + NodeSecure Vuln-era + +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit.

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Antoine + 18/10/2022 +
    +
    + + Everything you need to know: package managers + +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit.

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Thomas + 16/01/2023 +
    +
    + + JS-X-Ray 6.0 + +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit.

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Thomas + 19/02/2023 +
    +
    + + Securizing your GitHub org + +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit.

    +
    +
    + +
    +
    + + + + + \ No newline at end of file diff --git a/blog/securizing-your-github-org.html b/blog/securizing-your-github-org.html index 1cfd108..f11693c 100644 --- a/blog/securizing-your-github-org.html +++ b/blog/securizing-your-github-org.html @@ -1,113 +1,120 @@ - - - - - - - securizing-your-github-org - - - - -
    - ← Retour Γ  l'accueil -
    -
    -
    -

    --- -title: Securizing your GitHub org -author: Thomas.G -date: 19/02/2023 ---- - -Hello πŸ‘‹ - -I started open source a bit naively (like everyone I guess 😊). - -But the more I progress and the more important/popular some of my projects become 😎. That's great, but at some point you have to deal with a lot of things related to security (like Vulnerability disclosure). - -You start to hear and see a lot of scary stories around you 😱. Not to mention all the acronyms where you don't understand anything at first 😡 (VMT, CVE, SAST, SCA, CNA ...). - -As I was working on an open source security project, I put pressure on myself to be ready. Also as a member of the Node.js Security WG I thought it was an interesting topic and that I was probably not the only one who was worried about not being up to the task πŸ˜–. - -So I rolled up my sleeves and tackled the problem πŸ’ͺ. Here is my feedback/journey on how I improved the security of my NodeSecure GitHub organization. - -> πŸ‘€ We use Node.js and JavaScript (but most recommendations are valid for other ecosystems). - + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +

    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    Securizing your GitHub org

    +

    Hello πŸ‘‹

    +

    I started open source a bit naively (like everyone I guess 😊).

    +

    But the more I progress and the more important/popular some of my projects become 😎. That's great, but at some point you have to deal with a lot of things related to security (like Vulnerability disclosure).

    +

    You start to hear and see a lot of scary stories around you 😱. Not to mention all the acronyms where you don't understand anything at first 😡 (VMT, CVE, SAST, SCA, CNA ...).

    +

    As I was working on an open source security project, I put pressure on myself to be ready. Also as a member of the Node.js Security WG I thought it was an interesting topic and that I was probably not the only one who was worried about not being up to the task πŸ˜–.

    +

    So I rolled up my sleeves and tackled the problem πŸ’ͺ. Here is my feedback/journey on how I improved the security of my NodeSecure GitHub organization.

    +
    +

    πŸ‘€ We use Node.js and JavaScript (but most recommendations are valid for other ecosystems).

    +

    Security Policy and Vulnerability Disclosure

    - -Adding a root `SECURITY.md` file explaining how developers and security researchers should report vulnerability is important. You don't want a security threat to be turned into a public issue (This gives you time to analyze and possibly fix before disclosure). - -> ⚠️ If you are a developer, never report a security threat using a public GitHub issue. This is a serious mistake. This could even put your business/team at risk. - -I don't want to bullshit you, so let me share with you the OpenSSF guide that helped me set up my first reporting strategy: Guide to implementing a coordinated vulnerability disclosure process for open source projects. - -I started from scratch by reading this guide and taking inspiration from their templates 🐀. As a small open source team we don't especially have DNS or mail servers (not even a defined Vulnerability Management Team A.K.A VMT). - -I was a bit puzzled to put my personal email as I'm not alone 😟. - -I quickly learned that Github added a new feature to report/create private security issue 😍. You can enable it in the `Security` tab (I think it's also now possible to enable it on every repositories at once). - -And this is what it finally looks like: -!NodeSecure SECURITY.md - +

    Adding a root SECURITY.md file explaining how developers and security researchers should report vulnerability is important. You don't want a security threat to be turned into a public issue (This gives you time to analyze and possibly fix before disclosure).

    +
    +

    ⚠️ If you are a developer, never report a security threat using a public GitHub issue. This is a serious mistake. This could even put your business/team at risk.

    +
    +

    I don't want to bullshit you, so let me share with you the OpenSSF guide that helped me set up my first reporting strategy: Guide to implementing a coordinated vulnerability disclosure process for open source projects.

    +

    I started from scratch by reading this guide and taking inspiration from their templates 🐀. As a small open source team we don't especially have DNS or mail servers (not even a defined Vulnerability Management Team A.K.A VMT).

    +

    I was a bit puzzled to put my personal email as I'm not alone 😟.

    +

    I quickly learned that Github added a new feature to report/create private security issue 😍. You can enable it in the Security tab (I think it's also now possible to enable it on every repositories at once).

    +

    And this is what it finally looks like: +NodeSecure SECURITY.md

    Use OpenSSF scorecard

    - -!scorecard - -The OSSF scorecard initiative is really good to assess your project against security best practices. I am not the first to write about this. - -You can easily setup the GitHub action workflow by following those instructions. - -Once configured, you will have a set of alerts available in the `Security` tab. - -!Scorecard scanning alerts - -This will give you an overview of the different subjects to improve (workflows, dependencies etc). Each of these alerts contains a full description of the actions to be taken to fix the problem. - -!OSSF Scorecard - -I have personally used these recommendations to dig and train myself. The next chapters will help you improve your score. - -> πŸ“’ By the way NodeSecure CLI has a first-class support of the scorecard. - +

    scorecard

    +

    The OSSF scorecard initiative is really good to assess your project against security best practices. I am not the first to write about this.

    +

    You can easily setup the GitHub action workflow by following those instructions.

    +

    Once configured, you will have a set of alerts available in the Security tab.

    +

    Scorecard scanning alerts

    +

    This will give you an overview of the different subjects to improve (workflows, dependencies etc). Each of these alerts contains a full description of the actions to be taken to fix the problem.

    +

    OSSF Scorecard

    +

    I have personally used these recommendations to dig and train myself. The next chapters will help you improve your score.

    +
    +

    πŸ“’ By the way NodeSecure CLI has a first-class support of the scorecard.

    +

    πŸ”“ Enable branch protection

    -I am a bad student 😳. Almost all of my projects had no branch protection on the `main` / `master` branch πŸ™ˆ. - -> To set up the protection, go to `Settings` > `Branches` and edit your main branch. - -GitHub has quite a few options on the subject 😡. If you don't know what to choose in terms of options, don't check anything (it's ok to begin βœ”οΈ). - -If you want to be more restrictive, be careful because it could block you (some options are only viable in projects with many contributors/reviewers). - -As far as I am concerned I often choose: -- Require a pull request before merging -- Require conversation resolution before merging -- Require status checks to pass before merging - +

    I am a bad student 😳. Almost all of my projects had no branch protection on the main / master branch πŸ™ˆ.

    +
    +

    To set up the protection, go to Settings > Branches and edit your main branch.

    +
    +

    GitHub has quite a few options on the subject 😡. If you don't know what to choose in terms of options, don't check anything (it's ok to begin βœ”οΈ).

    +

    If you want to be more restrictive, be careful because it could block you (some options are only viable in projects with many contributors/reviewers).

    +

    As far as I am concerned I often choose:

    +
      +
    • Require a pull request before merging
    • +
    • Require conversation resolution before merging
    • +
    • Require status checks to pass before merging
    • +

    🐲 Workflows Hardening

    -I fell down when I saw all that it was necessary to know to secure workflows with GitHub actions 😲. - -- You must pay attention to the permissions granted to your jobs / GITHUB_TOKEN -- Ensure your GitHub Actions are pinned to a SHA -- Hardening the runner (see the StepSecurity HardenRunner) -- Probably a lot of other stuff I haven't had time to see yet πŸ˜† - -Fortunately there is a great free online tool that help you by doing all the hard work (it will open a pull-request and automatically fix issues). - -{% tweet https://twitter.com/fraxken/status/1617557370728767488 %} - -The tool was created by StepSecurity. I had the opportunity to talk with the CEO and they listen to the maintainers which is really cool. -Thanks to them ❀️! - +

    I fell down when I saw all that it was necessary to know to secure workflows with GitHub actions 😲.

    + +

    Fortunately there is a great free online tool that help you by doing all the hard work (it will open a pull-request and automatically fix issues).

    +

    {% tweet https://twitter.com/fraxken/status/1617557370728767488 %}

    +

    The tool was created by StepSecurity. I had the opportunity to talk with the CEO and they listen to the maintainers which is really cool. +Thanks to them ❀️!

    Configure Dependabot

    - -It is recommended to use Dependabot for updating your dependencies and GitHub actions (yes, it also supports updating workflows in a secure way 😍). - -You only need to add a `.github/dependabot.yml` config file. Personally I recommend a weekly interval (with a lot of projects daily is a bit horrible). - -
    yml
    -version: 2
    +

    It is recommended to use Dependabot for updating your dependencies and GitHub actions (yes, it also supports updating workflows in a secure way 😍).

    +

    You only need to add a .github/dependabot.yml config file. Personally I recommend a weekly interval (with a lot of projects daily is a bit horrible).

    +
    version: 2
     updates:
       - package-ecosystem: github-actions
         directory: /
    @@ -119,65 +126,45 @@ 

    Configure Dependabot

    schedule: interval: weekly
    - -The StepSecurity tool we have seen in the previous chapter is also capable of doing it πŸš€. - ---- - -Also, think to enable Dependabot alerts in the `Security` tab. This will allow the bot to open pull-request to fix known vulnerabilities by looking at your dependencies (referenced in package.json or others). - +

    The StepSecurity tool we have seen in the previous chapter is also capable of doing it πŸš€.

    +
    +

    Also, think to enable Dependabot alerts in the Security tab. This will allow the bot to open pull-request to fix known vulnerabilities by looking at your dependencies (referenced in package.json or others).

    πŸ”¬ Adding CodeQL scanning

    - -To enhance security even more you can add a SAST tool like CodeQL. Like scorecard it will report security scanning alert but for your codebase. - -Here an example: -!prototype-pollution - -A great way to make sure that newly added code does not contain vulnerabilities that were obvious to detect. - -> πŸ‘€ Note that once again StepSecurity can set up the workflow for you. - +

    To enhance security even more you can add a SAST tool like CodeQL. Like scorecard it will report security scanning alert but for your codebase.

    +

    Here an example: +prototype-pollution

    +

    A great way to make sure that newly added code does not contain vulnerabilities that were obvious to detect.

    +
    +

    πŸ‘€ Note that once again StepSecurity can set up the workflow for you.

    +

    πŸ“œ Enable Security advisories (and others)

    - -Github Security tab as a lot of cool features that help you maintain the security of your project. If you have followed all my previous chapters, most of them should be enabled now. - -Make sure to also enable `Secret scanning alerts`. - -!Github Security - -For an organization many of these parameters can be forced on all repositories. Go to `Settings` > `Code security and analysis`. You will have the options to enable/disable all. - -!Github Security - +

    Github Security tab as a lot of cool features that help you maintain the security of your project. If you have followed all my previous chapters, most of them should be enabled now.

    +

    Make sure to also enable Secret scanning alerts.

    +

    Github Security

    +

    For an organization many of these parameters can be forced on all repositories. Go to Settings > Code security and analysis. You will have the options to enable/disable all.

    +

    Github Security

    πŸ’‘ OpenSSF Best Pratices program

    - -Previously known as CII-Best-Practices, this program indicates that the project uses a set of security-focused best development practices for open source software. - -So I registered my first project on the website. It was a good surprise because it allowed me to question the quality of my documentation and tests 😬. - -Seeing the different levels and questions really helps you think about what you're missing (and possibly learn about the concepts you don't know about yet.. Like SBOM). - -!CII-Best-Practices - -I am still working on completing the first step/badge for the CLI project which now has a score of 8.7 out of 10 πŸŽ‰ on the OpenSSF scorecard. - +

    Previously known as CII-Best-Practices, this program indicates that the project uses a set of security-focused best development practices for open source software.

    +

    So I registered my first project on the website. It was a good surprise because it allowed me to question the quality of my documentation and tests 😬.

    +

    Seeing the different levels and questions really helps you think about what you're missing (and possibly learn about the concepts you don't know about yet.. Like SBOM).

    +

    CII-Best-Practices

    +

    I am still working on completing the first step/badge for the CLI project which now has a score of 8.7 out of 10 πŸŽ‰ on the OpenSSF scorecard.

    🎯 Conclusion

    - -That's it for this article. I've covered what I've done/learned in the last couple of months. Here are some really cool additional links πŸ’ƒ: - -- Concise Guide for Evaluating Open Source Software 2023-01-03 -- Concise Guide for Developing More Secure Software 2023-01-03 - -If you work with NPM, I invite you to read our latest article about package managers: - -{% link https://dev.to/nodesecure/everything-you-need-to-know-package-managers-286c %} - -Obviously, I probably still have a lot to learn. But I hope this will help other maintainers/developers ❀️. - -πŸ™ Thanks for reading me πŸ™ -

    -
    -
    - - - \ No newline at end of file +

    That's it for this article. I've covered what I've done/learned in the last couple of months. Here are some really cool additional links πŸ’ƒ:

    + +

    If you work with NPM, I invite you to read our latest article about package managers:

    +

    {% link https://dev.to/nodesecure/everything-you-need-to-know-package-managers-286c %}

    +

    Obviously, I probably still have a lot to learn. But I hope this will help other maintainers/developers ❀️.

    +

    πŸ™ Thanks for reading me πŸ™

    + + +
    +
    + + + + + \ No newline at end of file diff --git a/index.html b/index.html index 51e0edb..c01af4d 100644 --- a/index.html +++ b/index.html @@ -10,15 +10,15 @@ href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet"> - - + + NodeSecure - Securing the Node.js Ecosystem -
    +
    NodeSecure Logo style="width:28px;height:28px;filter:invert(1) brightness(2);"> Join Discord - + Blog Visit Blog @@ -85,7 +85,7 @@

    🐀 New to NodeSecure? Check out our beginner guides to start contributing.

    - + @@ -137,7 +137,7 @@

    πŸ”¬ JS-X-Ray

    - +

    Vulnera

    Programmatically fetch security vulnerabilities with one or many strategies (NPM Audit, Sonatype, Snyk, OSV...).

    diff --git a/package-lock.json b/package-lock.json index 20c5d59..291eca7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "MIT", "dependencies": { + "marked": "^16.3.0", "zup": "^0.0.2" }, "devDependencies": { @@ -2163,6 +2164,18 @@ "dev": true, "license": "MIT" }, + "node_modules/marked": { + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-16.3.0.tgz", + "integrity": "sha512-K3UxuKu6l6bmA5FUwYho8CfJBlsUWAooKtdGgMcERSpF7gcBUrCGsLH7wDaaNOzwq18JzSUDyoEb/YsrqMac3w==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", diff --git a/package.json b/package.json index f70fd00..ce7a464 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "type": "module", "scripts": { "dev": "vite", - "build": "vite build", + "build": "npm run build:articles && vite build", "preview": "vite preview", "build:articles": "node src/build-articles.js" }, @@ -26,6 +26,7 @@ "vite": "^7.0.2" }, "dependencies": { + "marked": "^16.3.0", "zup": "^0.0.2" } } diff --git a/public/css/blog.css b/public/css/blog.css new file mode 100644 index 0000000..aeb23c9 --- /dev/null +++ b/public/css/blog.css @@ -0,0 +1,202 @@ +.articleHeader { + z-index: 2; +} + +.articles-list { + padding: 30px; + display: grid; + grid-template-columns: repeat(4, 1fr); + grid-gap: 20px; + z-index: 2; +} + +.article { + padding: 20px; + border-radius: 6px; + display: flex; + flex-direction: column; + gap: 1rem; + justify-content: center; + margin-top: 1.5rem; + z-index: 2; + +} + +.article-link { + font-size: 30px; + z-index: 2; + font-weight: 600; +} + +.article-link:hover { + text-decoration: underline; +} + +article { + display: flex; + flex-direction: column; + justify-content: space-beween; + align-items: center; + width: 100%; +} + +.article-content { + max-width: 60%; + padding: 040px; + background: linear-gradient(135deg, rgba(90, 68, 218, 0.5) 0%, rgba(55, 34, 175, 0.5) 100%); +} + +.article-content > h1, +.article-content > h2, +.article-content >h3 { + margin: 20px 0; +} + +.article-content > h1 { + font-size: 32px; +} + +.article-content > h2 { + font-size: 28px; +} + +.article-content > h3 { + font-size: 24px; +} + +h1.article-title { + display: block; + text-align: center; + margin: 50px 0; +} + +.article-content > p { + font-size: 20px; + margin: 10px 0; +} + +.article-content > pre { + position: relative; + background-color: #1e1e1e; + border-radius: 8px; + overflow: hidden; + margin: 1.5rem 0; +} + +.article-content > pre code[class^="language-"]::before { + display: block; + color: grey; + font-size: 10px; + font-weight: 600; + text-transform: uppercase; + font-family: 'JetBrains Mono', monospace; + letter-spacing: 0.5px; + margin-bottom: 10px; +} + +.article-content > pre code.language-js::before, +.article-content > pre code.language-javascript::before { + content: "JavaScript"; +} + +.article-content > pre code.language-ts::before, +.article-content > pre code.language-typescript::before { + content: "TypeScript"; +} + +.article-content > pre code.language-css::before { + content: "CSS"; +} + +.article-content > pre code.language-html::before { + content: "HTML"; +} + +.article-content > pre code.language-json::before { + content: "JSON"; +} + +.article-content > pre code.language-yml::before { + content: 'YAML' +} + +.article-content > pre code.language-bash::before { + content: 'BASH' +} + +.article-content > pre code { + display: block; + padding: 1rem; + color: #f8f8f2; + font-family: 'JetBrains Mono', monospace; + background: none; + border: none; +} + +.article-card { + position: relative; + padding: 0.5rem; + color: #fff; + border-radius: 12px; + box-shadow: 0 6px 32px #0003; + background: var(--bg-img) center/cover no-repeat, #3722AF; + display: flex; + align-items: flex-end; + transform: skew(-4deg); + transition: transform 0.2s; + z-index: 2; +} + +.article-card:hover { + transform: skew(-4deg) scale(1.04); + box-shadow: 0 12px 40px #0005; +} + +.article-card-content { + min-height: 76%; + transform: skew(4deg); + padding: 2rem; + background: linear-gradient(0deg, #3722AFee 80%, #00D1FF44 100%); + border-radius: 12px; + display: flex; + flex-direction: column; + justify-content: start; + align-items: start; + gap: 10px; +} + +.article-card-header { + display: flex; + justify-content: start; + align-items: start; + gap: 1rem; + margin-bottom: 1rem; +} + +.article-card-header img { + width: 60px; + height: 60px; + border-radius: 50%; + box-shadow: + 0 0 0 6px rgba(0, 209, 255, 0.18), + 0 0 24px 8px #00d1ff55, + 0 0 48px 8px #3722af33; + background: linear-gradient(120deg, #261877 0%, #3722AF 100%); + object-fit: cover; +} + +.article-card-header-infos { + display: flex; + flex-direction: column; + justify-content: start; + align-items: start; + gap: 0.6rem; +} + +.article-card-header-infos > span:first-child { + font-size: 20px; +} + +.article-card-header-infos > span:last-child { + font-size: 12px; +} diff --git a/public/css/index.css b/public/css/index.css index cceaf91..e8f7eef 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -28,6 +28,10 @@ body { height: auto; } +a { + color: var(--primary-theme-color); +} + #network-bg { position: fixed; top: 0; @@ -38,6 +42,8 @@ body { opacity: 0.3; } + + .centered-content { width: calc(100% - 2rem); max-width: 1200px; @@ -83,6 +89,23 @@ header { margin-bottom: 2rem; } +.blogHeader { + margin-bottom: 0; +} + +.articleHeader { + width: 100%; + display: flex; + flex-direction: center; + justify-content: center; + height: 70px; +} + +.articleHeader > a { + align-self: center; + font-size: 30px; +} + @media only screen and (max-width: 600px) { header>.header-content > img { display: none; @@ -92,12 +115,12 @@ header { header>.header-background { position: absolute; inset: 0; - z-index: 1; + z-index: 1 !important; background: linear-gradient(120deg, rgba(38, 24, 119, 0.75) 0%, rgba(34, 100, 175, 0.90) 100%), url('../images/header-cover.PNG') center/cover no-repeat; } header>.header-content { - z-index: 2; + z-index: 2 !important; max-width: 800px !important; display: flex; flex-direction: column; @@ -528,6 +551,10 @@ header>.header-content>.description b { text-align: left; } +.project-content h1 { + font-size: 2rem; +} + .project-content .logo { height: 28px; width: auto; @@ -585,3 +612,11 @@ header>.header-content>.description b { color: #fff; letter-spacing: 0.01em; } + + + + + + + + diff --git a/public/css/reset.css b/public/css/reset.css index aa8f3ba..44c3421 100644 --- a/public/css/reset.css +++ b/public/css/reset.css @@ -129,10 +129,12 @@ q:after { a { text-decoration: none; + cursor: pointer; } @keyframes pulse { 0% { transform: scale(1); opacity: 0.5; } 50% { transform: scale(1.2); opacity: 0.8; } 100% { transform: scale(1); opacity: 0.5; } -} \ No newline at end of file +} + diff --git a/src/build-articles.js b/src/build-articles.js index cf09009..29efaf0 100644 --- a/src/build-articles.js +++ b/src/build-articles.js @@ -2,144 +2,195 @@ import fs from "node:fs"; import path from "node:path"; +// Import Third-party Dependencies +import { marked } from "marked"; + const inputDir = "./articles"; const outputDir = "./blog"; +const coreContributors = []; -function markdownToHtml(markdown) { - let html = markdown; +// function markdownToHtml(markdown) { +// let html = markdown; - // headers - html = html.replace(/^### (.*$)/gim, "

    $1

    "); - html = html.replace(/^## (.*$)/gim, "

    $1

    "); - html = html.replace(/^# (.*$)/gim, "

    $1

    "); +// // escapes "<" that are not html tags +// html = html.replace(/$1"); +// // headers +// html = html.replace(/^### (.*$)/gim, "

    $1

    "); +// html = html.replace(/^## (.*$)/gim, "

    $1

    "); +// html = html.replace(/^# (.*$)/gim, "

    $1

    "); - // italic text - html = html.replace(/\*(.*?)\*/g, "$1"); +// // bold text +// html = html.replace(/\*\*(.*?)\*\*/g, "$1"); - // links [text](url) - html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '
    $1'); +// // italic text +// html = html.replace(/\*(.*?)\*/g, "$1"); - // code inline `code` - // html = html.replace(/`([^`]+)`/g, "$1"); +// // links [text](url) +// html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1'); - // code blocks ``` - html = html.replace(/```([\s\S]*?)```/g, "
    $1
    "); +// // code blocks ``` +// const usedLangages = ["json", "js", "ts", "css"]; - // line breaks - html = html.replace(/\n\n/g, "

    "); - html = "

    " + html + "

    "; +// for (const lang of usedLangages) { +// const regex = new RegExp(`\`\`\`${lang}([\\s\\S]*?)\`\`\``, "g"); +// html = html.replace(regex, "
    $1
    "); +// } - // empty paragraphs - // html = html.replace(/

    <\/p>/g, ""); +// // line breaks +// html = html.replace(/\n\n/g, "

    "); +// html = "

    " + html + "

    "; - return html; -} +// // empty paragraphs +// // html = html.replace(/

    <\/p>/g, ""); + +// return html; +// } function generateBlogPost(markdownFile) { - const content = fs.readFileSync(markdownFile, "utf8"); + const markdownContent = fs.readFileSync(markdownFile, "utf8"); const fileName = path.basename(markdownFile, ".md"); - // extract title from first # header or use filename - const titleMatch = content.match(/^# (.*)$/m); - const title = titleMatch ? titleMatch[1] : fileName; - - const htmlContent = markdownToHtml(content); - - const template = ` - - - - - - ${title} - - - - -

    - ← Retour Γ  l'accueil -
    -
    -
    - ${htmlContent} -
    -
    - - - `; + const { metadata, content } = parseYamlFile(markdownContent); + // const htmlContent = markdownToHtml(content); + const htmlContent = marked.parse(content); + + const baseArticleTemplate = fs.readFileSync(`${outputDir}/article-base-template.html`, "utf-8"); + + const articleTemplate = baseArticleTemplate.replace("
    ", ` +
    +
    +

    ${metadata.title}

    + ${htmlContent} +
    +
    `); if (!fs.existsSync(outputDir)) { fs.mkdirSync(outputDir, { recursive: true }); } const outputPath = path.join(outputDir, `${fileName}.html`); - fs.writeFileSync(outputPath, template); + fs.writeFileSync(outputPath, articleTemplate); + + return { ...metadata, path: `${fileName}.html` }; +} + +function parseYamlFile(content) { + if (!content.startsWith("---")) { + return { metadata: {}, content }; + } + + const lines = content.split("\n"); + let endLineIndex = -1; + + for (let i = 1; i < lines.length; i++) { + if (lines[i].trim() === "---") { + endLineIndex = i; + break; + } + } + + if (endLineIndex === -1) { + return { metadata: {}, content }; + } - console.log(`articled generated: ${outputPath}`); + // Extraire le frontmatter (entre les deux ---) + const frontmatterLines = lines.slice(1, endLineIndex); + const markdownLines = lines.slice(endLineIndex + 1); - return outputPath; + // const frontmatterText = frontmatterLines.join("\n"); + const markdownContent = markdownLines.join("\n").trim(); + + // Parser le YAML simple (clΓ©: valeur) + const metadata = {}; + + for (const line of frontmatterLines) { + const trimmedLine = line.trim(); + if (trimmedLine && trimmedLine.includes(":")) { + const [key, ...valueParts] = trimmedLine.split(":"); + const value = valueParts.join(":").trim(); + metadata[key.trim()] = value; + } + } + + return { metadata, content: markdownContent }; } // processes all markdown files in articles directory -function convertAllMarkdownArticles() { +export function convertAllMarkdownArticles() { if (!fs.existsSync(inputDir)) { - console.log(`Directory ${inputDir} does not exist`); - - return; + throw new Error(`${inputDir} directory does not exist`); } const files = fs.readdirSync(inputDir) .filter((file) => file.endsWith(".md")); - files.forEach((file) => { + const articles = files.map((file) => { const filePath = path.join(inputDir, file); - generateBlogPost(filePath, outputDir); + + return generateBlogPost(filePath, outputDir); }); // Generate index page - generateBlogIndex(files, outputDir); + generateBlogIndex(articles); } -function generateBlogIndex(markdownFiles, outputDir) { - const articles = markdownFiles.map((file) => { - const fileName = path.basename(file, ".md"); - - return `
  • ${fileName}
  • `; +function generateBlogIndex(articles) { + const articlesList = articles.map((article) => { + const coreContributor = coreContributors.filter((c) => c.name === article.author)?.[0]; + + const imgSource = coreContributor?.github + ? `https://github.com/${coreContributor.github}.png` + : "https://img.icons8.com/ios-glyphs/30/test-account.png"; + + return ` +
    +
    +
    + + Thomas + +
    + ${article.author} + ${article.date} +
    +
    + + ${article.title} + +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit.

    +
    +
    + `; }).join("\n "); - const indexTemplate = ` - - - - - - Blog - NodeSecure - - - - -
    - ← Retour Γ  l'accueil -

    Articles de blog

    -
    -
    -
      - ${articles} -
    -
    - - - `; + const baseTemplate = fs.readFileSync(`${outputDir}/index-base-template.html`, "utf-8"); + + const indexTemplate = baseTemplate.replace('
    ', ` +
    + ${articlesList} +
    `); const indexPath = path.join(outputDir, "index.html"); fs.writeFileSync(indexPath, indexTemplate); - console.log(`blog index generated: ${indexPath}`); } -(() => { +(async() => { + const response = await fetch("https://raw.githubusercontent.com/NodeSecure/Governance/main/contributors.json"); + + if (!response.ok) { + throw new Error(`Error while fetching contributors list: ${response.status}`); + } + + const contributors = await response.json(); + + if (contributors.core) { + coreContributors.push(...contributors.core); + } + convertAllMarkdownArticles(); })(); diff --git a/vite.config.js b/vite.config.js index 1230797..f779856 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,11 +1,40 @@ +// Import Node.js Dependencies +import fs from "node:fs"; +import path from "node:path"; + // Import Third-party Dependencies import { defineConfig } from "vite"; // Import Internal Dependencies import zupTransformer from "./plugins/zupTransformer.js"; +function getBlogEntries() { + const entries = { + main: "index.html" + }; + + if (fs.existsSync("./blog")) { + const files = fs.readdirSync("./blog").filter((file) => file.endsWith(".html")); + + files.forEach((file) => { + const name = path.basename(file, ".html"); + + if (!name.includes("base-template")) { + entries[`blog-${name}`] = `blog/${file}`; + } + }); + } + + return entries; +} + export default defineConfig({ plugins: [ zupTransformer({}) - ] + ], + build: { + rollupOptions: { + input: getBlogEntries() + } + } }); From 9cd3c8062873499de181ab010e4a14ffcf80074b Mon Sep 17 00:00:00 2001 From: nasfernane Date: Wed, 17 Sep 2025 15:43:17 +0200 Subject: [PATCH 03/12] feat: added articles descriptions and updated computed blog articles authors with author gihub link --- articles/JS-X-Ray-6.0.md | 3 ++- articles/announcing-nodesecure-vuln-era.md | 3 ++- .../everything-you-need-to-know-about-package-managers.md | 3 ++- articles/securizing-your-github-org.md | 3 ++- blog/index.html | 8 ++++---- src/build-articles.js | 7 ++++--- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/articles/JS-X-Ray-6.0.md b/articles/JS-X-Ray-6.0.md index dc66124..86ba00a 100644 --- a/articles/JS-X-Ray-6.0.md +++ b/articles/JS-X-Ray-6.0.md @@ -1,6 +1,7 @@ --- title: JS-X-Ray 6.0 -author: Thomas +description: Discover what’s new in JS-X-Ray 6.0! Explore the latest features of this open source JavaScript security analyzer and see how it helps you write safer, cleaner code. +author: fraxken date: 16/01/2023 --- diff --git a/articles/announcing-nodesecure-vuln-era.md b/articles/announcing-nodesecure-vuln-era.md index fa211ec..70c4fcf 100644 --- a/articles/announcing-nodesecure-vuln-era.md +++ b/articles/announcing-nodesecure-vuln-era.md @@ -1,6 +1,7 @@ --- title: NodeSecure Vuln-era -author: Thomas +description: Dive into the rebranding of Vulnera, NodeSecure’s powerful tool for uncovering Node.js vulnerabilities from multiple sources. Discover its evolution and how it’s shaping the future of open source security! +author: fraxken date: 21/07/2022 --- diff --git a/articles/everything-you-need-to-know-about-package-managers.md b/articles/everything-you-need-to-know-about-package-managers.md index 8f6797c..99df8dd 100644 --- a/articles/everything-you-need-to-know-about-package-managers.md +++ b/articles/everything-you-need-to-know-about-package-managers.md @@ -1,6 +1,7 @@ --- title: Everything you need to know: package managers -author: Antoine +description: Curious about package managers? Explore their essential role in modern software, from Linux to npm, and learn why they’re the backbone of every developer’s workflow! +author: antoine-coulon date: 18/10/2022 --- diff --git a/articles/securizing-your-github-org.md b/articles/securizing-your-github-org.md index 4264bb6..c9f3d29 100644 --- a/articles/securizing-your-github-org.md +++ b/articles/securizing-your-github-org.md @@ -1,6 +1,7 @@ --- title: Securizing your GitHub org -author: Thomas +description: Learn hands-on strategies and real-world tips to boost the security of your GitHub organization. Perfect for open source maintainers and anyone serious about code safety! +author: fraxken date: 19/02/2023 --- diff --git a/blog/index.html b/blog/index.html index 3c273a7..0078edb 100644 --- a/blog/index.html +++ b/blog/index.html @@ -71,7 +71,7 @@

    class="article-link"> NodeSecure Vuln-era -

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit.

    +

    Dive into the rebranding of Vulnera, NodeSecure’s powerful tool for uncovering Node.js vulnerabilities from multiple sources. Discover its evolution and how it’s shaping the future of open source security!

    @@ -93,7 +93,7 @@

    class="article-link"> Everything you need to know: package managers -

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit.

    +

    Curious about package managers? Explore their essential role in modern software, from Linux to npm, and learn why they’re the backbone of every developer’s workflow!

    @@ -115,7 +115,7 @@

    class="article-link"> JS-X-Ray 6.0 -

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit.

    +

    Discover what’s new in JS-X-Ray 6.0! Explore the latest features of this open source JavaScript security analyzer and see how it helps you write safer, cleaner code.

    @@ -137,7 +137,7 @@

    class="article-link"> Securizing your GitHub org -

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit.

    +

    Learn hands-on strategies and real-world tips to boost the security of your GitHub organization. Perfect for open source maintainers and anyone serious about code safety!

    diff --git a/src/build-articles.js b/src/build-articles.js index 29efaf0..5241c46 100644 --- a/src/build-articles.js +++ b/src/build-articles.js @@ -137,7 +137,8 @@ export function convertAllMarkdownArticles() { function generateBlogIndex(articles) { const articlesList = articles.map((article) => { - const coreContributor = coreContributors.filter((c) => c.name === article.author)?.[0]; + const coreContributor = coreContributors.filter((c) => c.github === article.author)?.[0]; + console.log("coreContributors", coreContributors); const imgSource = coreContributor?.github ? `https://github.com/${coreContributor.github}.png` @@ -151,7 +152,7 @@ function generateBlogIndex(articles) { Thomas
    - ${article.author} + ${coreContributor?.name || article.author} ${article.date}
    @@ -161,7 +162,7 @@ function generateBlogIndex(articles) { class="article-link"> ${article.title} -

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit.

    +

    ${article.description}

    `; From 7f38485b286e6f4fbb7afd0c7a58e688fdff0bbe Mon Sep 17 00:00:00 2001 From: nasfernane Date: Sun, 21 Sep 2025 10:22:10 +0200 Subject: [PATCH 04/12] feat: update computed html styling --- public/css/blog.css | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/public/css/blog.css b/public/css/blog.css index aeb23c9..83daf3b 100644 --- a/public/css/blog.css +++ b/public/css/blog.css @@ -44,16 +44,18 @@ article { max-width: 60%; padding: 040px; background: linear-gradient(135deg, rgba(90, 68, 218, 0.5) 0%, rgba(55, 34, 175, 0.5) 100%); + z-index: 2; } .article-content > h1, .article-content > h2, .article-content >h3 { - margin: 20px 0; + margin: 30px 0 20px 0; + font-weight: 600; } .article-content > h1 { - font-size: 32px; + font-size: 40px } .article-content > h2 { @@ -64,6 +66,10 @@ article { font-size: 24px; } +img { + max-width: 100%; +} + h1.article-title { display: block; text-align: center; @@ -72,7 +78,14 @@ h1.article-title { .article-content > p { font-size: 20px; - margin: 10px 0; + margin: 12px 0; +} + +.article-content > p:has(img) { + display: flex; + justify-content: start; + align-items: center; + gap: 20px; } .article-content > pre { From f64b80a595f0013f26efd4cde4b9fa077583f944 Mon Sep 17 00:00:00 2001 From: nasfernane Date: Sun, 21 Sep 2025 12:05:35 +0200 Subject: [PATCH 05/12] feat: sanitize blog html content, format date and add read time estimation --- blog/JS-X-Ray-6.0.html | 24 +- blog/announcing-nodesecure-vuln-era.html | 12 +- ...u-need-to-know-about-package-managers.html | 76 +-- blog/index.html | 120 +++- blog/securizing-your-github-org.html | 22 +- package-lock.json | 558 +++++++++++++++++- package.json | 2 + public/css/blog.css | 12 +- src/build-articles.js | 169 ++++-- 9 files changed, 829 insertions(+), 166 deletions(-) diff --git a/blog/JS-X-Ray-6.0.html b/blog/JS-X-Ray-6.0.html index ceb9586..884f47e 100644 --- a/blog/JS-X-Ray-6.0.html +++ b/blog/JS-X-Ray-6.0.html @@ -55,9 +55,9 @@

    JS-X-Ray 6.0

    Hello πŸ‘‹

    -

    It's been a while since the last article on JS-X-Ray 😲!

    +

    It's been a while since the last article on JS-X-Ray 😲!

    {% link https://dev.to/nodesecure/js-x-ray-3-0-0-3ddn %}

    -

    In this article I will present you the latest major version πŸ‘€. I didn't do an article on version 4 and 5 because they didn't introduce new features (only breaking changes on the API).

    +

    In this article I will present you the latest major version πŸ‘€. I didn't do an article on version 4 and 5 because they didn't introduce new features (only breaking changes on the API).

    πŸ“’ What is JS-X-Ray ?

    If you are new in town, JS-X-Ray is an open source JavaScript SAST (Static Application Security Testing). The tool analyzes your JavaScript sources for patterns that may affect the security and quality of your project 😎.

    Among the notable features:

    @@ -77,13 +77,13 @@

    Major release 4 and 5

    Those information are visible in the NodeSecure CLI interface:

    NodeSecure

    Major release 6

    -

    🐬 Ok, let's dive into this major release to discover the surprises πŸŽ‰ it has in store for us.

    +

    🐬 Ok, let's dive into this major release to discover the surprises πŸŽ‰ it has in store for us.

    πŸš€ Introducing VariableTracer

    Almost a year of work on this new mechanism / class that brings a whole new dimension to JS-X-Ray.

    const tracer = new VariableTracer()
       .enableDefaultTracing()
    -  .trace("crypto.createHash", {
    -    followConsecutiveAssignment: true, moduleName: "crypto"
    +  .trace("crypto.createHash", {
    +    followConsecutiveAssignment: true, moduleName: "crypto"
       });
     
     tracer.walk(node);
    @@ -92,15 +92,15 @@ 

    πŸš€ Introducing VariableTracer

    const aA = Function.prototype.call;
     const bB = require;
     
    -const crypto = aA.call(bB, bB, "crypto");
    +const crypto = aA.call(bB, bB, "crypto");
     const cr = crypto.createHash;
    -cr("md5"); // weak-crypto warning is throw here
    +cr("md5"); // weak-crypto warning is throw here
     

    This allows us to implement Probes in a much simpler way (which makes maintenance and testing much easier).

    Here an example with the isWeakCrypto probe:

    function validateNode(node, { tracer }) {
       const id = getCallExpressionIdentifier(node);
    -  if (id === null || !tracer.importedModules.has("crypto")) {
    +  if (id === null || !tracer.importedModules.has("crypto")) {
         return [false];
       }
     
    @@ -108,7 +108,7 @@ 

    πŸš€ Introducing VariableTracer

    return [ data !== null && - data.identifierOrMemberExpr === "crypto.createHash" + data.identifierOrMemberExpr === "crypto.createHash" ]; }
    @@ -138,8 +138,8 @@

    πŸ”¬ Improving coverage

  • Mathieu KA
  • M4gie
  • -

    πŸ‘€ What's next ?

    -

    Here what I'm working for the next major release:

    +

    πŸ‘€ What's next ?

    +

    Here what I'm working for the next major release:

    • Adding support of TypeScript sources (probably by allowing a customization of the parser).
    • A new API that allows to dynamically extend the SAST with new custom probes (and custom warnings).
    • @@ -148,7 +148,7 @@

      πŸ‘€ What's next ?

      I will continue to work to reduce the number of false positives and keep improving obfuscated codes detection.


      Please think to drop a star on github ❀️!

      -

      That's it for today! Thanks for reading me πŸ˜‰

      +

      That's it for today! Thanks for reading me πŸ˜‰

    diff --git a/blog/announcing-nodesecure-vuln-era.html b/blog/announcing-nodesecure-vuln-era.html index 3f744de..067890b 100644 --- a/blog/announcing-nodesecure-vuln-era.html +++ b/blog/announcing-nodesecure-vuln-era.html @@ -56,9 +56,9 @@

    NodeSecure Vuln-era

    Hello πŸ‘‹,

    Back for a little article about the rebranding of one of the NodeSecure tools: Vulnera (previously vuln, the vuln-era has begun!).

    -

    An opportunity for me to also write about this wonderful project that was born with the redesign of the back-end less than a year ago ⌚. If you don't remember I wrote an article:

    +

    An opportunity for me to also write about this wonderful project that was born with the redesign of the back-end less than a year ago ⌚. If you don't remember I wrote an article:

    {% link https://dev.to/fraxken/announcing-new-node-secure-back-end-1dp9 %}

    -

    Don't wait and dive in 🌊 with me to discover this tool πŸ’ƒ.

    +

    Don't wait and dive in 🌊 with me to discover this tool πŸ’ƒ.

    What is Vulnera ? πŸ‘€

    Vulnera is a package that allows you to programmatically fetch your Node.js project vulnerabilities from multiple sources or strategies:

      @@ -71,7 +71,7 @@

      What is Vulnera ? πŸ‘€

      πŸ“’ Feel free to push new sources (we have a guide on how to add/contribute one).

      The code was originally designed for vulnerability management within the Scanner. Yet, its API is evolving with the objective of making it a full-fledged project.

      -
      import * as vulnera from "@nodesecure/vulnera";
      +
      import * as vulnera from "@nodesecure/vulnera";
       
       const def = await vulnera.setStrategy(
         vulnera.strategies.NPM_AUDIT
      @@ -95,7 +95,7 @@ 

      Standard vulnerability format πŸ‘―

      title: string; /** Vulnerability description **/ description?: string; - /** Vulnerability link references on origin's website **/ + /** Vulnerability link references on origin's website **/ url?: string; /** Vulnerability severity levels given the strategy **/ severity?: Severity; @@ -135,7 +135,7 @@

      Usage in Scanner πŸ”¬

      The following diagram explains the overall behavior and interactions between the Scanner and Vulnera. NodeSecure

      If you want to learn more about the Payload you can check the TypeScript interface here.

      -

      What's next ? πŸš€

      +

      What's next ? πŸš€

      Some sources are more difficult to exploit than others (for NPM we use Arborist which simplifies our lives).

      const { vulnerabilities } = (await arborist.audit()).toJSON();
       
      @@ -151,7 +151,7 @@

      Credits πŸ™‡

      Fun fact: its first contribution 🐀 on NodeSecure was also on the old version of the code Scanner that managed vulnerabilities.

      -

      But I don't forget individual contributions πŸ‘

      +

      But I don't forget individual contributions πŸ‘

      • Mathieu Kahlaoui for adding the getVulnerabilities() API
      • Oleh Sych for adding Snyk strategy
      • diff --git a/blog/everything-you-need-to-know-about-package-managers.html b/blog/everything-you-need-to-know-about-package-managers.html index 3480cd8..35071f1 100644 --- a/blog/everything-you-need-to-know-about-package-managers.html +++ b/blog/everything-you-need-to-know-about-package-managers.html @@ -60,7 +60,7 @@

        Everything you need to know: package managers

        This responsibility is that of a package manager and several can intervene within the same computer system.

        Operating system

        The majority of Unix-based operating systems embed a package manager as standard, providing a multitude of different packages very simply.

        -

        If you have ever used a Linux distribution such as Ubuntu or Debian, you've probably used a package manager before. If I say apt-get update does that ring a bell?

        +

        If you have ever used a Linux distribution such as Ubuntu or Debian, you've probably used a package manager before. If I say apt-get update does that ring a bell?

        This command tells APT to update all versions of packages installed. APT (Advanced Packaging Tool) is a package manager embedded very widely as standard on Linux operating systems. To install a package, you can for example enter the command apt-get install <package>.

        Programming language

        Most programming languages ​​can embed their own with package managers, either natively or provided within their respective ecosystem.

        @@ -75,7 +75,7 @@

        Programming language

        In four parts, we will see what are the main reasons for such an expansion of package managers to all layers of a computer system.

        1. Ease of use and maintenance of packages

        -

        The main interest of a package manager is obviously to simplify the installation of dependencies external to our application. Before the rise of npm in January 2010, the dependencies of a JavaScript application were mostly installed manually. By "manual installation" I mean:

        +

        The main interest of a package manager is obviously to simplify the installation of dependencies external to our application. Before the rise of npm in January 2010, the dependencies of a JavaScript application were mostly installed manually. By "manual installation" I mean:

        • downloading a zip archive from a remote server
        • unzipping the archive in the project
        • @@ -98,24 +98,24 @@

          Programming language

          With this command, the package manager will search within the registry for a package that has the name rxjs. When the version is not specified, the package manager will usually install the latest available version.

          1.2. Use

          // ECMAScript Modules (ESM)
          -import { of } from "rxjs";
          +import { of } from "rxjs";
           // CommonJS
          -const { of } = require("rxjs");
          +const { of } = require("rxjs");
           

          The module systems integrated into the programming languages ​​make it possible to import a library installed locally and sometimes remotely (like Go or Deno for example). In this case with Node.js, the package must be installed locally in a node_modules folder. With Node.js, the module resolution algorithm allows the dependency to be in a node_modules folder either adjacent to the source code or in a parent folder (which sometimes leads to an unexpected behavior).

          2. Managing the consistency of installed packages

          -

          Now, let's dive into a little more detail on one very important aspect that a package manager must manage: state consistency between installed packages. So far, installing a package looks like a trivial task, which is just to automate downloading a package of a certain version and making it available in a conventional folder that the application has access to.

          +

          Now, let's dive into a little more detail on one very important aspect that a package manager must manage: state consistency between installed packages. So far, installing a package looks like a trivial task, which is just to automate downloading a package of a certain version and making it available in a conventional folder that the application has access to.

          However this management of consistency between packages turns out to be relatively difficult and the way of modeling the dependency tree varies according to the ecosystems. Most of the time, we talk about a dependency tree, but we can also talk about a dependency graph, in particular a directed graph.

          If you are not familiar with the concept of directed graphs, I invite you to read the series of articles I wrote about it on dev.to with examples in JavaScript.

          The implementations of these data structures can be drastically different depending on the ecosystem of a package manager, but also between package managers of the same ecosystem (npm, yarn, pnpm for Node.js for example).

          How to ensure that all developers share the same dependencies and therefore the same versions of each underlying library?

          -

          Still in the context of npm, let's take for example a very simple list of dependencies, expressed as an object in the package.json file:

          +

          Still in the context of npm, let's take for example a very simple list of dependencies, expressed as an object in the package.json file:

          package.json

          { 
          -  "dependencies": {
          -    "myDependencyA": "<0.1.0"
          +  "dependencies": {
          +    "myDependencyA": "<0.1.0"
             }
           }
           
          @@ -123,8 +123,8 @@

          2. Managing the consistency of installed packages

          Semantic version management (commonly known as SemVer) is the application of a very precise specification to characterize the version of software. For more information on this subject, I invite you to take a look at the official specification https://semver.org/lang/fr/

          -

          In our case, by remaining on the classic <major>.<minor>.<patch> scheme, we express the possibility of installing all the versions of myDependencyA from "0.0.1" to "0.0.9". This therefore means that any version of the dependency that respects the range is considered valid. On the other hand, this also means that if a developer A installs the dependency at 2 p.m. and a developer B installs the dependency at 5 p.m., they may both not have the same dependency tree if ever a new version of myDependencyA is released in the meantime.

          -

          The npm dependency resolution algorithm will by default favor the installation of the most recent dependency that respects the semantic management described in the package.json. By specifying npm install myDependencyA, the most recent version of myDependencyA will be installed respecting the constraint "<1.0.0" (version strictly lower than "1.0.0").

          +

          In our case, by remaining on the classic <major>.<minor>.<patch> scheme, we express the possibility of installing all the versions of myDependencyA from "0.0.1" to "0.0.9". This therefore means that any version of the dependency that respects the range is considered valid. On the other hand, this also means that if a developer A installs the dependency at 2 p.m. and a developer B installs the dependency at 5 p.m., they may both not have the same dependency tree if ever a new version of myDependencyA is released in the meantime.

          +

          The npm dependency resolution algorithm will by default favor the installation of the most recent dependency that respects the semantic management described in the package.json. By specifying npm install myDependencyA, the most recent version of myDependencyA will be installed respecting the constraint "<1.0.0" (version strictly lower than "1.0.0").

          The major problem with this approach is the lack of stability and reproducibility of the dependency tree from one computer to another, for example between developers or even on the machine used in production. Imagine that version 0.0.9 of myDependencyA has just been released with a bug and your production machine is about to do an npm install on Friday at 5:59 PM…

          Production deployment on friday night

          The very simple example is often referred as version drift. This is why a single description file (in this case package.json) cannot be enough to guarantee an identical and reproducible representation of a dependency tree.

          @@ -136,22 +136,22 @@

          2. Managing the consistency of installed packages

        Lockfiles to the rescue

        To ensure the reproducibility of a dependency tree, we therefore need more information that would ideally describe the current state of our dependency tree. This is exactly what lockfiles do. These are files created and updated when the dependencies of a project are modified.

        -

        A lockfile is generally written in JSON or YAML format to simplify the readability and understanding of the dependency tree by a human. A lockfile makes it possible to describe the dependency tree in a very precise way and therefore to make it deterministic and reproducible from one environment to another. So it's important to commit this file to Git and make sure everyone is sharing the same lockfile.

        +

        A lockfile is generally written in JSON or YAML format to simplify the readability and understanding of the dependency tree by a human. A lockfile makes it possible to describe the dependency tree in a very precise way and therefore to make it deterministic and reproducible from one environment to another. So it's important to commit this file to Git and make sure everyone is sharing the same lockfile.

        package-lock.json

        {
        -  "name": "myProject",
        -  "version": "1.0.0",
        -  "dependencies": {
        -    "myDependencyA": {
        -      "version": "0.0.5",
        -      "resolved": "https://registry.npmjs.org/myDependencyA/-/myDependencyA-0.0.5.tgz",
        -      "integrity": "sha512-DeAdb33F+"
        -      "dependencies": {
        -        "B": {
        -          "version": "0.0.1",
        -          "resolved": "https://registry.npmjs.org/B/-/B-0.0.1.tgz",
        -          "integrity": "sha512-DeAdb33F+"
        -          "dependencies": {
        +  "name": "myProject",
        +  "version": "1.0.0",
        +  "dependencies": {
        +    "myDependencyA": {
        +      "version": "0.0.5",
        +      "resolved": "https://registry.npmjs.org/myDependencyA/-/myDependencyA-0.0.5.tgz",
        +      "integrity": "sha512-DeAdb33F+"
        +      "dependencies": {
        +        "B": {
        +          "version": "0.0.1",
        +          "resolved": "https://registry.npmjs.org/B/-/B-0.0.1.tgz",
        +          "integrity": "sha512-DeAdb33F+"
        +          "dependencies": {
                     // dependencies of B
                   }
                 }
        @@ -162,13 +162,13 @@ 

        2. Managing the consistency of installed packages

        For npm, the basic lockfile is called package-lock.json. In the snippet above, we can precisely see several important information:

          -
        • The version of myDependencyA is fixed at "0.0.5" so even if a new version is released, npm will install "0.0.5" no matter what.
        • +
        • The version of myDependencyA is fixed at "0.0.5" so even if a new version is released, npm will install "0.0.5" no matter what.
        • Each indirect dependency describes its set of dependencies with versions that also describe their own versioning constraints.
        • In addition to the version, the contents of the dependencies can be checked with the comparison of hashes which can vary according to the registers used.

        A lockfile therefore tries to accurately describes the dependency tree, which allows it to remain consistent and reproducible over time at each installation.

        ⚠️ But...

        -

        Lockfiles don't solve all inconsistency problems! Package managers implementations of the dependency graph can sometimes lead to inconsistencies. For a long time, npm's implementation introduced Phantom Dependencies and also NPM doppelgangers which are very well explained on the Rush.js documentation website (advanced topics that are out of the scope of this blog post).

        +

        Lockfiles don't solve all inconsistency problems! Package managers implementations of the dependency graph can sometimes lead to inconsistencies. For a long time, npm's implementation introduced Phantom Dependencies and also NPM doppelgangers which are very well explained on the Rush.js documentation website (advanced topics that are out of the scope of this blog post).

        3. Provision of distributed and transparent databases via open-source

        Distributed registries

        A package manager is a client that acts as a gateway to a distributed database (often called a registry). This allows in particular to share an infinite number of open-source libraries around the world. It is also possible to define company-wide private registries in a secured network, within which libraries would be accessible.

        @@ -185,25 +185,25 @@

        4. Security and integrity

        Integrity safety for each installed package

        Given that a package can be installed from any registry, it is important to implement verification mechanisms at the level of the content of the downloaded package, to ensure that no malicious code has been injected during the download, regardless of its origin.

        For this, integrity metadata is associated with each installed package. For example with npm, an integrity property is associated with each package in the lockfile. This property contains a cryptographic hash which is used to accurately represent the resource the user expects to receive. This allows any program to verify that the content of the resource matches what was downloaded. For example for @babel/core, this is how integrity is represented in package-lock.json:

        -
        "@babel/core": {
        -   "version": "7.16.10",
        -   "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.10.tgz",  
        -   "integrity": "sha512 pbiIdZbCiMx/MM6toR+OfXarYix3uz0oVsnNtfdAGTcCTu3w/JGF8JhirevXLBJUu0WguSZI12qpKnx7EeMyLA=="
        +
        "@babel/core": {
        +   "version": "7.16.10",
        +   "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.10.tgz",  
        +   "integrity": "sha512 pbiIdZbCiMx/MM6toR+OfXarYix3uz0oVsnNtfdAGTcCTu3w/JGF8JhirevXLBJUu0WguSZI12qpKnx7EeMyLA=="
         }
         
        -

        Let's take a closer look at how integrity can drastically reduce the risk of injecting malicious code by hashing source code.

        +

        Let's take a closer look at how integrity can drastically reduce the risk of injecting malicious code by hashing source code.

        As a reminder:

        We call hash function, a particular function which, from a datum supplied as input, calculates a digital fingerprint used to quickly identify the initial datum, in the same way as a signature to identify a person. Wikipedia

        -

        Let's take for example a simple case:

        +

        Let's take for example a simple case:

        // my-library
         function someJavaScriptCode() {
           addUser();
         }
         
        -

        Let's imagine that this JavaScript code represents a resource that a user might want to download. Using the SHA1 hash function, we get the hash 7677152af4ef8ca57fcb50bf4f71f42c28c772be. -If ever malicious code is injected, the library's fingerprint will by definition change because the input (source code here) to the hash function will have changed:

        +

        Let's imagine that this JavaScript code represents a resource that a user might want to download. Using the SHA1 hash function, we get the hash 7677152af4ef8ca57fcb50bf4f71f42c28c772be. +If ever malicious code is injected, the library's fingerprint will by definition change because the input (source code here) to the hash function will have changed:

        // my-library
         function someJavaScriptCode() {
           processMaliciousCode(); // this is injected, the user is not  expecting that
        @@ -216,11 +216,11 @@ 

        4. Security and integrity

      • Original code = 7677152af4ef8ca57fcb50bf4f71f42c28c772be
      • Malicious code = 28d32d30caddaaaafbde0debfcd8b3300862cc24
      -

      All package managers implement strict specifications on this approach to integrity. For example, npm respects the W3C's "Subresource Integrity or SRI" specification, which describes the mechanisms to be implemented to reduce the risk of malicious code injection. +

      All package managers implement strict specifications on this approach to integrity. For example, npm respects the W3C's "Subresource Integrity or SRI" specification, which describes the mechanisms to be implemented to reduce the risk of malicious code injection. You can jump directly here to the specification document if you want to dig deeper.

      Security constraints at the author level

      To strengthen security at the level of open-source packages, more and more constraints are emerging on the side of project authors and maintainers. Recently, GitHub, which owns npm, announced that it is forcing two-factor authentication (2FA) for contributors to the 100 most popular packages. The main idea around these actions is to secure resources upstream by limiting write access to open-source packages and identifying people more precisely.

      -

      It's important to also mention that there are tools that can be used to perform automatically scans and audits continuously.

      +

      It's important to also mention that there are tools that can be used to perform automatically scans and audits continuously.

      Built-in tools

      In order to automate the detection of vulnerabilities, many package managers natively integrate tools allowing to scan the installed libraries. Typically, these package managers communicate with databases that list all known and referenced vulnerabilities. For example, GitHub Advisory Database is an open-source database that references thousands of vulnerabilities across multiple ecosystems (Go, Rust, Maven, NuGet, etc) e.g. npm audit command uses this database.

      Third-party tools

      @@ -239,8 +239,8 @@

      4. Security and integrity

      Conclusion

      There you go, you now know what issues are addressed and solved by package managers!

      Package managers are complex tools that aim to make life easier for us as developers, but can quickly become problematic if misused.

      -

      It is therefore important to understand the issues they deal with and the solutions provided in order to be able to put into perspective several package managers of the same ecosystem. In the end, it's a tool like any other and it must mobilize thinking in the same way as when libraries/frameworks/programming languages ​​are used.

      -

      Don't also forget to take into account security issues and use automated tools which can drastically reduce the attack surface!

      +

      It is therefore important to understand the issues they deal with and the solutions provided in order to be able to put into perspective several package managers of the same ecosystem. In the end, it's a tool like any other and it must mobilize thinking in the same way as when libraries/frameworks/programming languages ​​are used.

      +

      Don't also forget to take into account security issues and use automated tools which can drastically reduce the attack surface!

      diff --git a/blog/index.html b/blog/index.html index 0078edb..0a979b1 100644 --- a/blog/index.html +++ b/blog/index.html @@ -58,20 +58,37 @@

      - Thomas + Thomas
      Thomas - 21/07/2022 + + + calendar + Feb 19, 2023 + + + clock + 7 min read + +
      - NodeSecure Vuln-era + Securizing your GitHub org -

      Dive into the rebranding of Vulnera, NodeSecure’s powerful tool for uncovering Node.js vulnerabilities from multiple sources. Discover its evolution and how it’s shaping the future of open source security!

      +

      Learn hands-on strategies and real-world tips to boost the security of your GitHub organization. Perfect for open source maintainers and anyone serious about code safety!

      @@ -80,20 +97,37 @@

      - Thomas + Thomas
      - Antoine - 18/10/2022 + Thomas + + + calendar + Jan 16, 2023 + + + clock + 4 min read + +
      - Everything you need to know: package managers + JS-X-Ray 6.0 -

      Curious about package managers? Explore their essential role in modern software, from Linux to npm, and learn why they’re the backbone of every developer’s workflow!

      +

      Discover what’s new in JS-X-Ray 6.0! Explore the latest features of this open source JavaScript security analyzer and see how it helps you write safer, cleaner code.

      @@ -102,20 +136,37 @@

      - Thomas + Thomas
      - Thomas - 16/01/2023 + Antoine + + + calendar + Oct 18, 2022 + + + clock + 13 min read + +
      - JS-X-Ray 6.0 + Everything you need to know: package managers -

      Discover what’s new in JS-X-Ray 6.0! Explore the latest features of this open source JavaScript security analyzer and see how it helps you write safer, cleaner code.

      +

      Curious about package managers? Explore their essential role in modern software, from Linux to npm, and learn why they’re the backbone of every developer’s workflow!

      @@ -124,20 +175,37 @@

      - Thomas + Thomas
      Thomas - 19/02/2023 + + + calendar + Jul 21, 2022 + + + clock + 4 min read + +
      - Securizing your GitHub org + NodeSecure Vuln-era -

      Learn hands-on strategies and real-world tips to boost the security of your GitHub organization. Perfect for open source maintainers and anyone serious about code safety!

      +

      Dive into the rebranding of Vulnera, NodeSecure’s powerful tool for uncovering Node.js vulnerabilities from multiple sources. Discover its evolution and how it’s shaping the future of open source security!

      diff --git a/blog/securizing-your-github-org.html b/blog/securizing-your-github-org.html index f11693c..b72855c 100644 --- a/blog/securizing-your-github-org.html +++ b/blog/securizing-your-github-org.html @@ -56,22 +56,22 @@

      Securizing your GitHub org

      Hello πŸ‘‹

      I started open source a bit naively (like everyone I guess 😊).

      -

      But the more I progress and the more important/popular some of my projects become 😎. That's great, but at some point you have to deal with a lot of things related to security (like Vulnerability disclosure).

      -

      You start to hear and see a lot of scary stories around you 😱. Not to mention all the acronyms where you don't understand anything at first 😡 (VMT, CVE, SAST, SCA, CNA ...).

      +

      But the more I progress and the more important/popular some of my projects become 😎. That's great, but at some point you have to deal with a lot of things related to security (like Vulnerability disclosure).

      +

      You start to hear and see a lot of scary stories around you 😱. Not to mention all the acronyms where you don't understand anything at first 😡 (VMT, CVE, SAST, SCA, CNA ...).

      As I was working on an open source security project, I put pressure on myself to be ready. Also as a member of the Node.js Security WG I thought it was an interesting topic and that I was probably not the only one who was worried about not being up to the task πŸ˜–.

      So I rolled up my sleeves and tackled the problem πŸ’ͺ. Here is my feedback/journey on how I improved the security of my NodeSecure GitHub organization.

      πŸ‘€ We use Node.js and JavaScript (but most recommendations are valid for other ecosystems).

      Security Policy and Vulnerability Disclosure

      -

      Adding a root SECURITY.md file explaining how developers and security researchers should report vulnerability is important. You don't want a security threat to be turned into a public issue (This gives you time to analyze and possibly fix before disclosure).

      +

      Adding a root SECURITY.md file explaining how developers and security researchers should report vulnerability is important. You don't want a security threat to be turned into a public issue (This gives you time to analyze and possibly fix before disclosure).

      ⚠️ If you are a developer, never report a security threat using a public GitHub issue. This is a serious mistake. This could even put your business/team at risk.

      -

      I don't want to bullshit you, so let me share with you the OpenSSF guide that helped me set up my first reporting strategy: Guide to implementing a coordinated vulnerability disclosure process for open source projects.

      -

      I started from scratch by reading this guide and taking inspiration from their templates 🐀. As a small open source team we don't especially have DNS or mail servers (not even a defined Vulnerability Management Team A.K.A VMT).

      -

      I was a bit puzzled to put my personal email as I'm not alone 😟.

      -

      I quickly learned that Github added a new feature to report/create private security issue 😍. You can enable it in the Security tab (I think it's also now possible to enable it on every repositories at once).

      +

      I don't want to bullshit you, so let me share with you the OpenSSF guide that helped me set up my first reporting strategy: Guide to implementing a coordinated vulnerability disclosure process for open source projects.

      +

      I started from scratch by reading this guide and taking inspiration from their templates 🐀. As a small open source team we don't especially have DNS or mail servers (not even a defined Vulnerability Management Team A.K.A VMT).

      +

      I was a bit puzzled to put my personal email as I'm not alone 😟.

      +

      I quickly learned that Github added a new feature to report/create private security issue 😍. You can enable it in the Security tab (I think it's also now possible to enable it on every repositories at once).

      And this is what it finally looks like: NodeSecure SECURITY.md

      Use OpenSSF scorecard

      @@ -91,7 +91,7 @@

      πŸ”“ Enable branch protection

      To set up the protection, go to Settings > Branches and edit your main branch.

      -

      GitHub has quite a few options on the subject 😡. If you don't know what to choose in terms of options, don't check anything (it's ok to begin βœ”οΈ).

      +

      GitHub has quite a few options on the subject 😡. If you don't know what to choose in terms of options, don't check anything (it's ok to begin βœ”οΈ).

      If you want to be more restrictive, be careful because it could block you (some options are only viable in projects with many contributors/reviewers).

      As far as I am concerned I often choose:

      Fortunately there is a great free online tool that help you by doing all the hard work (it will open a pull-request and automatically fix issues).

      {% tweet https://twitter.com/fraxken/status/1617557370728767488 %}

      @@ -146,11 +146,11 @@

      πŸ“œ Enable Security advisories (and others)

      πŸ’‘ OpenSSF Best Pratices program

      Previously known as CII-Best-Practices, this program indicates that the project uses a set of security-focused best development practices for open source software.

      So I registered my first project on the website. It was a good surprise because it allowed me to question the quality of my documentation and tests 😬.

      -

      Seeing the different levels and questions really helps you think about what you're missing (and possibly learn about the concepts you don't know about yet.. Like SBOM).

      +

      Seeing the different levels and questions really helps you think about what you're missing (and possibly learn about the concepts you don't know about yet.. Like SBOM).

      CII-Best-Practices

      I am still working on completing the first step/badge for the CLI project which now has a score of 8.7 out of 10 πŸŽ‰ on the OpenSSF scorecard.

      🎯 Conclusion

      -

      That's it for this article. I've covered what I've done/learned in the last couple of months. Here are some really cool additional links πŸ’ƒ:

      +

      That's it for this article. I've covered what I've done/learned in the last couple of months. Here are some really cool additional links πŸ’ƒ:

      • Concise Guide for Evaluating Open Source Software 2023-01-03
      • Concise Guide for Developing More Secure Software 2023-01-03
      • diff --git a/package-lock.json b/package-lock.json index 291eca7..0b278fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,8 @@ "version": "1.0.0", "license": "MIT", "dependencies": { + "dompurify": "^3.2.7", + "jsdom": "^27.0.0", "marked": "^16.3.0", "zup": "^0.0.2" }, @@ -17,6 +19,169 @@ "vite": "^7.0.2" } }, + "node_modules/@asamuzakjp/css-color": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.0.4.tgz", + "integrity": "sha512-cKjSKvWGmAziQWbCouOsFwb14mp1betm8Y7Fn+yglDMUUu3r9DCbJ9iJbeFDenLMqFbIMC0pQP8K+B8LAxX3OQ==", + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-color-parser": "^3.0.10", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "lru-cache": "^11.1.0" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.5.5.tgz", + "integrity": "sha512-kI2MX9pmImjxWT8nxDZY+MuN6r1jJGe7WxizEbsAEPB/zxfW5wYLIiPG1v3UKgEOOP8EsDkp0ZL99oRFAdPM8g==", + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.1.0", + "is-potential-custom-element-name": "^1.0.1" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "license": "MIT" + }, + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.14.tgz", + "integrity": "sha512-zSlIxa20WvMojjpCSy8WrNpcZ61RqfTfX3XTaOeVlGJrt/8HF3YbzgFZa01yTbT4GWQLwfTcC3EB8i3XnB647Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", @@ -1092,6 +1257,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.35.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.1.tgz", @@ -1372,6 +1544,15 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1419,6 +1600,15 @@ "dev": true, "license": "MIT" }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, "node_modules/brace-expansion": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", @@ -1511,11 +1701,50 @@ "node": ">= 8" } }, + "node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/cssstyle": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.1.tgz", + "integrity": "sha512-g5PC9Aiph9eiczFpcgUhd9S4UUO3F+LHGRIi5NUMZ+4xtoIYbHNZwZnWA2JsFGe8OU8nl4WyaEFiZuGuxlutJQ==", + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^4.0.3", + "@csstools/css-syntax-patches-for-csstree": "^1.0.14", + "css-tree": "^3.1.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/data-urls": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.0.tgz", + "integrity": "sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==", + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^15.0.0" + }, + "engines": { + "node": ">=20" + } + }, "node_modules/debug": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -1529,6 +1758,12 @@ } } }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "license": "MIT" + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -1536,6 +1771,27 @@ "dev": true, "license": "MIT" }, + "node_modules/dompurify": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", + "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/esbuild": { "version": "0.25.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", @@ -1990,6 +2246,56 @@ "node": ">= 0.4" } }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -2076,6 +2382,12 @@ "node": ">=0.12.0" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "license": "MIT" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2096,6 +2408,45 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsdom": { + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.0.0.tgz", + "integrity": "sha512-lIHeR1qlIRrIN5VMccd8tI2Sgw6ieYXSVktcSHaNe3Z5nE/tcPQYQWOq00wxMvYOsz+73eAkNenVvmPC6bba9A==", + "license": "MIT", + "dependencies": { + "@asamuzakjp/dom-selector": "^6.5.4", + "cssstyle": "^5.3.0", + "data-urls": "^6.0.0", + "decimal.js": "^10.5.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^7.3.0", + "rrweb-cssom": "^0.8.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^15.0.0", + "ws": "^8.18.2", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -2164,6 +2515,15 @@ "dev": true, "license": "MIT" }, + "node_modules/lru-cache": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.1.tgz", + "integrity": "sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==", + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/marked": { "version": "16.3.0", "resolved": "https://registry.npmjs.org/marked/-/marked-16.3.0.tgz", @@ -2176,6 +2536,12 @@ "node": ">= 20" } }, + "node_modules/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "license": "CC0-1.0" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -2233,14 +2599,12 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "dev": true, "funding": [ { "type": "github", @@ -2325,6 +2689,18 @@ "node": ">=6" } }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -2349,7 +2725,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, "license": "ISC" }, "node_modules/picomatch": { @@ -2369,7 +2744,6 @@ "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "dev": true, "funding": [ { "type": "opencollective", @@ -2408,7 +2782,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -2435,6 +2808,15 @@ ], "license": "MIT" }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -2496,6 +2878,12 @@ "fsevents": "~2.3.2" } }, + "node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", + "license": "MIT" + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -2520,6 +2908,24 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", @@ -2560,7 +2966,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -2592,6 +2997,12 @@ "node": ">=8" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "license": "MIT" + }, "node_modules/tinyglobby": { "version": "0.2.14", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", @@ -2609,6 +3020,24 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/tldts": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.15.tgz", + "integrity": "sha512-heYRCiGLhtI+U/D0V8YM3QRwPfsLJiP+HX+YwiHZTnWzjIKC+ZCxQRYlzvOoTEc6KIP62B1VeAN63diGCng2hg==", + "license": "MIT", + "dependencies": { + "tldts-core": "^7.0.15" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.15.tgz", + "integrity": "sha512-YBkp2VfS9VTRMPNL2PA6PMESmxV1JEVoAr5iBlZnB5JG3KUrWzNCB3yNNkRa2FZkqClaBgfNYCp8PgpYmpjkZw==", + "license": "MIT" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -2622,6 +3051,30 @@ "node": ">=8.0" } }, + "node_modules/tough-cookie": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz", + "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==", + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, "node_modules/ts-api-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", @@ -2771,6 +3224,61 @@ } } }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.0.tgz", + "integrity": "sha512-n4W4YFyz5JzOfQeA8oN7dUYpR+MBP3PIUsn2jLjWXwK5ASUzt0Jc/A5sAUZoCYFJRGF0FBKJ+1JjN43rNdsQzA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-15.1.0.tgz", + "integrity": "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==", + "license": "MIT", + "dependencies": { + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.0" + }, + "engines": { + "node": ">=20" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -2797,6 +3305,42 @@ "node": ">=0.10.0" } }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "license": "MIT" + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index ce7a464..4948e9f 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,8 @@ "vite": "^7.0.2" }, "dependencies": { + "dompurify": "^3.2.7", + "jsdom": "^27.0.0", "marked": "^16.3.0", "zup": "^0.0.2" } diff --git a/public/css/blog.css b/public/css/blog.css index 83daf3b..007765e 100644 --- a/public/css/blog.css +++ b/public/css/blog.css @@ -83,9 +83,11 @@ h1.article-title { .article-content > p:has(img) { display: flex; + flex-direction: column; justify-content: start; align-items: center; gap: 20px; + max-width: 100%; } .article-content > pre { @@ -186,7 +188,7 @@ h1.article-title { margin-bottom: 1rem; } -.article-card-header img { +.article-card-header .authorImg { width: 60px; height: 60px; border-radius: 50%; @@ -194,10 +196,18 @@ h1.article-title { 0 0 0 6px rgba(0, 209, 255, 0.18), 0 0 24px 8px #00d1ff55, 0 0 48px 8px #3722af33; + transition: transform 0.3s, box-shadow 0.3s; background: linear-gradient(120deg, #261877 0%, #3722AF 100%); object-fit: cover; } +.article-card-header .authorImg:hover { + box-shadow: + 0 0 0 8px #00d1ff88, + 0 0 32px 12px #00d1ff77, + 0 0 64px 16px #3722af55; +} + .article-card-header-infos { display: flex; flex-direction: column; diff --git a/src/build-articles.js b/src/build-articles.js index 5241c46..8dc6a4a 100644 --- a/src/build-articles.js +++ b/src/build-articles.js @@ -4,66 +4,43 @@ import path from "node:path"; // Import Third-party Dependencies import { marked } from "marked"; +import createDOMPurify from "dompurify"; +import { JSDOM } from "jsdom"; const inputDir = "./articles"; const outputDir = "./blog"; const coreContributors = []; -// function markdownToHtml(markdown) { -// let html = markdown; - -// // escapes "<" that are not html tags -// html = html.replace(/$1

    "); -// html = html.replace(/^## (.*$)/gim, "

    $1

    "); -// html = html.replace(/^# (.*$)/gim, "

    $1

    "); - -// // bold text -// html = html.replace(/\*\*(.*?)\*\*/g, "$1"); - -// // italic text -// html = html.replace(/\*(.*?)\*/g, "$1"); - -// // links [text](url) -// html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1'); - -// // code blocks ``` -// const usedLangages = ["json", "js", "ts", "css"]; - -// for (const lang of usedLangages) { -// const regex = new RegExp(`\`\`\`${lang}([\\s\\S]*?)\`\`\``, "g"); -// html = html.replace(regex, "
    $1
    "); -// } - -// // line breaks -// html = html.replace(/\n\n/g, "

    "); -// html = "

    " + html + "

    "; - -// // empty paragraphs -// // html = html.replace(/

    <\/p>/g, ""); - -// return html; -// } - function generateBlogPost(markdownFile) { const markdownContent = fs.readFileSync(markdownFile, "utf8"); const fileName = path.basename(markdownFile, ".md"); + // retrieve metadata and dirty html from yaml file const { metadata, content } = parseYamlFile(markdownContent); - // const htmlContent = markdownToHtml(content); const htmlContent = marked.parse(content); - const baseArticleTemplate = fs.readFileSync(`${outputDir}/article-base-template.html`, "utf-8"); + // sanitize html + const window = new JSDOM("").window; + const DOMPurify = createDOMPurify(window); + const sanitizedHtmlContent = DOMPurify.sanitize(htmlContent); + + metadata.readTime = getReadTimeEstimation(sanitizedHtmlContent); + + const baseArticleTemplate = fs.readFileSync( + `${outputDir}/article-base-template.html`, + "utf-8" + ); - const articleTemplate = baseArticleTemplate.replace("

    ", ` + const articleTemplate = baseArticleTemplate.replace( + "
    ", + `

    ${metadata.title}

    - ${htmlContent} + ${sanitizedHtmlContent}
    -
    `); + ` + ); if (!fs.existsSync(outputDir)) { fs.mkdirSync(outputDir, { recursive: true }); @@ -108,8 +85,18 @@ function parseYamlFile(content) { const trimmedLine = line.trim(); if (trimmedLine && trimmedLine.includes(":")) { const [key, ...valueParts] = trimmedLine.split(":"); - const value = valueParts.join(":").trim(); - metadata[key.trim()] = value; + + const dataKey = key.trim(); + const dataValue = valueParts.join(":").trim(); + + if (dataKey === "date") { + const [day, month, year] = dataValue.split("/").map(Number); + const date = new Date(year, month - 1, day); + metadata[dataKey] = date; + } + else { + metadata[dataKey] = dataValue; + } } } @@ -122,8 +109,7 @@ export function convertAllMarkdownArticles() { throw new Error(`${inputDir} directory does not exist`); } - const files = fs.readdirSync(inputDir) - .filter((file) => file.endsWith(".md")); + const files = fs.readdirSync(inputDir).filter((file) => file.endsWith(".md")); const articles = files.map((file) => { const filePath = path.join(inputDir, file); @@ -136,24 +122,44 @@ export function convertAllMarkdownArticles() { } function generateBlogIndex(articles) { - const articlesList = articles.map((article) => { - const coreContributor = coreContributors.filter((c) => c.github === article.author)?.[0]; - console.log("coreContributors", coreContributors); - - const imgSource = coreContributor?.github - ? `https://github.com/${coreContributor.github}.png` - : "https://img.icons8.com/ios-glyphs/30/test-account.png"; - - return ` + const articlesList = articles + .sort((articleA, articleB) => articleB.date - articleA.date) + .map((article) => { + const coreContributor = coreContributors.filter( + (c) => c.github === article.author + )?.[0]; + + const imgSource = coreContributor?.github + ? `https://github.com/${coreContributor.github}.png` + : "https://img.icons8.com/ios-glyphs/30/test-account.png"; + + return `
    - Thomas + Thomas
    ${coreContributor?.name || article.author} - ${article.date} + + + calendar + ${formatDate(article.date)} + + + clock + ${article.readTime} min read + +
    `; - }).join("\n "); + }) + .join("\n "); - const baseTemplate = fs.readFileSync(`${outputDir}/index-base-template.html`, "utf-8"); + const baseTemplate = fs.readFileSync( + `${outputDir}/index-base-template.html`, + "utf-8" + ); - const indexTemplate = baseTemplate.replace('
    ', ` + const indexTemplate = baseTemplate.replace( + '
    ', + `
    ${articlesList} -
    `); + ` + ); const indexPath = path.join(outputDir, "index.html"); fs.writeFileSync(indexPath, indexTemplate); } +function formatDate(date) { + if (!(date instanceof Date)) { + return date; + } + + const day = date.getDate(); + const month = date.toLocaleString("en-US", { month: "short" }); + const year = date.getFullYear(); + + return `${month} ${day}, ${year}`; +} + +function getReadTimeEstimation(content) { + // remove HTML tags to get plain text, regroup white spaces + const text = content.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim(); + + // get words count filtering empty elements out + const wordCount = text.split(" ").filter(Boolean).length; + + // calculate minutes, round up to nearest integer - min is one minute + return Math.max(1, Math.ceil(wordCount / 200)); +} + (async() => { - const response = await fetch("https://raw.githubusercontent.com/NodeSecure/Governance/main/contributors.json"); + const response = await fetch( + "https://raw.githubusercontent.com/NodeSecure/Governance/main/contributors.json" + ); if (!response.ok) { - throw new Error(`Error while fetching contributors list: ${response.status}`); + throw new Error( + `Error while fetching contributors list: ${response.status}` + ); } const contributors = await response.json(); @@ -194,4 +234,3 @@ function generateBlogIndex(articles) { convertAllMarkdownArticles(); })(); - From fd6e2f0d8d67e24c7a6c1d4dc5f91639c46e64d5 Mon Sep 17 00:00:00 2001 From: nasfernane Date: Sun, 21 Sep 2025 12:54:09 +0200 Subject: [PATCH 06/12] fix: format external dev.to article links --- blog/JS-X-Ray-6.0.html | 2 +- blog/announcing-nodesecure-vuln-era.html | 2 +- blog/securizing-your-github-org.html | 2 +- public/css/blog.css | 5 +++++ src/build-articles.js | 11 +++++++++-- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/blog/JS-X-Ray-6.0.html b/blog/JS-X-Ray-6.0.html index 884f47e..6aacc71 100644 --- a/blog/JS-X-Ray-6.0.html +++ b/blog/JS-X-Ray-6.0.html @@ -56,7 +56,7 @@

    JS-X-Ray 6.0

    Hello πŸ‘‹

    It's been a while since the last article on JS-X-Ray 😲!

    -

    {% link https://dev.to/nodesecure/js-x-ray-3-0-0-3ddn %}

    +

    β†ͺ Read article

    In this article I will present you the latest major version πŸ‘€. I didn't do an article on version 4 and 5 because they didn't introduce new features (only breaking changes on the API).

    πŸ“’ What is JS-X-Ray ?

    If you are new in town, JS-X-Ray is an open source JavaScript SAST (Static Application Security Testing). The tool analyzes your JavaScript sources for patterns that may affect the security and quality of your project 😎.

    diff --git a/blog/announcing-nodesecure-vuln-era.html b/blog/announcing-nodesecure-vuln-era.html index 067890b..d3e4f4d 100644 --- a/blog/announcing-nodesecure-vuln-era.html +++ b/blog/announcing-nodesecure-vuln-era.html @@ -57,7 +57,7 @@

    NodeSecure Vuln-era

    Hello πŸ‘‹,

    Back for a little article about the rebranding of one of the NodeSecure tools: Vulnera (previously vuln, the vuln-era has begun!).

    An opportunity for me to also write about this wonderful project that was born with the redesign of the back-end less than a year ago ⌚. If you don't remember I wrote an article:

    -

    {% link https://dev.to/fraxken/announcing-new-node-secure-back-end-1dp9 %}

    +

    β†ͺ Read article

    Don't wait and dive in 🌊 with me to discover this tool πŸ’ƒ.

    What is Vulnera ? πŸ‘€

    Vulnera is a package that allows you to programmatically fetch your Node.js project vulnerabilities from multiple sources or strategies:

    diff --git a/blog/securizing-your-github-org.html b/blog/securizing-your-github-org.html index b72855c..e297b13 100644 --- a/blog/securizing-your-github-org.html +++ b/blog/securizing-your-github-org.html @@ -156,7 +156,7 @@

    🎯 Conclusion

  • Concise Guide for Developing More Secure Software 2023-01-03
  • If you work with NPM, I invite you to read our latest article about package managers:

    -

    {% link https://dev.to/nodesecure/everything-you-need-to-know-package-managers-286c %}

    +

    β†ͺ Read article

    Obviously, I probably still have a lot to learn. But I hope this will help other maintainers/developers ❀️.

    πŸ™ Thanks for reading me πŸ™

    diff --git a/public/css/blog.css b/public/css/blog.css index 007765e..c35390f 100644 --- a/public/css/blog.css +++ b/public/css/blog.css @@ -223,3 +223,8 @@ h1.article-title { .article-card-header-infos > span:last-child { font-size: 12px; } + + +.external-article-link:hover { + text-decoration: underline; +} diff --git a/src/build-articles.js b/src/build-articles.js index 8dc6a4a..21545fc 100644 --- a/src/build-articles.js +++ b/src/build-articles.js @@ -17,12 +17,19 @@ function generateBlogPost(markdownFile) { // retrieve metadata and dirty html from yaml file const { metadata, content } = parseYamlFile(markdownContent); - const htmlContent = marked.parse(content); + // replace dev.to articles links + const contentWithLinks = content.replace( + /{%\s*link\s+(https?:\/\/[^\s%]+)\s*%}/g, + 'β†ͺ Read article' + ); + const htmlContent = marked.parse(contentWithLinks); // sanitize html const window = new JSDOM("").window; const DOMPurify = createDOMPurify(window); - const sanitizedHtmlContent = DOMPurify.sanitize(htmlContent); + const sanitizedHtmlContent = DOMPurify.sanitize(htmlContent, { + ADD_ATTR: ["target", "rel", "class"] + }); metadata.readTime = getReadTimeEstimation(sanitizedHtmlContent); From 374ce3f78594776ad98e4c29348c63dea023856c Mon Sep 17 00:00:00 2001 From: nasfernane Date: Sun, 21 Sep 2025 13:27:27 +0200 Subject: [PATCH 07/12] feat: responsive on articles list --- public/css/blog.css | 29 ++++++++++++++++++++++------- public/css/index.css | 2 -- src/build-articles.js | 4 ++-- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/public/css/blog.css b/public/css/blog.css index c35390f..49265a8 100644 --- a/public/css/blog.css +++ b/public/css/blog.css @@ -5,9 +5,26 @@ .articles-list { padding: 30px; display: grid; - grid-template-columns: repeat(4, 1fr); - grid-gap: 20px; + grid-template-columns: repeat(2, 1fr); + grid-gap: 40px; z-index: 2; + margin: auto; + max-width: 70%; +} + +@media (max-width: 1600px) { + .articles-list { + grid-template-columns: repeat(2, 1fr); + max-width: 90%; + } +} + +@media (max-width: 1000px) { + .articles-list { + display: flex; + flex-direction: column; + align-items: center; + } } .article { @@ -41,8 +58,9 @@ article { } .article-content { + margin: 40px 0; max-width: 60%; - padding: 040px; + padding: 40px; background: linear-gradient(135deg, rgba(90, 68, 218, 0.5) 0%, rgba(55, 34, 175, 0.5) 100%); z-index: 2; } @@ -156,20 +174,17 @@ h1.article-title { box-shadow: 0 6px 32px #0003; background: var(--bg-img) center/cover no-repeat, #3722AF; display: flex; - align-items: flex-end; - transform: skew(-4deg); transition: transform 0.2s; z-index: 2; } .article-card:hover { - transform: skew(-4deg) scale(1.04); + transform: scale(1.04); box-shadow: 0 12px 40px #0005; } .article-card-content { min-height: 76%; - transform: skew(4deg); padding: 2rem; background: linear-gradient(0deg, #3722AFee 80%, #00D1FF44 100%); border-radius: 12px; diff --git a/public/css/index.css b/public/css/index.css index e8f7eef..ecccf10 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -42,8 +42,6 @@ a { opacity: 0.3; } - - .centered-content { width: calc(100% - 2rem); max-width: 1200px; diff --git a/src/build-articles.js b/src/build-articles.js index 21545fc..8f2ec27 100644 --- a/src/build-articles.js +++ b/src/build-articles.js @@ -215,10 +215,10 @@ function getReadTimeEstimation(content) { // remove HTML tags to get plain text, regroup white spaces const text = content.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim(); - // get words count filtering empty elements out + // get words count, filtering empty elements out const wordCount = text.split(" ").filter(Boolean).length; - // calculate minutes, round up to nearest integer - min is one minute + // calculate minutes, round up to nearest integer - one minute min return Math.max(1, Math.ceil(wordCount / 200)); } From fc6ae54e6ed8ad262917fd2b1c8fe803243c5113 Mon Sep 17 00:00:00 2001 From: nasfernane Date: Sun, 21 Sep 2025 13:53:09 +0200 Subject: [PATCH 08/12] feat: add article author links --- blog/index.html | 8 ++++---- src/build-articles.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/blog/index.html b/blog/index.html index 0a979b1..8a5d831 100644 --- a/blog/index.html +++ b/blog/index.html @@ -57,7 +57,7 @@

    - + Thomas
    @@ -96,7 +96,7 @@

    - + Thomas
    @@ -135,7 +135,7 @@

    - + Thomas
    @@ -174,7 +174,7 @@

    - + Thomas
    diff --git a/src/build-articles.js b/src/build-articles.js index 8f2ec27..858a97d 100644 --- a/src/build-articles.js +++ b/src/build-articles.js @@ -144,7 +144,7 @@ function generateBlogIndex(articles) {
    - + Thomas
    From b598c333ae1485a13b3d34a59f305d17cd2574b2 Mon Sep 17 00:00:00 2001 From: nasfernane Date: Sun, 21 Sep 2025 19:07:00 +0200 Subject: [PATCH 09/12] feat: format blog externals links --- blog/JS-X-Ray-1.0.html | 144 ++++ blog/JS-X-Ray-2.0.html | 215 ++++++ blog/JS-X-Ray-3.0.html | 100 +++ blog/NodeSecure-CLI-v2.0.0.html | 191 ++++++ ...technical-tale-of-nodesecure-chapter1.html | 185 ++++++ ...technical-tale-of-nodesecure-chapter2.html | 192 ++++++ blog/annoucing-new-nodesecure-backend.html | 163 +++++ blog/index.html | 624 ++++++++++++++++++ blog/nodesecure-pdf-report.html | 166 +++++ blog/nodesecure-the-future.html | 110 +++ blog/nodesecure-v0.4.0.html | 163 +++++ blog/nodesecure-v0.5.0.html | 179 +++++ blog/nodesecure-v0.6.0.html | 226 +++++++ blog/nodesecure-v0.7.0.html | 119 ++++ blog/nodesecure-v0.8.0.html | 128 ++++ blog/nodesecure-v0.9.0.html | 164 +++++ blog/nodesecure-whats-new-in-2022.html | 119 ++++ package.json | 2 +- public/css/blog.css | 28 +- src/build-articles.js | 80 ++- 20 files changed, 3249 insertions(+), 49 deletions(-) create mode 100644 blog/JS-X-Ray-1.0.html create mode 100644 blog/JS-X-Ray-2.0.html create mode 100644 blog/JS-X-Ray-3.0.html create mode 100644 blog/NodeSecure-CLI-v2.0.0.html create mode 100644 blog/a-technical-tale-of-nodesecure-chapter1.html create mode 100644 blog/a-technical-tale-of-nodesecure-chapter2.html create mode 100644 blog/annoucing-new-nodesecure-backend.html create mode 100644 blog/nodesecure-pdf-report.html create mode 100644 blog/nodesecure-the-future.html create mode 100644 blog/nodesecure-v0.4.0.html create mode 100644 blog/nodesecure-v0.5.0.html create mode 100644 blog/nodesecure-v0.6.0.html create mode 100644 blog/nodesecure-v0.7.0.html create mode 100644 blog/nodesecure-v0.8.0.html create mode 100644 blog/nodesecure-v0.9.0.html create mode 100644 blog/nodesecure-whats-new-in-2022.html diff --git a/blog/JS-X-Ray-1.0.html b/blog/JS-X-Ray-1.0.html new file mode 100644 index 0000000..bd2f9d5 --- /dev/null +++ b/blog/JS-X-Ray-1.0.html @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    JS-X-Ray 1.0

    +

    Hi,

    +

    While I was working on the next release (0.6.0) of Node-Secure I thought that the AST analysis was getting bigger and bigger (and much more complicated too).

    +

    That's why I decided to separate all the analysis from the Node-secure project to allow easier maintenance and future enhancement. This also allows other projects to use my package if they need to!

    +

    https://github.com/fraxken/js-x-ray

    +

    This is how JS-X-RAY was born. I have chosen the word x-ray because in games this is often a feature that allow to see through the walls, I like to imagine my analysis as being able to see through the most common techniques (obfuscation, etc.).

    +

    The goal

    +

    One of the primary goals of this package is to be able to find any required Node.js dependencies in a given code. If the analysis is not able to follow a require statement then an unsafe-import warning will be throw.

    +

    The more time goes and the more I think to make my code generic to also detect patterns specific to the front.

    +

    So I think the code will evolve in this direction :)

    +

    Example

    +
    +

    Purescript

    +

    Take the purescript-installer incident and specially the corrupted rate-map code.

    +
    +

    One of the objectives of node-secure is to be able to quickly identify code with warnings and give a bunch of very useful informations to the developer.

    +
    +

    In this case node-secure was able to detect the following dependencies: +append-type, fs, dl-tar.

    +
    const px = require.resolve(
    +Buffer.from([100, 108, 45, 116, 97, 114]).toString()
    +);
    +
    +

    My AST analysis has detected a Buffer.from and as converted the value to dl-tar itself. In this case an unsafe-import will be throw with the file name and the Source Location.

    +
    +

    Event-stream

    +

    Take the Payload A in the event-stream incident.

    +

    So what's going on here?

    +
      +
      1. +
      2. assign of process and require into new variables.
      3. +
      +
    • +
      1. +
      2. hexa value.
      3. +
      +
    • +
      1. +
      2. code obfuscated (all identifiers have a length of 1).
      3. +
      +
    • +
    +

    I'm working on a bench of experimental analysis and warnings to be able to detect similar cases to event-stream incident.

    +
    [
    +  {
    +    "kind": "unsafe-assign",
    +    "start": { "line": 3, "column": 12 },
    +    "end": { "line": 3, "column": 23 },
    +    "value": "require"      
    +  },
    +  {
    +    "kind": "unsafe-assign",
    +    "start": { "line": 4, "column": 12 },
    +    "end": { "line": 4, "column": 23 },
    +    "value": "process"
    +  },
    +  {
    +    "kind": "hexa-value",
    +    "start": { "line": 9, "column": 20 },
    +    "end": { "line": 9, "column": 44 },
    +    "value": "./test/data"
    +  },
    +  {
    +    "kind": "short-ids",
    +    "start": { "line": 0, "column": 0 },
    +    "end": { "line": 0,"column": 0 },
    +    "value": 1
    +  }
    +]
    +
    +

    However, A lot of packages may be detected as false positives (even if it's always better than nothing πŸ˜…). It will surely take time to discover and improve these parameters.

    +

    Conclusion

    +

    Still a LOT of work has to be done to be able to achieve an accurate analysis. Right now the analysis is capable of gathering a whole of very useful information (unsafe-regex, unused and missing dependencies etc.).

    +

    I am always very excited to experience new warnings because they can detect patterns and errors that are often (un)common. Step by step they also lead me to a better understanding of the most dangerous patterns of the ecosystem.

    +
    +

    For example 90%+ of the false positive are always generated because of files that was not mean to be published on the npm registry (tests, coverage files, etc.).

    +
    +

    Thanks for reading!

    +

    Best Regards, +Thomas

    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/blog/JS-X-Ray-2.0.html b/blog/JS-X-Ray-2.0.html new file mode 100644 index 0000000..f935d33 --- /dev/null +++ b/blog/JS-X-Ray-2.0.html @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    NodeSecure v0.7.0 and v0.8.0@next

    +

    Hello,

    +

    It's been a few weeks now that I've been working on a new major release for JS-X-Ray. This new version brings a lot of important changes including:

    +
      +
    • New warnings names (I've taken the time to think of consistent names).
    • +
    • New features to detect an obfuscated code (Still experimental though).
    • +
    • New format for the SourceLocation (an array instead of the ESTree SourceLocation Object).
    • +
    • Complete documentation for warnings (With explanations on technical implementation when necessary).
    • +
    • Improvement of the code as a whole (it is much more maintainable).
    • +
    • Improvement of unit tests.
    • +
    +

    The project is completely open-source and accessible on github: https://github.com/fraxken/js-x-ray (Remember to star πŸ’–).

    +

    What is JS-X-Ray?

    +

    I'll make a summary for the latecomers. (Also feel free to read the other articles in the series to better understand.)

    +

    JS-X-Ray is a free and open-source JavaScript/Node.js SAST scanner. It was mainly built to meet the needs of the Node-secure project but gradually became independent.

    +

    The project as a whole analyzes JavaScript SourceCode on format AST (Abstract Syntax Tree) and provides a set of information on it including "security" warnings.

    +

    The goal is to quickly identify dangerous patterns (in the given code) for Developers and Security researchers.

    +

    For who ?

    +

    As previously mentioned, the project is currently being used as a dependency of other security projects (Like Node-secure).

    +

    This tool is not magic and still requires basic security knowledge to tell the difference between a real problem and a false positive..

    +

    The target of the project is mainly security researchers as well as developers interested in the development of security tools.

    +

    An example?

    +

    Let's take a look at one of the previous incidents in the ecosystem (npm). For example the event-stream incident where malicious codes are still accessible here on badjs.

    +

    We're going to run an analysis on the Payload C.

    +
    const { runASTAnalysis } = require("js-x-ray");
    +const { readFileSync } = require("fs");
    +const { inspect } = require("util");
    +
    +const log = (str) => console.log(inspect(str, { compact: false, colors: true }));
    +const code = readFileSync("./event-stream-payloadc.js", "utf-8");
    +log(runASTAnalysis(code));
    +
    +
    {
    +  dependencies: ASTDeps {
    +    dependencies: [Object: null prototype] {
    +      http: [Object],
    +      crypto: [Object],
    +      'bitcore-wallet-client/lib/credentials.js': [Object]
    +    }
    +  },
    +  warnings: [
    +    {
    +      kind: 'encoded-literal',
    +      value: '636f7061796170692e686f7374',
    +      location: [Array]
    +    },
    +    {
    +      kind: 'encoded-literal',
    +      value: '3131312e39302e3135312e313334',
    +      location: [Array]
    +    },
    +    {
    +      kind: 'short-identifiers',
    +      location: [Array],
    +      value: 1
    +    }
    +  ],
    +  idsLengthAvg: 1,
    +  stringScore: 0,
    +  isOneLineRequire: false
    +}
    +
    +

    That's what JS-X-Ray return. We find the dependencies that were required within the script and some warnings:

    +
      +
    • Two encoded literals.
    • +
    • A warning telling us that identifiers in the code are too short (below an average of 1.5).
    • +
    +

    What might give us a clue here is the nature of the warnings and the used dependencies...Of course tools such as Node-secure will give you a much better view when the need is to analyse a complete project.

    +

    +

    Warnings

    +

    All warnings are explained on the README of the github. Advanced documentation on how they work and how they are implemented can be found here.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    namedescription
    parsing-errorAn error occured when parsing the JavaScript code with meriyah. It mean that the conversion from string to AST as failed. If you encounter such an error, please open an issue.
    unsafe-importUnable to follow an import (require, require.resolve) statement/expr.
    unsafe-regexA RegEx as been detected as unsafe and may be used for a ReDoS Attack. Under the hood we use the package safe-regex.
    unsafe-stmtUsage of dangerous statement like eval() or Function("").
    unsafe-assignAssignment of a protected global like process or require.
    encoded-literalAn encoded literal has been detected (it can be an hexa value, unicode sequence, base64 string etc)
    short-identifiersThis mean that all identifiers has an average length below 1.5. Only possible if the file contains more than 5 identifiers.
    suspicious-literalThis mean that the sum of suspicious score of all Literals is bigger than 3.
    obfuscated-code (experimental)There's a very high probability that the code is obfuscated...
    +

    unsafe-import

    +

    What do we mean when it is impossible to follow an expression or statement? Let's take the following example:

    +
    function boo() {
    +  // something is going on here!
    +}
    +
    +require(boo());
    +
    +

    Here the analysis is not able to follow because it would be too painful and time consuming to know what the function really returns.

    +

    unsafe-assign

    +

    A fairly common pattern among hackers is to assign global variables to new variables to hide the use of a require or eval. JS-X-Ray is able to trace the use of these variables and will consider this pattern as dangerous.

    +

    Example:

    +
    const g = global.process;
    +const r = g.mainModule;
    +const c = r.require;
    +c("http");
    +r.require("fs");
    +
    +

    obfuscated-code

    +

    He's the new kid. However the results are not yet perfect and a lot of work will be necessary in the coming months to allow the detection of more obfuscated codes.

    + +

    On the future

    +

    I wish I could iterate over the entire npm registry. I think that this project could provide us valuable insight on packages and maybe even prevent a lot of malicious code to reach npm users.

    +

    This is already what I do personally with Node-secure which allows me to secure and improve the SlimIO solution.

    +

    Beyond the security aspect, this project allows to detect and understand the use of a set of bad patterns/practices. We could also eventually guide and prevent these practices to improve the ecosystem as a whole.

    +

    At the moment I'm investing my free time to work on this project... But I would obviously like to invest myself professionally in it!

    +

    Conclusion

    +

    There's still a lot of work to be done. One of the blocking points I'm encountering at the moment is the analysis of common patterns in identifiers (which can be diverse and varied depending on the generation method).

    +

    The current version is not yet implemented on Node-secure and it might take a few weeks (I'm a bit too busy at the moment).

    +

    Hope you enjoy this article to keep you up to date with the developments and progress I have made!

    +

    Thank you for reading this series and see you soon for an article on Node-secure :)

    +

    Best Regards, +Thomas

    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/blog/JS-X-Ray-3.0.html b/blog/JS-X-Ray-3.0.html new file mode 100644 index 0000000..0b07406 --- /dev/null +++ b/blog/JS-X-Ray-3.0.html @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    JS-X-Ray 3.0

    +

    Hello!

    +

    I have been working every night of the week on a new major version of my open-source JavaScript SAST JS-X-Ray. I've been looking forward to making significant changes to the code for several months now...

    +

    Why ?

    +

    Because I'm still learning every day and the project has grown quite large since 2.0.0. Also when I started the project I lacked a certain rigor in the way I documented the code (and also on some speculations).

    +

    It became necessary to make changes in order to continue to evolve the project.

    +

    So what's new ?

    +

    sec-literal

    +
    npm i sec-literal
    +
    +

    I started to work on a package to analyze ESTree Literals and JavaScript strings. This is a very important part that could be separated in its own package (which simplifies my documentation and testing).

    +

    Some of the features of this package:

    +
      +
    • Detect Hexadecimal, Base64 and Unicode sequences.
    • +
    • Detect patterns (prefix, suffix) on groups of identifiers.
    • +
    • Detect suspicious string and return advanced metrics on it (with char diversity etc).
    • +
    +

    It's a start... I plan to extend the features of the package in the coming months (but also to re-invest some time in documentation and testing).

    +

    new project structure

    +

    image

    +

    Still very far from the perfection I imagine but it's a good start. The code had become messy and it was almost impossible to reason properly.

    +

    The new version is now much easier to maintain and evolve. I will surely continue to improve it for the next major release.

    +

    More documentation, more tests

    +

    I took advantage of the refacto to reinsert a whole set of documentation and unit tests. It also allowed me to fix a number of issues that had not been resolved in version 2.3.

    +

    Obfuscation detection is hard

    +

    I knew it! But I swear to you that it is much more complex than anyone can imagine. I had to rewind my steps several times.

    +

    But if there were no challenges it wouldn't be fun.

    +

    ESM Import evaluation

    +

    Version 3 now throw an unsafe-import for import with javascript code evaluation.

    +
    import 'data:text/javascript;base64,Y29uc29sZS5sb2coJ2hlbGxvIHdvcmxkJyk7Cg==';
    +
    +

    For more info: https://2ality.com/2019/10/eval-via-import.html

    +

    Conclusion

    +

    Nothing incredible for this new version. But the project continues to progress step by step and I hope to be able to add a whole bunch of new detections by the end of the year.

    +

    Best Regards, +Thomas

    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/blog/NodeSecure-CLI-v2.0.0.html b/blog/NodeSecure-CLI-v2.0.0.html new file mode 100644 index 0000000..bd140ab --- /dev/null +++ b/blog/NodeSecure-CLI-v2.0.0.html @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    NodeSecure CLI v2.0.0

    +

    Hello πŸ‘‹,

    +

    I am writing this article with excitement and after several months of work. With the core team we are thrilled to announce that we are publishing a new version of the UI.πŸš€.

    +

    As you are reading these lines I am probably under the sun β˜€οΈ of Tel Aviv for the NodeTLV conference where I will give a talk about NodeSecure and some other tools.

    +

    NodeSecure

    +

    What an incredible journey 😍. Four years ago I was working on my tool alone πŸ˜₯... But now more than a dozen developers are contributing to the project and I can only thank all of you for your precious support πŸ™.

    +

    If you are new, then let me introduce you to the project

    +

    🐀 Getting started with NodeSecure

    +

    NodeSecure is an organization gathering a lot of individual projects that will allow you to improve the security and quality of your projects πŸ’ͺ. With our tools you can visually discover the dependencies you use on a daily basis and learn more about them πŸ“š.

    +

    Our most notable project is: +πŸ”— GitHub: NodeSecure/cli

    +

    How can you use it? It's easy, you just have to install globally the CLI with npm:

    +
    $ npm i @nodesecure/cli -g
    +
    +# Analyze a remote package on the NPM Registry.
    +# Note: also work with a private registry like gitlab or verdaccio
    +$ nsecure auto fastify
    +
    +# Analyze a local manifest (or local project).
    +# -> omit the package name to run it at the cwd.
    +$ cd /myproject
    +$ nsecure auto
    +
    +

    We have many other projects and many opportunities for you to contribute. Feel free to join us on Discord to discuss.

    +

    πŸ‘€ What's changed in v2.0.0 ?

    +

    A lot to be honest πŸ˜†. Our initial idea was simply to improve and complete the interface (We went a bit overboard I guess πŸ˜…).

    +

    One of the things that became problematic was the lack of space in the interface 😨. So we had to completely redesign the UX. I have to thank Medhi Bouchard, who spent dozens of hours designing UI on figma (Without him all this would have been much more difficult to achieve πŸ’ͺ).

    +

    Multiple views

    +

    This new interface offers several distinct views:

    +
      +
    • Home (global informations about the project you asked to analyze).
    • +
    • Network (where we are drawing the dependency tree).
    • +
    • Settings (which allows you to customize your experience with the tool)
    • +
    +
    +

    Note: It is also possible to switch between each view with a keyboard shortcut (which corresponds to the capitalized character).

    +
    +

    Home view

    +

    The home view is a replacement for the old Global stats button. We have been working to bring more attention to the information.

    +

    NodeSecure UI

    +

    To summarize the information we find in this view;

    +
      +
    • Global stats on the project (direct vs indirect, size, downloads)
    • +
    • Licenses and Extensions
    • +
    • Authors
    • +
    • Global warnings (not visible in the screenshot since there is none).
    • +
    • Links to Github and NPM.
    • +
    +

    NodeSecure UI

    +

    We plan to expand this view with even more information and really cool gadgets. We also want to bring more attention and information around the creators and maintainers.

    +

    πŸ”§ Settings view

    +

    This is the new kid in the town. There is not much to customize yet but that will come with time.

    +

    NodeSecure UI

    +

    One of the key ideas of NodeSecure is that each developer and maintainer can customize their experience with the tool.

    +
    +

    Some of our warnings have a lot of false positives that is real, so you will be able to ignore them if you don't find them relevant.

    +
    +

    Eventually the options will allow to make more clear-cut decisions like tagging a maintainer's library (which will be useful during incidents like the one with Faker.js or node-ipc).

    +

    🌎 Network view

    +

    We have slightly improved the network view and updated the colors for something more pleasant.

    +

    In version 1.4.0 of our Vis-network implementation, we have also implemented different theme for parent and child nodes (What you can see in the screenshot below).

    +

    NodeSecure UI

    +
    +

    Note: We have not abandoned the "Dark" theme. Eventually it will be possible to switch from a light to a dark theme in the settings.

    +
    +

    πŸš€ New left pannel

    +

    We wanted to keep the spirit of the old interface where we could retrieve information about a package very quickly. However we want to avoid as much as possible the need to scroll to get the information.

    +

    No more popup πŸ’ƒ. All information is now directly accessible in this new panel.

    +

    NodeSecure UI

    +

    This new design is divided into the following sub-panels:

    +
      +
    • Overview (Package informations, github stats, etc).
    • +
    • Files and size (with bundlephobia).
    • +
    • Scripts and Dependencies.
    • +
    • Threats and issues in JavaScript source.
    • +
    • Vulnerabilities.
    • +
    • Licenses conformance (SPDX).
    • +
    +

    There is also much more information than before. For example, I've been wanting to implement vulnerabilities in the interface for two years and it's now done:

    +

    NodeSecure vulnerabilities

    +
    +

    Note: I remind you that we support multiple strategy for vulnerabilities like Sonatype or Snyk.

    +
    +

    Scripts

    +

    This new version allows you to consult the scripts of a package. Really cool combined with the πŸ“¦ hasScript flag. Most supply chain attack uses a malicious script ... so it became important for us to be able to consult them in the UI.

    +

    NodeSecure scripts

    +

    Threats in source code

    +

    This version implements the latest release of JS-X-Ray which includes new features;

    +
      +
    • Detecting weak crypto algorithm (md5, sha1 ...).
    • +
    • Warnings now have a level of severity (like vulnerabilities).
    • +
    +

    NodeSecure UI

    +

    There is still a lot of work to be done on the interface, especially to better visualize the faulty code. You will notice that the links to access NPM and Unpkg are now always present in the header.

    +

    Licenses conformance

    +

    The information is still the same, but the design is a little more enjoyable. We have also added a small tooltip if you want to know more about SPDX.

    +

    NodeSecure SPDX

    +

    The title and file name are clickable. The first one will open the license page on the SPDX website and the second one the file itself on unpkg.

    +

    Others

    +

    We have slightly improved the short descriptions of the flags and they are now clickable (this will open the wiki directly to the relevant flag).

    +

    NodeSecure UI

    +
    +

    Also in the scripts & dependencies section you will find a show/hide button on the third-party dependencies.

    +

    NodeSecure UI

    +

    Still the same behavior as in the old version, it will hide in the network all the children of the package.

    +

    New documentation/wiki

    +

    We have developed a brand new documentation-ui module that allows us to implement a wiki on any of our projects.

    +

    In this new version you can open the wiki by clicking on the button with the book icon on the right side of the screen. We now also have documentation on the warnings of our static analyzer JS-X-RAY accessible in the SAST Warnings pannel of the wiki.

    +

    NodeSecure wiki

    +

    πŸ‘― Credits

    +

    All this work is possible thanks to the different contributors and contributions they made those last few months.

    + +

    Their simple presence, good mood and spirit were a source of inspiration and motivation for me. Thanks you very much ❀️

    +

    Conclusion

    +

    As always we move forward and evolve. We continue to work hard to improve security in the JavaScript ecosystem and we look forward to being joined by other developers with the same commitment.

    +

    Thanks for reading me and see you soon for another great story!

    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/blog/a-technical-tale-of-nodesecure-chapter1.html b/blog/a-technical-tale-of-nodesecure-chapter1.html new file mode 100644 index 0000000..407e14d --- /dev/null +++ b/blog/a-technical-tale-of-nodesecure-chapter1.html @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    A technical tale of NodeSecure - Chapter 1

    +

    Hello πŸ‘‹

    +

    I have been working on the NodeSecure project for almost three years now 😡. I have personally come a long way... At the beginning I didn't know much about the field in which I started 🐀.

    +

    That's why I thought that writing articles about "some" of the technical difficulties and the tools I used could be valuable πŸš€.

    +

    I will try to make articles that focus on one aspect 🎯. Let's get started πŸ’ƒ.

    +

    πŸ” Fetching the dependency tree

    +

    One of the first challenges I had to solve was how to get the dependency tree and all the information attached to the packages.

    +

    My first instinct was to work with the public API of the npm registry. +This sounds like a very good idea, but you will soon run into a set of problems (cache, private registry etc..).

    +

    What I wanted to do has already been implemented in the package named pacote.

    +
    +

    Note: Arborist did not exist yet. I will come back to this in a future article. The first versions of NodeSecure did not support the analysis of a local project anyway.

    +
    +

    Pacote

    +

    As its README suggests, Pacote is a library that allows you to retrieve various data for a given package. To be more precise:

    +
      +
    • A package manifest (A manifest is similar to a package.json file. However, it has a few pieces of extra metadata, and sometimes lacks metadata that is inessential to package installation.)
    • +
    • A packument (A packument is the top-level package document that lists the set of manifests for available versions for a package.)
    • +
    • A tarball (The archive containing the package itself with the published files)
    • +
    +

    These terms are really important and are explained in the pacote README.

    +
    +

    Note: There is a package with the type definitions @npm/types.

    +
    +

    In the NodeSecure/scanner these methods are used at different stages of the analysis. When we browse the dependency tree for example we use the manifest() method with the range version (or specifier) of the package.

    +
    await pacote.manifest(gitURL ?? packageName, {
    +  ...NPM_TOKEN,
    +  registry: getLocalRegistryURL(),
    +  cache: `${os.homedir()}/.npm`
    +});
    +
    +

    The library allows you to manage a whole set of things quite quickly without too much difficulty πŸ’ͺ.

    +

    Note that in the above code there is a notion of Git URL πŸ‘€.

    +

    πŸ”¬ Dependency resolution

    +

    You are probably used to see SemVer versions or ranges within your package.json. Quite similar to this:

    +
    "dependencies": {
    +    "@nodesecure/flags": "^2.2.0",
    +    "@nodesecure/fs-walk": "^1.0.0",
    +    "@nodesecure/i18n": "^1.2.0",
    +    "@nodesecure/js-x-ray": "^4.1.2",
    +    "@nodesecure/npm-registry-sdk": "^1.3.0"
    +}
    +
    +

    But there are many other ways to install/link a dependency within a package.json 😲:

    + +

    One of the advantages of pacote is that it handles most of these resolutions for you 😎. I discovered all this while working on the subject (because I had never dealt with those types of resolutions).

    +

    If you want to be able to spot them here is a regular expression:

    +
    if (/^([a-zA-Z]+:|git\+|\.\\)/.test(version)) {
    +  // Version with custom resolution
    +}
    +
    +

    This also explains why in NodeSecure we have a "hasCustomResolver" flag allowing quick identification of packages using resolutions to dependencies that diverge from the usual.

    +

    Pacote also exposes a resolve() method:

    +
    import pacote from "pacote";
    +
    +const tarURL = await pacote.resolve("@slimio/is@^1.0.0");
    +
    +

    It resolve a specifier like foo@latest or github:user/project all the way to a tarball url, tarball file, or git repo with commit hash.

    +

    πŸ“¦ Download and extract tarball

    +

    One of the steps is to retrieve the package on the local system to be able to analyze it and retrieve a set of information.

    +
    const spec = ref.flags.includes("isGit") ?
    +  ref.gitUrl : `${name}@${version}`;
    +
    +await pacote.extract(spec, dest, {
    +  ...NPM_TOKEN,
    +  registry: getLocalRegistryURL(),
    +  cache: `${os.homedir()}/.npm`
    +});
    +
    +

    The package will be extracted into a temporary directory generated when the scanner is launched.

    +
    +

    Note: see fs.mkdtemp

    +
    +

    Once the extraction is finished, we will retrieve the information we need:

    +
      +
    • Files, extensions, size on disk etc..
    • +
    • Execute NodeSecure/JS-X-Ray on each JavaScript files.
    • +
    • Fetch licenses and retrieve their SPDX conformance.
    • +
    +

    We will dig deeper into the steps of static code analysis in a future article.

    +

    😈 It can't be that simple

    +

    In all this there are things quite complex to manage:

    +
      +
    • Same packages but with different "range" of versions 🎭.
    • +
    • Ensure the integrity of the links (relations) between packages.
    • +
    +
    +

    The first one is hard because most of the time we are dealing with SemVer range and not with the EXACT version of the package. There is quite a bit of connection here with how npm handles conflict during installation (also how npm algorithms pick the right manifest).

    +

    I think I probably still lack some vision and experience on the subject. The current code is probably quite heavy too.

    +

    Today the cwd API of the Scanner use Arborist. For the from API i would like to avoid having to deal with a packument.

    +
    +

    For the second one it is mainly a problem with the behaviour of the walker that will browse asynchronously the tree. We must therefore avoid that a package already analyzed is taken into account again. The problem with this is that we will be missing relationship links between some packages in the tree.

    +

    The current scanner solves the problem by going through all the dependencies one last time to create the missing link.

    +
    for (const [packageName, descriptor] of payload.dependencies) {
    +  for (const verStr of descriptor.versions) {
    +    const verDescriptor = descriptor[verStr];
    +
    +    const fullName = `${packageName}@${verStr}`;
    +    const usedDeps = exclude.get(fullName) ?? new Set();
    +    if (usedDeps.size === 0) {
    +      continue;
    +    }
    +
    +    const usedBy = Object.create(null);
    +    const deps = [...usedDeps].map((name) => name.split(" "));
    +    for (const [name, version] of deps) {
    +      usedBy[name] = version;
    +    }
    +    Object.assign(verDescriptor.usedBy, usedBy);
    +  }
    +}
    +
    +

    ✨ Conclusion

    +

    That's it for this article where we have explored a little bit the difficulties around going through the dependency tree.

    +

    If you like the concept don't hesitate to like and share.

    +

    πŸ™ Thanks for reading and see you soon for a new article.

    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/blog/a-technical-tale-of-nodesecure-chapter2.html b/blog/a-technical-tale-of-nodesecure-chapter2.html new file mode 100644 index 0000000..20ebf2f --- /dev/null +++ b/blog/a-technical-tale-of-nodesecure-chapter2.html @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    A technical tale of NodeSecure - Chapter 2

    +

    Hello πŸ‘‹,

    +

    I'm back at writing for a new technical article on NodeSecure. This time I want to focus on the SAST JS-X-Ray πŸ”¬.

    +

    I realized very recently that the project on Github was already more than two years old. It's amazing how time flies 😡.

    +

    It's been a long time since I wanted to share my experience and feelings about AST analysis. So let's jump in πŸ˜‰

    +

    πŸ’ƒ How it started

    +

    When I started the NodeSecure project I had almost no experience 🐀 with AST (Abstract Syntax Tree). My first time was on the SlimIO project to generate codes dynamically with the astring package (and I had also looked at the ESTree specification).

    +

    One of my first goals for my tool was to be able to retrieve the dependencies in each JavaScript file contained within an NPM tarball (By this I mean able to retrieve any dependencies imported in CJS or ESM).

    +

    I started the subject a bit naively 😏 and very quickly I set myself a challenge to achieve with my AST analyser:

    +
    function unhex(r) {
    +   return Buffer.from(r, "hex").toString();
    +}
    +
    +const g = Function("return this")();
    +const p = g["pro" + "cess"];
    +
    +const evil = p["mainMod" + "ule"][unhex("72657175697265")];
    +evil(unhex("68747470")).request
    +
    +

    The goal is to be able to output accurate information for the above code. At the time I didn't really know what I was getting into πŸ˜‚ (But I was passionate about it and I remain excited about it today).

    +
    +

    I thank Targos who at the time submitted a lot of code and ideas.

    +
    +

    To date the SAST is able to follow this kind of code without any difficulties 😎... But it wasn't always that simple.

    +

    🐀 Baby steps

    +

    One of the first things I learned was to browse the tree. Even for me today this seems rather obvious, but it wasn't necessarily so at the time πŸ˜….

    +

    I discovered the package estree-walker from Rich Harris which was compatible with the EStree spec. Combined with the meriyah package this allows me to convert a JavaScript source into an ESTree compliant AST.

    +
    import { readFile } from "node:fs/promises";
    +
    +import { walk } from "estree-walker";
    +import * as meriyah from "meriyah";
    +
    +export async function scanFile(location: string) {
    +  const strToAnalyze = await readFile(location, "utf-8");
    +
    +  const { body } = meriyah.parseScript(strToAnalyze, {
    +    next: true, loc: true, raw: true, module: true
    +  });
    +
    +  walk(body, {
    +    enter(node) {
    +      // Skip the root of the AST.
    +      if (Array.isArray(node)) {
    +        return;
    +      }
    +
    +      // DO THE WORK HERE
    +    }
    +  });
    +}
    +
    +

    I also quickly became familiar with the tool ASTExplorer which allows you to analyze the tree and properties for a specific code.

    +

    nodesecure

    +

    As a beginner, you can be quickly scared by the size and complexity of an AST. This tool is super important to better cut out and focus on what is important.

    +
    +

    I also had fun re-implementing the ESTree Specification in TypeScript. It helped me a lot to be more confident and comfortable with different concepts that were unknown to me until then.

    +
    +

    At the beginning of 2021 I also had the opportunity to do a talk for the French JS community (it's one more opportunity to study).

    +

    + β–Ά Watch on YouTube +

    +

    😫 MemberExpression

    +

    JavaScript member expression can be quite complicated to deal with at first. You must be comfortable with recursion and be ready to face a lot of possibilities.

    +

    Here is an example of possible code:

    +
    const myVar = "test";
    +foo.bar["hel" + "lo"].test[myVar]();
    +
    +

    nodesecure

    +

    Computed property, Binary expression, Call expression etc. The order in which the tree is built seemed unintuitive to me at first (and I had a hard time figuring out how to use the object and property properties).

    +

    Since i created my own set of AST utilities including getMemberExpressionIdentifier.

    +

    πŸš€ A new package (with its own API)

    +

    When NodeSecure was a single project the AST analysis was at most a few hundred lines in two or three JavaScript files. All the logic was coded with if and else conditions directly in the walker πŸ™ˆ.

    +

    nodesecure

    +

    To evolve and maintain the project, it became necessary to separate the code and make it a standalone package with its own API πŸ‘€.

    +

    I wrote an article at the time that I invite you to read. It contains some nice little explanations: +β†ͺ Read article

    +

    The thing to remember here is that you probably shouldn't be afraid to start small and grow into something bigger later. Stay pragmatic.

    +

    Easy to write, hard to scale 😭

    +

    It's easy to write a little prototype, but it's really hard to make it scale when you have to handle dozens or hundreds of possibilities. It requires a mastery and understanding of the language that is just crazy 😡. This is really what makes creating a SAST a complicated task.

    +

    For example, do you know how many possibilities there are to require on Node.js? In CJS alone:

    +
      +
    • require
    • +
    • process.mainModule.require
    • +
    • require.main.require
    • +
    +
    +

    I probably forget some 😈 (as a precaution I also trace methods like require.resolve).

    +
    +

    But as far as I'm concerned, it's really what I find exciting 😍. I've learned so much in three years. All this also allowed me to approach the language from an angle that I had never experienced or seen πŸ‘€.

    +

    Probes

    +

    On JS-X-Ray I brought the notion of "probe" into the code which will collect information on one or more specific node. The goal is to separate the AST analysis into lots of smaller pieces that are easier to understand, document and test.

    +
    +

    Very far from perfection 😞. However, it is much better than before and the team is now helping me to improve all this (by adding documentation and tests).

    +
    +

    It was for JS-X-Ray 3.0.0 and at the time i have written the following article (which includes many more details if you are interested). +β†ͺ Read article

    +

    VariableTracer

    +

    This is one of the new killer feature coming to JS-X-Ray soon. A code able to follow the declarations, assignment, destructuration, importating of any identifiers or member expression.

    +

    In my experience being able to keep track of assignments has been one of the most complex tasks (and I've struggled with it).

    +

    This new implementation/API will offer a new spectrum of tools to develop really cool new features.

    +
    const tracer = new VariableTracer().trace("crypto.createHash", {
    +  followConsecutiveAssignment: true
    +});
    +
    +// Use this in the tree walker
    +tracer.walk(node);
    +
    +

    This simple code will allow us, for example, to know each time the method createHash is used. We can use this for information purposes, for example to warn on the usage of a deprecated hash algorithm like md5.

    +

    Here an example:

    +
    const myModule = require("crypto");
    +
    +const myMethodName = "createHash";
    +const callMe = myModule[myMethodName];
    +callMe("md5");
    +
    +
    +

    The goal is not necessarily to track or read malicious code. The idea is to handle enough cases because developers use JavaScript in many ways.

    +
    +

    We can imagine and implement a lot of new scenarios without worries 😍.

    +

    By default we are tracing:

    +
      +
    • eval and Function
    • +
    • require, require.resolve, require.main, require.mainModule.require
    • +
    • Global variables (global, globalThis, root, GLOBAL, window).
    • +
    +

    ✨ Conclusion

    +

    Unfortunately, I could not cover everything as the subject is so vast. One piece of advice I would give to anyone starting out on a similar topic would be to be much more rigorous about documentation and testing. It can be very easy to get lost and not know why we made a choice X or Y.

    +

    Thanks for reading this new technical article. See you soon for a new article (something tells me that it will arrive soon 😏).

    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/blog/annoucing-new-nodesecure-backend.html b/blog/annoucing-new-nodesecure-backend.html new file mode 100644 index 0000000..4ba7d8e --- /dev/null +++ b/blog/annoucing-new-nodesecure-backend.html @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    Announcing new NodeSecure back-end

    +

    Hello πŸ‘‹

    +

    In the last article of the series I announced the future of NodeSecure. Well, we have just finished rebuilding our back-end 😲 (or at least a first version of it).

    +

    So what are the particularities of this new back-end? This is what we will discover in this article πŸ‘€.

    +

    But first let me make an introduction for the newcomers.

    +

    What is NodeSecure ❓

    +

    NodeSecure is an open source organization that aims to create free JavaScript security tools. Our biggest area of expertise is in npm package and code analysis.

    +

    Our most notable projects are:

    + +

    The main project is a CLI that will fetch and deeply analyze the dependency tree of a given npm package (Or a local project with a package.json) and output a .json file that will contain all metadata and flags about each package.

    +

    The CLI is able to open the JSON and draw a Network of all dependencies (UI and emojis flags will help you to identify potential issues and security threats).

    +

    image

    +

    More information on our Governance page.

    +

    New back-end πŸš€

    +

    Moving everything to the NodeSecure github org 🏠

    +

    All packages have been moved to the github organization. You will notice that we have a nice new logo ✨ (created by Tony).

    +

    image

    +

    This should make it simple to implement a new set of tools and collaborate more effectively. The integration of new maintainers should also be greatly simplified.

    +

    Moving to Node.js 16 and ESM

    +

    One of the major choices was to use ESM instead of CJS. Many maintainers like Sindresorhus made the choice to switch to ESM which prevented us from updating some of our packages 😭.

    +

    There are still a lot of things that are not stable, but we are convinced that it is the right choice for the future of our tools πŸ’ͺ.

    +

    Knowing that we still have time before completely finalizing the version 1 we also made the choice to have a limited support to the next LTS of Node.js.

    +

    New segmentation and packages πŸ“¦

    +

    We have segmented the back-end into a multitude of packages. That makes them reusable in other tools.

    +

    image

    +

    It will also greatly improve the quality of documentation and testing πŸ’Ž.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    namedescription
    scanner⚑️ A package API to run a static analysis of your module's dependencies.
    vulnNPM Audit, Snyk and Node.js Security WG vulnerability strategies built for NodeSecure.
    flagsNodeSecure security flags 🚩 (configuration and documentation)
    i18nNodeSecure Internationalization
    npm-registry-sdkNode.js SDK to fetch data from the npm API.
    +

    And there is still a lot more to discover (fs-walk, sec-literal , npm-tarball-license-parser etc).

    +

    Scanner API πŸ”¬

    +

    Even though we now have a dedicated package the API has not changed.

    +
    import * as scanner from "@nodesecure/scanner";
    +import fs from "fs/promises";
    +
    +// CONSTANTS
    +const kPackagesToAnalyze = ["mocha", "cacache", "is-wsl"];
    +
    +const payloads = await Promise.all(
    +  kPackagesToAnalyze.map((name) => scanner.from(name))
    +);
    +
    +const promises = [];
    +for (let i = 0; i < kPackagesToAnalyze.length; i++) {
    +  const data = JSON.stringify(payloads[i], null, 2);
    +
    +  promises.push(fs.writeFile(`${kPackagesToAnalyze[i]}.json`, data));
    +}
    +await Promise.allSettled(promises);
    +
    +

    The PDF & HTML report project has been updated to use this new back-end.

    +

    Team and contributors πŸ‘―

    +

    We are integrating Vincent Dhennin as a new maintainer. His help and contributions have been important and I can only thank him for this investment.

    +

    We are now three (including Tony Gorez and me).

    +

    I would like to thank the other contributors who participated a lot:

    + +

    What's next ?

    +

    To be clear, the objective is to prepare a version 0.9.0 of NodeSecure implementing the new back-end (already in progress).

    +

    This will allow us to continually improve and update the back-end features. It will also now be easier to work on the evolution of the CLI.

    +
    +

    We still don't have a roadmap or vision for the new interface. We will start working on it by October or November I think.

    +
    +
    +

    πŸ™ Thanks for reading and see you soon for an article on the next version of the CLI 😍.

    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/blog/index.html b/blog/index.html index 8a5d831..f90ef23 100644 --- a/blog/index.html +++ b/blog/index.html @@ -209,6 +209,630 @@

    + +
    +
    +
    + + Thomas + +
    + Thomas + + + calendar + Jun 29, 2022 + + + clock + 7 min read + + +
    +
    + + NodeSecure CLI v2.0.0 + +

    TBC

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Thomas + + + calendar + Jun 6, 2022 + + + clock + 7 min read + + +
    +
    + + A technical tale of NodeSecure - Chapter 2 + +

    TBC

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Thomas + + + calendar + Feb 7, 2022 + + + clock + 4 min read + + +
    +
    + + NodeSecure - What's new in 2022 ? + +

    TBC

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Thomas + + + calendar + Dec 7, 2021 + + + clock + 3 min read + + +
    +
    + + NodeSecure v0.9.0 + +

    TBC

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Thomas + + + calendar + Nov 22, 2021 + + + clock + 5 min read + + +
    +
    + + A technical tale of NodeSecure - Chapter 1 + +

    TBC

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Thomas + + + calendar + Sep 11, 2021 + + + clock + 4 min read + + +
    +
    + + Announcing new NodeSecure back-end + +

    TBC

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Thomas + + + calendar + Feb 28, 2021 + + + clock + 2 min read + + +
    +
    + + JS-X-Ray 3.0 + +

    TBC

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Thomas + + + calendar + Feb 21, 2021 + + + clock + 3 min read + + +
    +
    + + NodeSecure v0.8.0 + +

    TBC

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Thomas + + + calendar + Jan 4, 2021 + + + clock + 3 min read + + +
    +
    + + NodeSecure - The future + +

    TBC

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Thomas + + + calendar + Sep 12, 2020 + + + clock + 3 min read + + +
    +
    + + NodeSecure v0.7.0 and v0.8.0@next + +

    TBC

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Thomas + + + calendar + Aug 19, 2020 + + + clock + 6 min read + + +
    +
    + + NodeSecure v0.7.0 and v0.8.0@next + +

    TBC

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Thomas + + + calendar + Jul 30, 2020 + + + clock + 3 min read + + +
    +
    + + NodeSecure PDF Report + +

    TBC

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Thomas + + + calendar + Apr 6, 2020 + + + clock + 6 min read + + +
    +
    + + NodeSecure release v0.6.0 + +

    TBC

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Thomas + + + calendar + Mar 30, 2020 + + + clock + 3 min read + + +
    +
    + + JS-X-Ray 1.0 + +

    TBC

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Thomas + + + calendar + Mar 2, 2020 + + + clock + 5 min read + + +
    +
    + + NodeSecure release v0.5.0 + +

    TBC

    +
    +
    + + +
    +
    +
    + + Thomas + +
    + Thomas + + + calendar + Jan 11, 2020 + + + clock + 4 min read + + +
    +
    + + NodeSecure release v0.4.0 + +

    TBC

    +
    +
    + diff --git a/blog/nodesecure-pdf-report.html b/blog/nodesecure-pdf-report.html new file mode 100644 index 0000000..d04e64c --- /dev/null +++ b/blog/nodesecure-pdf-report.html @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    NodeSecure PDF Report

    +

    Hello,

    +

    I had promised a little while ago to write an article about a SlimIO project that allows the generation of HTML & PDF security reports. It uses the Node-secure project API under the hood to fetch security data of npm packages and git repositories!

    +

    The initial objective was obviously to be able to automate the regular sending of a report on a set of projects (especially for our SlimIO agent packages and git). This provides an overview of the status of several projects on a regular basis.

    +

    The project is completely open-source and works with any npm/github organization. The git support has only been tested with github but it most likely works for gitlab as well.

    +

    What's the report look like?

    +

    + +

    +

    Data

    +

    All the data displayed in the report comes from Node-secure. The analysis is separated into two parts: npm packages and git repositories.

    +

    For each of them, the report will give you an assessment of:

    +
      +
    • The size (external, internal, all).
    • +
    • The dependency list.
    • +
    • The list of dependency with transitive (deep) dependencies.
    • +
    • The list of Node.js core modules used in these projects.
    • +
    • The list of authors (with their gravatar if available).
    • +
    • Charts about extensions, licenses, warnings and flags.
    • +
    +
    +

    At the moment I am not satisfied with the granularity of the information in graphics. I will work in the future to get a more accurate overview...

    +
    +

    Configuration

    +

    You just need to edit the configuration at data/config.json and run the project with the npm start command to go!

    +
    {
    +    "theme": "dark",
    +    "report_title": "SlimIO Security Report",
    +    "report_logo": "https://avatars0.githubusercontent.com/u/29552883?s=200&v=4",
    +    "npm_org_prefix": "@slimio",
    +    "npm_packages": [
    +        "@slimio/addon",
    +        "@slimio/scheduler",
    +        "@slimio/config",
    +        "@slimio/core",
    +        "@slimio/arg-parser",
    +        "@slimio/profiles",
    +        "@slimio/queue",
    +        "@slimio/sqlite-transaction",
    +        "@slimio/alert",
    +        "@slimio/metrics",
    +        "@slimio/units",
    +        "@slimio/ipc",
    +        "@slimio/safe-emitter"
    +    ],
    +    "git_url": "https://github.com/SlimIO",
    +    "git_repositories": [
    +        "Aggregator",
    +        "Alerting",
    +        "Socket",
    +        "Gate",
    +        "ihm"
    +    ],
    +    "charts": [
    +        {
    +            "name": "Extensions",
    +            "display": true,
    +            "interpolation": "d3.interpolateRainbow"
    +        },
    +        {
    +            "name": "Licenses",
    +            "display": true,
    +            "interpolation": "d3.interpolateCool"
    +        },
    +        {
    +            "name": "Warnings",
    +            "display": true,
    +            "type": "horizontalBar",
    +            "interpolation": "d3.interpolateInferno"
    +        },
    +        {
    +            "name": "Flags",
    +            "display": true,
    +            "type": "horizontalBar",
    +            "interpolation": "d3.interpolateSinebow"
    +        }
    +    ]
    +}
    +
    +

    The theme can be either dark or light. Themes are editable/extendable at public/css/themes. (feel free to PR new themes etc).

    +

    The npm_org_prefix is only useful to determine whether or not the package is internal or external.

    +
    +

    Charts only have four properties: name, display, type and interpolation. Interpolation is the function used for the chart background colors (all possible interpolation can be found on the D3 doc).

    +

    The type is by default equal to bar. You can configure it at horizontalBar or pie. (note: not worked much on pie support).

    +

    What's next?

    +

    I'm already pretty happy with the initial result but there's still a lot of work to be done. Some of the improvements I have in mind include:

    +
      +
    • A more complete and flexible configuration.
    • +
    • A better PDF generation (There are a lot of problems between the HTML and PDF versions).
    • +
    • Continue to improve the design of the report (both UI and UX).
    • +
    • Enhance the GIT config (allow local path and complete GIT url).
    • +
    • Add some modules to forward the report to an email or anything else (slack, discord etc.).
    • +
    +

    All contributions are of course welcome!

    +

    Conclusion

    +

    +

    As usual a great pleasure for me to extend the use of Node-secure and to be able to collect a set of statistics on my projects (it's always exciting to discover hidden things.).

    +

    I'm also quite happy that this project can be used by different companies (even if for the moment there is still some work to be done).

    +

    https://github.com/SlimIO/Security

    +

    Thank you for taking the time to read!

    +

    Best Regards, +Thomas

    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/blog/nodesecure-the-future.html b/blog/nodesecure-the-future.html new file mode 100644 index 0000000..f4b81f8 --- /dev/null +++ b/blog/nodesecure-the-future.html @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    NodeSecure - The future

    +

    Hello πŸ‘‹

    +

    Today I'm writing to tell you about the future of NodeSecure πŸ‘€.

    +

    I have not been very active in the last few months because of my job which has taken up a lot of my time. But I'm back 😊.

    +

    Moving forward and updating the project has become much more complicated 😡. So it was time to announce and make major changes.

    +

    What is node-secure (or nsecure) ?

    +

    Node-secure is a CLI that will fetch and deeply analyze the dependency tree of a given npm package (Or a local project with a package.json) and output a .json file that will contains all metadata and flags about each packages.

    +

    The CLI is able to open the JSON and draw a Network of all dependencies (UI and emojis flags will help you to identify potential issues and security threats).

    +

    🏫 Creating an organization

    +

    NodeSecure is not only one tool anymore. The project is now a set of tools and packages that need to be maintained and extended. The project has also gained contributors on its way and many developers pushed me to go even further πŸš€.

    +

    That's why I decided to gather these different projects in the same github organization (and same for npm with @nodesecure). It will also be easier to integrate new collaborators into the project.

    +

    The URL to our new home: https://github.com/NodeSecure

    +

    πŸ“‹ Roadmap

    +

    Well, that's all very nice, but what is the objective in concrete terms? The goal is to release a version 1.0 with the following roadmap:

    +

    Move all the packages in the org

    +
      +
    • js-x-ray
    • +
    • sec-literal
    • +
    • size-satisfies
    • +
    • npm-tarball-license-parser
    • +
    • Migrating SlimIO/Security into the org and rename it @nodesecure/report.
    • +
    • Rewriting SlimIO/npm-registry from zero in the org (with undici as http client).
    • +
    +

    We will update these packages and they will use ESM by default.

    +

    Split Nsecure into three parts

    +

    We will rewrite the Nsecure back-end logic into an independent package named scanner. The CLI and the UI will also be separated in two distinct packages.

    +

    We will focus our efforts initially on the scanner. The objective is above all to simplify maintenance by separating the project into minimal parts that can be more easily documented, evolved and tested.

    +

    This should also reduce the number of dependencies for tools that only want to use the scanner without the CLI and UI.

    +
    +

    ⚠️ We will update the current nsecure package with the new components until the new version arrives.

    +
    +

    New UI

    +

    The NodeSecure web interface will be rewritten from scratch. This new project will use D3.js to generate the network graph.

    +

    It will also be a good opportunity to discuss what we will use for the new interface.

    +

    πŸ‘₯ The team

    +

    I am pleased to announce that I am launching this initiative with Tony Gorez who, as you know, has contributed a lot to the project in recent months.

    +

    Several developers have indicated their intention to actively participate... so the team will grow very quickly.

    +

    This is just the beginning and you are welcome to join us if you want to contribute.

    +
    +

    πŸ’¬ We use Discord to communicate. My Discord tag fraxken#8064.

    +
    +

    Thanks ❀️

    +

    And that's it! A lot of work ahead for us. The new interface will certainly take a few months to be created so don't expect V1 anytime soon.

    +

    However those changes should allow us to release a 0.9 and 0.10 version very quickly in the coming weeks.

    +

    Best Regards, +Thomas

    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/blog/nodesecure-v0.4.0.html b/blog/nodesecure-v0.4.0.html new file mode 100644 index 0000000..da65824 --- /dev/null +++ b/blog/nodesecure-v0.4.0.html @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    NodeSecure release v0.4.0

    +

    Hey !

    +

    Writing my first article on the platform to introduce a new release of a tool. I'm working on for few months with some members of the French JavaScript community.

    +

    https://github.com/ES-Community/nsecure

    +

    First, What is node-secure (or nsecure) ?

    +

    Node-secure is a CLI that will fetch and deeply analyze the dependency tree of a given npm package (Or a local project with a package.json) and output a .json file that will contains all metadata and flags about each packages.

    +

    The CLI is able to open the JSON and draw a Network of all dependencies (UI and emojis flags will help you to identify potential issues and security threats).

    +

    The package is usable as an API too if you want to achieve a security analysis on multiple non-related packages or projects (As we do in my team: https://github.com/SlimIO/Security).

    +

    Release v0.4.0

    +

    So what's new in this release ? This is what we will see below:

    +

    Enhanced license analysis with conformance

    +

    Thanks to Tierney Cyren for developing the conformance package which is allowing the tool to retrieve all spdx informations in the generated .json file.

    +
    {
    +    "uniqueLicenseIds": [
    +        "MIT"
    +    ],
    +    "hasMultipleLicenses": false,
    +    "licenses": [
    +        {
    +            "uniqueLicenseIds": [
    +                "MIT"
    +            ],
    +            "spdxLicenseLinks": [
    +                "https://spdx.org/licenses/MIT.html#licenseText"
    +            ],
    +            "spdx": {
    +                "osi": true,
    +                "fsf": true,
    +                "fsfAndOsi": true,
    +                "includesDeprecated": false
    +            },
    +            "from": "package.json"
    +        }
    +    ]
    +}
    +
    +

    All informations are not in the UI yet... But these are going to be useful for advanced conformance tests on a whole enterprise package/project stack.

    +

    New flags documentation and UI legends

    +

    While this is certainly not perfect yet, we have worked on improving the documentation and legends UI to allow developers to better understand the implication of all flags (and by the same way some road for resolving some of them).

    +

    +

    And emoji in the left "info" menu now show a little description on hover:

    +

    +
    +

    Help is welcome to improve these descriptions!

    +
    +

    New global stats

    +

    This release includes three new global stats:

    +
      +
    • Extensions types count
    • +
    • Licenses count
    • +
    • Maintainers (with Avatar and link when available).
    • +
    +

    The maintainers stat is not finished yet. (and this doesn't include git contributors and npm package publishers.). Right now this is more about packages owners rather than maintainers.

    +

    +

    New flag

    +

    πŸ“š hasMultipleLicenses

    +

    This flag has been created in case we detect different licenses in different files. For example:

    +
      +
    • package.json: MIT detected
    • +
    • LICENSE: ISC detected
    • +
    +

    So in this given case the package will be flagged has been having multiple licenses.

    +

    πŸ‘€ hasMissingOrUnusedDependency

    +

    The package has a missing dependency (in the package.json) or a dependency installed but not required in the code itself.

    +

    +

    However don't jump to conclusion to soon! Some packages use for good reason dev dependencies like @types/node or even use a package installed by a sub dependency (not a cool practice but it happens...).

    +

    New CLI commands

    +

    This version brings a new auto command to the CLI that allow to chain a cwd or from command with the command to open the json with an http server.

    +

    Before with v0.3.0:

    +
    $ nsecure from express
    +$ nsecure http
    +# still possible, but http has been replaced with the `open` command
    +
    +

    After with v0.4.0:

    +
    $ nsecure auto express
    +
    +

    Everything else

    +
      +
    • More tests (65% to 75%+ coverage).
    • +
    • new AST features (require.resolve, process.mainModule ...).
    • +
    • Enhance and cleanup vulnerabilities detection code (and execute hydrate-db automatically).
    • +
    +

    Installation ?

    +
    $ npm install nsecure -g
    +
    +

    Node.js v12.10.0 or higher is required to run the tool. Check the project page for all informations and usage example: https://github.com/ES-Community/nsecure

    +

    What's next ?

    +

    Still a lot of work around making the current implemented features dry (still a lot of edge cases where flags are not getting the situation).

    + +

    Thanks for reading me !

    +

    Best Regards, +Thomas

    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/blog/nodesecure-v0.5.0.html b/blog/nodesecure-v0.5.0.html new file mode 100644 index 0000000..e986430 --- /dev/null +++ b/blog/nodesecure-v0.5.0.html @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    NodeSecure release v0.5.0

    +

    Hello !

    +

    The "new" release v0.5.0 of node-secure has been published few hours ago. This release includes new features and a lot of UI improvement.

    +

    Do not hesitate to check the article on the v0.4.0 (which include a presentation of the project too).

    +

    I have made a little video to show the new UI and some of the new features (click on the image). + + +

    +

    Release v0.5.0

    +

    πŸ’€ isDead flag

    +

    This is a new activity flag. This means that the dependency (the package) has not received any updates from at least one year and has at least one dependency that need to be updated.

    +
    +

    The condition and the period of one year is still experimental.

    +
    +

    In the payload the real name of the flag is hasOutdatedDependency. isDead is the composition of hasOutdatedDependency and the new metadata hasReceivedUpdateInOneYear.

    +

    New metadata in the payload

    +

    The payload has brand-new metadata that has been useful to create the new πŸ’€ flag.

    +
      +
    • dependencyCount (Number of dependencies of the package)
    • +
    • hasReceivedUpdateInOneYear
    • +
    +

    🎭 Emoji on the network graph

    +

    This emoji is not a real flag and is only added in the UI to indicate that the package is already somewhere else in the dependency tree (with different versions).

    +

    +

    New searchbar

    +

    The new search bar is still a prototype (the goal is to build a search bar with real query API like Discord or Github.). The complete search bar will land in v0.6.0 !

    +

    +

    And it is even possible to filter:

    +

    +

    Available filters are:

    +
      +
    • package (default)
    • +
    • version
    • +
    • license
    • +
    • ext
    • +
    • builtin (allow to search for usage of a given Node.js core dependency)
    • +
    • author
    • +
    • flag (the complete flag name)
    • +
    +

    Clickable list items

    +

    Some of the list items in the left menu are now clickable (showed in the presentation video). Depending on the kind of items, the action will be different:

    +
      +
    • Node.js dependencies (Open the Node.js documentation)
    • +
    • Third-party dependencies (Open and move to the dependency in the network graph)
    • +
    • Required Files (Open the file on github.. when possible).
    • +
    +

    Show more / Show less for list items

    +

    Only the first 5 rows are now displayed by default. Before this feature this was a nightmare to navigate when a given package had a LOT of dependencies and required files.

    +

    +

    License popup

    +

    This version allows to click on the License field in the left menu.

    +

    +

    This will open a popup with a table of all licenses used in the project with their conformance information.

    +

    +

    New warnings

    +

    Warnings emoji has been refactored and has a new meaning. Now the payload can contain a list of warnings. These warnings are:

    +
      +
    • unsafe-import (the AST analysis has failed to retrieve the required/imported package/file name).
    • +
    • unsafe-regex (a vulnerable regex can lead to a ReDos attack).
    • +
    • ast-error (when an error occur in the AST analysis of the package).
    • +
    +

    Unsafe-import and unsafe-regex are related to a file with the exact position of the problem. Like licenses these warnings are available in a popup:

    +

    +

    In the JSON it will produce an object like the following one

    +
    "warnings": [{
    +    "kind": "unsafe-regex",
    +    "start": {
    +        "line": 81,
    +        "column": 20
    +    },
    +    "end": {
    +        "line": 81,
    +        "column": 76
    +    },
    +    "file": "old.js"
    +}]
    +
    +

    Improved flags: πŸ‘€ and πŸ”¬

    +

    The AST analysis has been updated to support new patterns:

    +
      +
    • exclude dependency required in a try statement
    • +
    • exclude the package itself from the dependency list (case detected on ajv).
    • +
    • exclude one line CJS require from being detected as "minified" file.
    • +
    +

    Example

    +
    modules.exports = require("./src/file.js");
    +
    +

    Better CLI

    +

    The CLI will now give you a clear state of what is going on under the hood with some new lazy spinners!

    +

    +

    --keep for nsecure auto command

    +

    By default the .json file will be removed when the CLI is closed with the auto command. This can be disabled with the --keep (-k) flag.

    +

    This makes the default behavior of auto more consistent.

    +
    nsecure auto express --keep
    +
    +

    A lot more...

    +

    A lot of refactoring has been done and new tests has been added to the project!

    +

    What's next ?

    +

    The next release will "surely" include:

    +
      +
    • The final search-bar prototype with a complete query API.
    • +
    • A new CLI command to run an AST analysis on a given npm package.
    • +
    • New warnings ? (I want to implement a secrets detection.. not sure "how" yet).
    • +
    • More tests, more stability etc.
    • +
    +

    One of the next major features to implement is the support of package-lock.json (the current analysis may not match the current locked project dependency tree).

    +

    And surely more with the feedbacks of those who use the tool.

    +

    Bonus

    +

    With my team we are working on a customizable open-source Security report that use node-secure under the hood to analyze a given list of packages and git repositories. I will write a complete article when the project will be done (soon).

    +

    The project on github: https://github.com/SlimIO/Security

    +

    Preview of the design report (white theme available too).

    +

    +

    +
    +

    Thanks for reading me and see you for the next release :)

    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/blog/nodesecure-v0.6.0.html b/blog/nodesecure-v0.6.0.html new file mode 100644 index 0000000..f422331 --- /dev/null +++ b/blog/nodesecure-v0.6.0.html @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    NodeSecure release v0.6.0

    +

    Hello world!

    +

    I recently published the release v0.6.0 of Node-secure. If you missed the previous articles:

    + +

    These past weeks I have worked hard on exporting the AST Analysis in is own npm package js-x-ray. I have written an article on this subject recently if you want to know more.

    +

    As usual we will review the new features that version 0.6.0 brings.

    +

    New features

    +
    +

    no more AST analysis and more coverage

    +

    The AST analysis has been moved to the js-x-ray package. This notably allowed to reduce the number of tests to maintain.

    +

    Even more tests have been added to enhance the coverage by ten percent (95%).

    +

    webpack

    +

    All front-end assets is now bundled with webpack. This slightly improves the maintainability of front assets and codes.

    +

    The configuration is surely not perfect, and a lot of space could surely be saved for the package tarball.

    +

    i18n

    +

    This version allows for new languages to be added. The current version support both English and French (which is my native language).

    +

    +

    The tokens cover all the parts of Node-secure (CLI, API and UI). However, the UI is not entirely finished because a lot of text is added through the JavaScript code (I will work on improving the surface for the next version.).

    +

    Feel free to pull-request your own language (or help with existing one). There is a root i18n directory on the Github.

    +

    The lang command has been added to be able to switch between languages.

    +
    $ nsecure lang
    +
    +

    used by + npm home page

    +

    Move between parent and children easily with the left menu (used by / third-party dependencies).

    +

    And a new link to open the npm package page.

    +

    +

    multiple filters searchbar

    +

    The new searchbar allows to search anything on the tree (graph) by multiple criteria (filters). The current available filters are:

    +
      +
    • package (the default filter if there is none).
    • +
    • version (take a semver range as an argument).
    • +
    • flag (list of available flags in the current payload/tree).
    • +
    • license (list of available licenses in the current payload/tree).
    • +
    • author (author name/email/url).
    • +
    • ext (list of available file extensions in the current payload/tree).
    • +
    • builtin (available Node.js core module name).
    • +
    +

    Exemple of query:

    +
    version: >=1.2 | 2, ext: .js, builtin: fs
    +
    +

    The searchbar and some of the filters still require a huge amount of work to work properly (example: there is missing flags). So don't worry we will work to improve it for the next version!

    +

    +

    new verify command

    +
    $ nsecure verify express
    +
    +

    This new command has only been fully implemented as API but not yet full featured for the CLI. I created the command to run complete and advanced analysis on a given npm package.

    +

    Why ?

    +
      +
    • Better precision on the SourceLocation of each required dependency.
    • +
    • More metadata (which we should normally avoid to not make the json too heavy).
    • +
    +

    And maybe more in the future. In CLI the command only print the JSON payload to the terminal.

    +
    interface VerifyPayload {
    +    files: {
    +        list: string[];
    +        extensions: string[];
    +        minified: string[];
    +    };
    +    directorySize: number;
    +    uniqueLicenseIds: string[];
    +    licenses: License[];
    +    ast: {
    +        dependencies: {
    +            [fileName: string]: Dependencies;
    +        };
    +        warnings: Warning[];
    +    };
    +}
    +
    +

    global warnings

    +

    The root of the Node-secure JSON has been completely refactored to allow new metadata to appear in the future.

    +
    {
    +  "id": "7743b4ef",
    +  "rootDepencyName": "express",
    +  "warnings": [],
    +  "dependencies": {}
    +}
    +
    +

    And one of the new root metadata is warnings. At the moment these are just simple warning messages.

    +

    +
    +

    Example with @scarf/scarf which is a package that collect data against your will by default.

    +
    +

    These warnings will obviously evolve over time!

    +

    New warnings

    +

    New experimental warnings were added by the js-x-ray AST analysis:

    +
      +
    • unsafe-stmt (eval or Function("..."))
    • +
    • hexa-value (An hex value has been detected in a Literal)
    • +
    • short-ids (This mean that all identifiers has an average length below 1.5. Only possible if the file contains more than 5 identifiers).
    • +
    • suspicious-string
    • +
    +

    Hexa-value is not a much relevant as we want yet (we will work to remove 80-90% of false positives).

    +
    +

    Please feel free to feedback on these warnings! Making them as precise as possible is essential to achieve the goal of Node-secure.

    +
    +

    Better AST Analysis

    +

    At least 20 to 30 hours of work have been invested on the js-x-ray package. The current release detects major security threats in ALL Node.js code payload of the precedent attacks and issues (some are hosted on badjs.).

    +
    +

    If you think you have a code that is not detected then open an issue (We'll make sure to detect it in the future.).

    +
    +

    At the beginning of the project we laughed about how cool it would be to be able to detect what's going on in the following code:

    +
    function unhex(r) {
    +    return Buffer.from(r, "hex").toString();
    +}
    +
    +const g = eval("this");
    +const p = g["pro" + "cess"];
    +
    +const evil = p["mainMod" + "ule"][unhex("72657175697265")];
    +evil(unhex("68747470")).request
    +
    +

    But it's no longer a dream...

    +
    required:
    +[ 'http' ]
    +
    +warnings:
    +[
    +  'unsafe-stmt -> eval',
    +  'unsafe-assign -> g.process',
    +  'unsafe-assign -> p.mainModule.require',
    +  'hexa-value -> require',
    +  'unsafe-import -> http'
    +]
    +
    +

    (this is a simple log, there a much more available informations like SourceLocation etc)

    +

    New flag βš”οΈ hasBannedFile

    +

    No more inspiration for emoji πŸ˜…

    +

    This new flag uses the API entry of the package ban-sensitive-files. This highlight that the project has at least one sensitive file (or a file with sensitive information in it).

    +

    File like .pem or .key are considered sensitive.

    +

    A lot of fix and improvement

    +
      +
    • Fix UI popup overflow-y and add a max-height.
    • +
    • Fix Node.js fs ENOENT error with the auto-command when the nsecure-result.json file is manually deleted.
    • +
    • Add child_process to the list of dependencies for 🌍 hasExternalCapacity flag.
    • +
    • Remove all @types/ from unused dependencies list.
    • +
    +

    What's next ?

    +

    The next version will mainly be used to stabilize and complete the functionality of this version.

    +
      +
    • Add an history to the searchbar.
    • +
    • Add a new size filter (ex: size: >= 32KB).
    • +
    • Fix all bugs and add translation tokens (searchbar).
    • +
    • Add the CLI output for verify command.
    • +
    • Add more i18n tokens for the UI.
    • +
    • Add the list of "sensitive" files in the JSON (and the left menu in the UI).
    • +
    +

    One of the next major feature will be to walk the dependency tree by using the package-lock.json (only with the cwd command). This feature will bring a lot of new flags to match as possible the usage of lockfile-lint.

    +

    How to use it ?

    +
    $ npm i nsecure -g
    +$ nsecure auto express
    +
    +

    Please take a look at the complete documentation here.

    +

    Conclusion

    +

    Thank to all of those who give me valuable feedback. Thank you for taking the time to read my articles too!

    +

    https://github.com/ES-Community/nsecure

    +

    Think to put a star on the github!

    +

    Best Regards, +Thomas

    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/blog/nodesecure-v0.7.0.html b/blog/nodesecure-v0.7.0.html new file mode 100644 index 0000000..185929b --- /dev/null +++ b/blog/nodesecure-v0.7.0.html @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    NodeSecure v0.7.0 and v0.8.0@next

    +

    Hi,

    +

    I'm writing this article a bit late because version 0.7.0 has already been published 3 months ago. So I'm going to take this opportunity to make the link with the next version already testable with the @next tag.

    +

    For those who don't know the tool yet: https://github.com/ES-Community/nsecure#about

    +

    Version 0.7.0

    +

    Let's discover the new features of version 0.7.0

    +

    verify command CLI output

    +

    The command now work with CLI. Although it will certainly require some iteration and long-term work to improve the stdout.

    +
    +

    As a reminder, this command allows you to have a much more complete report of the result of the AST analysis for a given npm package.

    +
    +

    +

    Popups improvement

    +

    Warnings and licenses popups design has been enhanced. Also the tables in these popups will now by default be filterable when clicking on a column name.

    +

    Warnings popup new features

    +

    The warnings popup has been greatly improved with:

    +
      +
    • New top buttons to allow you to quickly browse the sources on npm and unpkg.
    • +
    • A search input when there a lot of warnings.
    • +
    • Clicking on the name of the file now opens it on unpkg..
    • +
    +

    +

    New way to walk the tree with cwd command

    +

    Before the cwd command was walking the tree in the same way as the from command. It was however impossible to get the tree from the package-lock.json file.

    +

    This release will now read and walk with the local package-lock.json by default (can always be disabled using an option).

    +

    Lot of hotfix and code refactoring

    +

    This version includes a lot of bugfixes and code improvements of all kinds.

    +
    +

    Version @next (v0.8.0)

    +

    This version is still under development but brings important improvements.

    +

    @npmcli/arborist

    +

    In the previous version we used a home-made implementation to browse package-lock.json. But now we use one of the new npm packages: @npmcli/arborist.

    +

    The implementation of this version is much faster and accurate.

    +

    It never end

    +

    We corrected an issue that caused CLI in some cases to never complete the analysis. The process was blocked indefinitely and the counters stopped moving.

    +

    JS-X-Ray 2.0

    +

    😱😱😱! This new version of Node-secure includes the latest version of JS-X-Ray.

    +

    I wrote a whole article recently about this new version that I highly recommend you to read if you haven't already done so: https://dev.to/fraxken/js-x-ray-2-0-1mk0

    +
    +

    What's next ?

    +
      +
    • New :size filter for the searchbar (already implemented on master).
    • +
    • Verify command now work for local project too (already implemented on master).
    • +
    • I'm working on the possibility to draw the network tree with D3.js instead of Vis.js (The idea is to achieve a much more complete experience).
    • +
    • Maybe a new flag to identify native addon.
    • +
    • Continue to iterate on all current features.
    • +
    +
    +

    Don't hesitate to provide us feedbacks which are precious to us to improve or invent functionalities.

    +
    +

    Conclusion

    +

    The project continues to move forward little by little and I'm still very satisfied with the tool.. And I hope that the people who follow and use it are are also satisfied.

    +

    Thanks for reading !

    +

    Best Regards, +Thomas

    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/blog/nodesecure-v0.8.0.html b/blog/nodesecure-v0.8.0.html new file mode 100644 index 0000000..f3fd234 --- /dev/null +++ b/blog/nodesecure-v0.8.0.html @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    NodeSecure v0.8.0

    +

    Hello,

    +

    It's been a while since I've had the opportunity to write an article here (Slightly less free time for open-source at the moment).

    +

    Today I released the version 0.8.0 of Node-secure (not a pre-release this time).

    +

    Let's dive directly into what's new since the last article;

    +

    JS-X-Ray 2.3.0

    +

    A lot of improvement has been made on the static analysis. The number of "encoded-literals" warnings has been reduced by 50%!

    +

    The analysis is also capable to detect Morse code πŸ˜† (not a joke). +

    +

    Verify command on a local project

    +

    It is now possible to run the verify command on a local project. You just have to omit the package name (as for the auto command).

    +
    $ nsecure verify
    +
    +

    Search packages by size

    +

    The search bar now allows you to filter packages by their size. Example with express:

    +

    image

    +

    Under the hood it use a package i created: size-satisfies

    +

    Inspect and show warning code

    +

    This new version add an "inspect" column to the warnings popup. If you make a click it will load and display the code in a little block.

    +

    image

    +
    +

    Thanks to tony for his work on the feature. It took us several weeks to get a result we were happy with.

    +
    +

    Replacing webpack with esbuild

    +

    The UI build with esbuild instead of webpack. Now the build is done in about 200ms and we have removed all dependencies related to webpack.

    +

    New flag for native addons 🐲

    +

    We added the flag hasNativeCode 🐲 if the package contains anything related to a native addon:

    +
      +
    • .c, .cpp, .gyp file extensions
    • +
    • a dependency known to be useful for native addon (node-gyp, node-addon-api, prebuildify... things like this).
    • +
    • "gypfile" property is true in the package.json
    • +
    +

    image

    +

    Summary command

    +

    A new "beta" command we added to show a summary for a given Nsecure JSON payload (as we do in the interface).

    +

    image

    +
    +

    Thanks again to tony who worked on the feature. ⚠️ There are still missing elements that will certainly be added in the next version.

    +
    +

    The github issue is available here.

    +

    Other contributions

    +
      +
    • Global warnings are now also displayed at CLI runtime so that they don't go unnoticed.
    • +
    • Global warnings are also part of the i18n.
    • +
    • Use Github actions instead of Travis.
    • +
    • Add the version of Node-secure in the JSON payload.
    • +
    • Enhance flags description (HTML).
    • +
    +

    Thanks to Tony, Targos, Mickeal and kecsou for all the contributions.

    +

    Release available here.

    +

    What's next ?

    +
      +
    • Adding support for Snyk and Npm audit to detect and fetch CVE.
    • +
    • Taking into account the compatibility of the version when loading the json - PR open by Tony.
    • +
    • Rework part of the UI with web component (i'm already working on a POC).
    • +
    • Use D3.js instead of Vis.js (no POC on how we will do this yet).
    • +
    • Working a lot to enhance JS-X-Ray and the static analysis.
    • +
    +

    If you think you have ideas don't hesitate to come talk and contribute.

    +

    Conclusion

    +

    A version that took a long time to be published but in the end I am still satisfied with the progress made.

    +

    Thanks for reading!

    +

    Best Regards, +Thomas

    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/blog/nodesecure-v0.9.0.html b/blog/nodesecure-v0.9.0.html new file mode 100644 index 0000000..2a90072 --- /dev/null +++ b/blog/nodesecure-v0.9.0.html @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    NodeSecure v0.9.0

    +

    Hello πŸ‘‹,

    +

    After more than ten long months of work we are finally there 😡! Version 0.9.0 has been released on npm πŸš€.

    +

    This is a version that required a lot of effort. Thank you to everyone who contributed and made this possible πŸ™.

    +

    So what are the features of this new release v0.9.0? This is what we will discover in this article πŸ‘€.

    +
    +

    For newcomers you can learn more about NodeSecure here or by reading the series.

    +
    +

    V0.9.0 πŸ’ͺ

    +

    This new version uses the new back-end and especially version 3 of the scanner.

    +

    ESM instead of CJS

    +

    This is a choice we explained in a previous article. This version has been completely rewritten in ESM.

    +

    We also made the choice to abandon Jest which causes too many problems 😟. We now use tape.

    +

    Better CLI

    +

    All commands are now separated by file and the bin/index.js file has been cleaned of all unnecessary code.

    +

    CLI

    +

    We are also working on adding UT for each command (which should avoid regressions and allow better contributions).

    +

    New front-end network management

    +

    This release heavily improves the front-end code with the addition of a package dedicated to vis-network management.

    +

    πŸ”— GitHub: NodeSecure/vis-network

    +

    This should also allow us to migrate more easily to D3.js in 2022 πŸš€.

    +

    Better resolver support

    +

    The new version of the scanner has support for github: and git: spec.

    +

    The scanner is now able to analyze the following dependencies:

    +
    "dependencies": {
    +  "zen-observable": "^0.8.15",
    +  "nanoid": "github:ai/nanoid",
    +  "js-x-ray": "git://github.com/NodeSecure/js-x-ray.git",
    +  "nanodelay": "git+ssh://git@github.com:ai/nanodelay.git",
    +  "nanoevents": "git+https://github.com/ai/nanoevents.git"
    +}
    +
    +

    Better payload structure

    +

    The structure of JSON has been improved to be more consistent (especially on the management of versions by dependency).

    +

    The latest version of the scanner also corrects many inconsistencies in the management of authors and maintainers.

    +
    "author": {
    +  "name": "GENTILHOMME Thomas",
    +  "email": "gentilhomme.thomas@gmail.com"
    +},
    +"publishers": [
    +  {
    +    "name": "fraxken",
    +    "email": "gentilhomme.thomas@gmail.com",
    +    "version": "2.2.0",
    +    "at": "2021-11-11T18:18:06.891Z"
    +  }
    +],
    +"maintainers": [
    +  {
    +    "name": "kawacrepe",
    +    "email": "vincent.dhennin@viacesi.fr"
    +  },
    +  {
    +    "name": "fraxken",
    +    "email": "gentilhomme.thomas@gmail.com"
    +  },
    +  {
    +    "name": "tonygo",
    +    "email": "gorez.tony@gmail.com"
    +  }
    +]
    +
    +

    Brand new vulnerabilities management

    +

    We have already presented it, but now we use our own package that allows to recover vulnerabilities using several strategies (Security WG, NPM Audit etc..).

    +

    πŸ”— GitHub: NodeSecure/vuln

    +

    This is just the beginning and I think it will soon be a fully featured project. Among the new features there is a new standard format dedicated for NodeSecure:

    +
    export interface StandardVulnerability {
    +    id?: string;
    +    origin: Origin;
    +    package: string;
    +    title: string;
    +    description?: string;
    +    url?: string;
    +    severity?: Severity;
    +    cves: string[];
    +    cvssVector?: string;
    +    cvssScore?: number;
    +    vulnerableRanges: string[];
    +    vulnerableVersions: string[];
    +    patchedVersions?: string;
    +    patches?: Patch[];
    +}
    +
    +

    Trojan source detection with JS-X-Ray 4.2.0

    +

    The new backend implements the version 4 of JS-X-Ray. In this latest release we added a warning for Trojan source.

    +

    Documentation and tests

    +

    A lot of effort has been put into adding documentation and unit testing to all of the projects.

    +

    There is still a long way to go to make this even more accessible and you are welcome to help us.

    +

    What's next ?

    +

    We are now working as a group on different topics. We have many ongoing projects/subjects:

    + +

    Conclusion πŸ™

    +

    We should be able to produce more frequent releases until the new UI comes.

    +

    Thanks again to the core contributors of the project without whom we would not have arrived here today!

    +

    See you soon for the release v0.10.0 πŸ’ƒ.

    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/blog/nodesecure-whats-new-in-2022.html b/blog/nodesecure-whats-new-in-2022.html new file mode 100644 index 0000000..d598a23 --- /dev/null +++ b/blog/nodesecure-whats-new-in-2022.html @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + NodeSecure - Blog + + + + + +
    +
    +
    + NodeSecure Logo +

    + NodeSecure Blog +

    +

    + Building a safer Node.js and JavaScript ecosystem +

    +

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    + +
    +
    +
    + +
    +
    +

    NodeSecure - What's new in 2022 ?

    +

    Hello πŸ‘‹,

    +

    Back for a different article than usual. This is the opportunity for me to talk about the NodeSecure project and to tell you about what's new since the beginning of the year πŸ’ƒ.

    +

    The project has grown significantly and we are now several active contributors on the project 😍. This opens up great opportunities for the organization and our tools as a whole.

    +

    Above all, many thanks to all those who participate in this adventure 😘. If you also follow the project and want to contribute and learn, do not hesitate πŸ™Œ.

    +

    Release 1.0.0 πŸš€

    +

    We have moved and renamed the main project. It became necessary to bring the project into the org to allow everyone to discover our other tools.

    +

    Now available on the NodeSecure github under the cli name. The old package has been deprecated and the new release can be downloaded with the name @nodesecure/cli.

    +

    Changing the name was necessary. It all started with one tool but now NodeSecure is a family of tools, contributors πŸ‘― etc.

    +

    This also marks the beginning of the first major release πŸŽ‰.

    +
    $ npm install -g @nodesecure/cli
    +
    +

    πŸ”— GitHub: NodeSecure/cli

    +

    And by the way: this new release include support for Workspaces with the cwd command 😎.

    +

    NodeSecure ci πŸ“Ÿ

    +

    Image description

    +

    A remarkable work from Antoine who has been actively working on the project for a good month πŸ’ͺ. This will bring a whole new dimension to the NodeSecure project and meet to at least some needs long requested by developers.

    +

    He wrote an article to present the tool and explain how to set it up πŸ‘€, I recommend you to read it:

    +

    β†ͺ Read article

    +

    There is still work to do, don't hesitate to come and contribute to this beautiful project which promises a lot for the future.

    +

    πŸ”— GitHub: NodeSecure/ci

    +

    NodeSecure preview

    +

    Working on security accessibility for developers within the JavaScript ecosystem is important to us.

    +

    This is why Tony Gorez has taken it upon himself to design the Preview project which will allow to scan online npm packages. We still have some difficulties to put it online but we are working on it.

    +

    The goal of the project is to highlight some of the benefits and metrics reported by the NodeSecure tools and why not make more developers sensitive to security subjects.

    +

    πŸ”— GitHub: NodeSecure/preview

    +

    NodeSecure authors

    +

    In light of the recent events with Marak Squares it is I think quite important to have some insight on the maintainers of the packages we use.

    +

    β†ͺ Read article

    +

    We must have better tools to warn developers in case of incident like Faker. But also to highlight these maintainers who also need funding.

    +

    This could also allow some developers to realize the dependence they have on certain projects and why not encourage them to contribute to help.

    +

    That's why we are working on a new package with Vincent Dhennin to optimize and fetch additional metadata for package authors.

    +

    πŸ”— GitHub: NodeSecure/authors

    +

    Our goal is to implement these improvements in future releases of Scanner. I'm excited about this because personally I like to get to know the maintainers of the packages I use.

    +

    NodeSecure RC

    +

    We are working on adding a runtime configuration for our tools (especially the CI project).

    +
    import assert from "node:assert/strict";
    +import * as RC from "@nodesecure/rc";
    +
    +const writeOpts: RC.writeOptions = {
    +  payload: { version: "2.0.0" },
    +  partialUpdate: true
    +};
    +
    +const result = (
    +  await RC.write(void 0, writeOpts)
    +).unwrap();
    +assert.strictEqual(result, void 0);
    +
    +

    This should improve the experience for many of our tools where we had a CLI with complex settings and commands or pseudo configuration within the project (like report).

    +
    +

    That's it for this article. We continue to work and listen to your various feedbacks to improve our tools.

    +

    See you soon for another article πŸ˜‰.

    +

    Best Regards, +Thomas

    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/package.json b/package.json index 4948e9f..7ff4a5b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "landing_git", "version": "1.0.0", - "description": "A simple HTML/CSS landing page hosted on [GitHub Pages](https://pages.github.com/). Just open `index.html` and you're all set!", + "description": "NodeSecure Landing Page", "main": "index.js", "type": "module", "scripts": { diff --git a/public/css/blog.css b/public/css/blog.css index 49265a8..e1498da 100644 --- a/public/css/blog.css +++ b/public/css/blog.css @@ -27,17 +27,6 @@ } } -.article { - padding: 20px; - border-radius: 6px; - display: flex; - flex-direction: column; - gap: 1rem; - justify-content: center; - margin-top: 1.5rem; - z-index: 2; - -} .article-link { font-size: 30px; @@ -52,7 +41,7 @@ article { display: flex; flex-direction: column; - justify-content: space-beween; + justify-content: center; align-items: center; width: 100%; } @@ -157,6 +146,18 @@ h1.article-title { content: 'BASH' } +.article-content > table { + border: 1px solid #ccc; + border-collapse: collapse; + width: 100%; +} + +.article-content > table th, +.article-content > table td { + border: 1px solid #ccc; + padding: 10px 16px; +} + .article-content > pre code { display: block; padding: 1rem; @@ -184,8 +185,8 @@ h1.article-title { } .article-card-content { - min-height: 76%; padding: 2rem; + width: 100%; background: linear-gradient(0deg, #3722AFee 80%, #00D1FF44 100%); border-radius: 12px; display: flex; @@ -239,7 +240,6 @@ h1.article-title { font-size: 12px; } - .external-article-link:hover { text-decoration: underline; } diff --git a/src/build-articles.js b/src/build-articles.js index 858a97d..423067f 100644 --- a/src/build-articles.js +++ b/src/build-articles.js @@ -9,7 +9,24 @@ import { JSDOM } from "jsdom"; const inputDir = "./articles"; const outputDir = "./blog"; -const coreContributors = []; + +// processes all markdown files in articles directory +export function convertAllMarkdownArticles(authors) { + if (!fs.existsSync(inputDir)) { + throw new Error(`${inputDir} directory does not exist`); + } + + const files = fs.readdirSync(inputDir).filter((file) => file.endsWith(".md")); + + const articles = files.map((file) => { + const filePath = path.join(inputDir, file); + + return generateBlogPost(filePath, outputDir); + }); + + // Generate index page + generateBlogIndex(articles, authors); +} function generateBlogPost(markdownFile) { const markdownContent = fs.readFileSync(markdownFile, "utf8"); @@ -17,11 +34,29 @@ function generateBlogPost(markdownFile) { // retrieve metadata and dirty html from yaml file const { metadata, content } = parseYamlFile(markdownContent); - // replace dev.to articles links - const contentWithLinks = content.replace( - /{%\s*link\s+(https?:\/\/[^\s%]+)\s*%}/g, - 'β†ͺ Read article' - ); + + // replace external links tags + const contentWithLinks = content + // 1. dev.to articles + .replace( + /{%\s*link\s+(https?:\/\/[^\s%]+)\s*%}/g, + 'β†ͺ Read article' + ) + // 2. youtube videos + .replace( + /{%\s*youtube\s+([a-zA-Z0-9_-]{11})\s*%}/g, + ` + β–Ά Watch on YouTube + ` + // 2. github links + ).replace( + /{%\s*github\s+([a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+)\s*%}/g, + 'πŸ”— GitHub: $1' + ); + const htmlContent = marked.parse(contentWithLinks); // sanitize html @@ -78,14 +113,12 @@ function parseYamlFile(content) { return { metadata: {}, content }; } - // Extraire le frontmatter (entre les deux ---) + // extract frontformatter const frontmatterLines = lines.slice(1, endLineIndex); const markdownLines = lines.slice(endLineIndex + 1); - // const frontmatterText = frontmatterLines.join("\n"); const markdownContent = markdownLines.join("\n").trim(); - // Parser le YAML simple (clΓ©: valeur) const metadata = {}; for (const line of frontmatterLines) { @@ -110,29 +143,11 @@ function parseYamlFile(content) { return { metadata, content: markdownContent }; } -// processes all markdown files in articles directory -export function convertAllMarkdownArticles() { - if (!fs.existsSync(inputDir)) { - throw new Error(`${inputDir} directory does not exist`); - } - - const files = fs.readdirSync(inputDir).filter((file) => file.endsWith(".md")); - - const articles = files.map((file) => { - const filePath = path.join(inputDir, file); - - return generateBlogPost(filePath, outputDir); - }); - - // Generate index page - generateBlogIndex(articles); -} - -function generateBlogIndex(articles) { +function generateBlogIndex(articles, authors) { const articlesList = articles .sort((articleA, articleB) => articleB.date - articleA.date) .map((article) => { - const coreContributor = coreContributors.filter( + const coreContributor = authors.filter( (c) => c.github === article.author )?.[0]; @@ -234,10 +249,7 @@ function getReadTimeEstimation(content) { } const contributors = await response.json(); + const authors = contributors.core; - if (contributors.core) { - coreContributors.push(...contributors.core); - } - - convertAllMarkdownArticles(); + convertAllMarkdownArticles(authors); })(); From c2f843ca5593ff59e7618b6828d5ba7a235e685e Mon Sep 17 00:00:00 2001 From: nasfernane Date: Sun, 21 Sep 2025 19:18:31 +0200 Subject: [PATCH 10/12] feat: update list and code styling --- .gitignore | 1 - articles/announcing-nodesecure-vuln-era.md | 2 +- blog/announcing-nodesecure-vuln-era.html | 2 +- public/css/blog.css | 18 ++++++++++++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 37d13a0..1170717 100644 --- a/.gitignore +++ b/.gitignore @@ -134,4 +134,3 @@ dist .yarn/build-state.yml .yarn/install-state.gz .pnp.* - diff --git a/articles/announcing-nodesecure-vuln-era.md b/articles/announcing-nodesecure-vuln-era.md index 70c4fcf..3b9f136 100644 --- a/articles/announcing-nodesecure-vuln-era.md +++ b/articles/announcing-nodesecure-vuln-era.md @@ -21,7 +21,7 @@ Vulnera is a package that allows you to **programmatically** fetch your Node.js - NPM Audit ([Github Advisory Database](https://github.com/advisories)) - [Sonatype OSS Index](https://ossindex.sonatype.org/) -- deprecated [Node.js Security WG Database](https://github.com/nodejs/security-wg/tree/main/vuln) +- `deprecated` [Node.js Security WG Database](https://github.com/nodejs/security-wg/tree/main/vuln) - Snyk > πŸ“’ Feel free to push new sources (we have [a guide](https://github.com/NodeSecure/vuln/blob/main/docs/adding_new_strategy.md) on how to add/contribute one). diff --git a/blog/announcing-nodesecure-vuln-era.html b/blog/announcing-nodesecure-vuln-era.html index d3e4f4d..8f23a6f 100644 --- a/blog/announcing-nodesecure-vuln-era.html +++ b/blog/announcing-nodesecure-vuln-era.html @@ -64,7 +64,7 @@

    What is Vulnera ? πŸ‘€

    diff --git a/public/css/blog.css b/public/css/blog.css index e1498da..9563502 100644 --- a/public/css/blog.css +++ b/public/css/blog.css @@ -146,6 +146,24 @@ h1.article-title { content: 'BASH' } +.article-content code { + background: #23272f; + color: #ffecb3; + padding: 2px 6px; + border-radius: 4px; + font-size: 0.95em; + font-family: 'JetBrains Mono', monospace; + font-weight: 500; + box-shadow: 0 1px 2px #0002; + white-space: break-spaces; +} + +.article-content li { + list-style: disc inside; + margin-left: 1.5em; + margin-bottom: 0.5em; +} + .article-content > table { border: 1px solid #ccc; border-collapse: collapse; From ecaf383dc8e15b1a604dccd5f2c1a5aa45125443 Mon Sep 17 00:00:00 2001 From: nasfernane Date: Sun, 21 Sep 2025 19:23:04 +0200 Subject: [PATCH 11/12] feat: update code blocks padding --- public/css/blog.css | 2 +- public/css/index.css | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/public/css/blog.css b/public/css/blog.css index 9563502..6e6e17b 100644 --- a/public/css/blog.css +++ b/public/css/blog.css @@ -149,7 +149,7 @@ h1.article-title { .article-content code { background: #23272f; color: #ffecb3; - padding: 2px 6px; + padding: 1px 6px; border-radius: 4px; font-size: 0.95em; font-family: 'JetBrains Mono', monospace; diff --git a/public/css/index.css b/public/css/index.css index ecccf10..a282ba6 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -113,12 +113,12 @@ header { header>.header-background { position: absolute; inset: 0; - z-index: 1 !important; + z-index: 1; background: linear-gradient(120deg, rgba(38, 24, 119, 0.75) 0%, rgba(34, 100, 175, 0.90) 100%), url('../images/header-cover.PNG') center/cover no-repeat; } header>.header-content { - z-index: 2 !important; + z-index: 2; max-width: 800px !important; display: flex; flex-direction: column; From 9c6b42f97502c55722ab3952a600467abf875ad6 Mon Sep 17 00:00:00 2001 From: nasfernane Date: Thu, 25 Sep 2025 20:27:26 +0200 Subject: [PATCH 12/12] fix: remove built blog files --- .gitignore | 4 + blog/JS-X-Ray-1.0.html | 144 --- blog/JS-X-Ray-2.0.html | 215 ----- blog/JS-X-Ray-3.0.html | 100 --- blog/JS-X-Ray-6.0.html | 160 ---- blog/NodeSecure-CLI-v2.0.0.html | 191 ---- ...technical-tale-of-nodesecure-chapter1.html | 185 ---- ...technical-tale-of-nodesecure-chapter2.html | 192 ---- blog/annoucing-new-nodesecure-backend.html | 163 ---- blog/announcing-nodesecure-vuln-era.html | 170 ---- ...u-need-to-know-about-package-managers.html | 252 ------ blog/index.html | 842 ------------------ blog/nodesecure-pdf-report.html | 166 ---- blog/nodesecure-the-future.html | 110 --- blog/nodesecure-v0.4.0.html | 163 ---- blog/nodesecure-v0.5.0.html | 179 ---- blog/nodesecure-v0.6.0.html | 226 ----- blog/nodesecure-v0.7.0.html | 119 --- blog/nodesecure-v0.8.0.html | 128 --- blog/nodesecure-v0.9.0.html | 164 ---- blog/nodesecure-whats-new-in-2022.html | 119 --- blog/securizing-your-github-org.html | 170 ---- public/css/blog.css | 4 +- src/build-articles.js | 4 +- 24 files changed, 8 insertions(+), 4162 deletions(-) delete mode 100644 blog/JS-X-Ray-1.0.html delete mode 100644 blog/JS-X-Ray-2.0.html delete mode 100644 blog/JS-X-Ray-3.0.html delete mode 100644 blog/JS-X-Ray-6.0.html delete mode 100644 blog/NodeSecure-CLI-v2.0.0.html delete mode 100644 blog/a-technical-tale-of-nodesecure-chapter1.html delete mode 100644 blog/a-technical-tale-of-nodesecure-chapter2.html delete mode 100644 blog/annoucing-new-nodesecure-backend.html delete mode 100644 blog/announcing-nodesecure-vuln-era.html delete mode 100644 blog/everything-you-need-to-know-about-package-managers.html delete mode 100644 blog/index.html delete mode 100644 blog/nodesecure-pdf-report.html delete mode 100644 blog/nodesecure-the-future.html delete mode 100644 blog/nodesecure-v0.4.0.html delete mode 100644 blog/nodesecure-v0.5.0.html delete mode 100644 blog/nodesecure-v0.6.0.html delete mode 100644 blog/nodesecure-v0.7.0.html delete mode 100644 blog/nodesecure-v0.8.0.html delete mode 100644 blog/nodesecure-v0.9.0.html delete mode 100644 blog/nodesecure-whats-new-in-2022.html delete mode 100644 blog/securizing-your-github-org.html diff --git a/.gitignore b/.gitignore index 1170717..8c92b77 100644 --- a/.gitignore +++ b/.gitignore @@ -134,3 +134,7 @@ dist .yarn/build-state.yml .yarn/install-state.gz .pnp.* + +# Ignore all files in /blog except base templates +/blog/* +!/blog/*base-template.html* diff --git a/blog/JS-X-Ray-1.0.html b/blog/JS-X-Ray-1.0.html deleted file mode 100644 index bd2f9d5..0000000 --- a/blog/JS-X-Ray-1.0.html +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    JS-X-Ray 1.0

    -

    Hi,

    -

    While I was working on the next release (0.6.0) of Node-Secure I thought that the AST analysis was getting bigger and bigger (and much more complicated too).

    -

    That's why I decided to separate all the analysis from the Node-secure project to allow easier maintenance and future enhancement. This also allows other projects to use my package if they need to!

    -

    https://github.com/fraxken/js-x-ray

    -

    This is how JS-X-RAY was born. I have chosen the word x-ray because in games this is often a feature that allow to see through the walls, I like to imagine my analysis as being able to see through the most common techniques (obfuscation, etc.).

    -

    The goal

    -

    One of the primary goals of this package is to be able to find any required Node.js dependencies in a given code. If the analysis is not able to follow a require statement then an unsafe-import warning will be throw.

    -

    The more time goes and the more I think to make my code generic to also detect patterns specific to the front.

    -

    So I think the code will evolve in this direction :)

    -

    Example

    -
    -

    Purescript

    -

    Take the purescript-installer incident and specially the corrupted rate-map code.

    -
    -

    One of the objectives of node-secure is to be able to quickly identify code with warnings and give a bunch of very useful informations to the developer.

    -
    -

    In this case node-secure was able to detect the following dependencies: -append-type, fs, dl-tar.

    -
    const px = require.resolve(
    -Buffer.from([100, 108, 45, 116, 97, 114]).toString()
    -);
    -
    -

    My AST analysis has detected a Buffer.from and as converted the value to dl-tar itself. In this case an unsafe-import will be throw with the file name and the Source Location.

    -
    -

    Event-stream

    -

    Take the Payload A in the event-stream incident.

    -

    So what's going on here?

    -
      -
      1. -
      2. assign of process and require into new variables.
      3. -
      -
    • -
      1. -
      2. hexa value.
      3. -
      -
    • -
      1. -
      2. code obfuscated (all identifiers have a length of 1).
      3. -
      -
    • -
    -

    I'm working on a bench of experimental analysis and warnings to be able to detect similar cases to event-stream incident.

    -
    [
    -  {
    -    "kind": "unsafe-assign",
    -    "start": { "line": 3, "column": 12 },
    -    "end": { "line": 3, "column": 23 },
    -    "value": "require"      
    -  },
    -  {
    -    "kind": "unsafe-assign",
    -    "start": { "line": 4, "column": 12 },
    -    "end": { "line": 4, "column": 23 },
    -    "value": "process"
    -  },
    -  {
    -    "kind": "hexa-value",
    -    "start": { "line": 9, "column": 20 },
    -    "end": { "line": 9, "column": 44 },
    -    "value": "./test/data"
    -  },
    -  {
    -    "kind": "short-ids",
    -    "start": { "line": 0, "column": 0 },
    -    "end": { "line": 0,"column": 0 },
    -    "value": 1
    -  }
    -]
    -
    -

    However, A lot of packages may be detected as false positives (even if it's always better than nothing πŸ˜…). It will surely take time to discover and improve these parameters.

    -

    Conclusion

    -

    Still a LOT of work has to be done to be able to achieve an accurate analysis. Right now the analysis is capable of gathering a whole of very useful information (unsafe-regex, unused and missing dependencies etc.).

    -

    I am always very excited to experience new warnings because they can detect patterns and errors that are often (un)common. Step by step they also lead me to a better understanding of the most dangerous patterns of the ecosystem.

    -
    -

    For example 90%+ of the false positive are always generated because of files that was not mean to be published on the npm registry (tests, coverage files, etc.).

    -
    -

    Thanks for reading!

    -

    Best Regards, -Thomas

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/JS-X-Ray-2.0.html b/blog/JS-X-Ray-2.0.html deleted file mode 100644 index f935d33..0000000 --- a/blog/JS-X-Ray-2.0.html +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    NodeSecure v0.7.0 and v0.8.0@next

    -

    Hello,

    -

    It's been a few weeks now that I've been working on a new major release for JS-X-Ray. This new version brings a lot of important changes including:

    -
      -
    • New warnings names (I've taken the time to think of consistent names).
    • -
    • New features to detect an obfuscated code (Still experimental though).
    • -
    • New format for the SourceLocation (an array instead of the ESTree SourceLocation Object).
    • -
    • Complete documentation for warnings (With explanations on technical implementation when necessary).
    • -
    • Improvement of the code as a whole (it is much more maintainable).
    • -
    • Improvement of unit tests.
    • -
    -

    The project is completely open-source and accessible on github: https://github.com/fraxken/js-x-ray (Remember to star πŸ’–).

    -

    What is JS-X-Ray?

    -

    I'll make a summary for the latecomers. (Also feel free to read the other articles in the series to better understand.)

    -

    JS-X-Ray is a free and open-source JavaScript/Node.js SAST scanner. It was mainly built to meet the needs of the Node-secure project but gradually became independent.

    -

    The project as a whole analyzes JavaScript SourceCode on format AST (Abstract Syntax Tree) and provides a set of information on it including "security" warnings.

    -

    The goal is to quickly identify dangerous patterns (in the given code) for Developers and Security researchers.

    -

    For who ?

    -

    As previously mentioned, the project is currently being used as a dependency of other security projects (Like Node-secure).

    -

    This tool is not magic and still requires basic security knowledge to tell the difference between a real problem and a false positive..

    -

    The target of the project is mainly security researchers as well as developers interested in the development of security tools.

    -

    An example?

    -

    Let's take a look at one of the previous incidents in the ecosystem (npm). For example the event-stream incident where malicious codes are still accessible here on badjs.

    -

    We're going to run an analysis on the Payload C.

    -
    const { runASTAnalysis } = require("js-x-ray");
    -const { readFileSync } = require("fs");
    -const { inspect } = require("util");
    -
    -const log = (str) => console.log(inspect(str, { compact: false, colors: true }));
    -const code = readFileSync("./event-stream-payloadc.js", "utf-8");
    -log(runASTAnalysis(code));
    -
    -
    {
    -  dependencies: ASTDeps {
    -    dependencies: [Object: null prototype] {
    -      http: [Object],
    -      crypto: [Object],
    -      'bitcore-wallet-client/lib/credentials.js': [Object]
    -    }
    -  },
    -  warnings: [
    -    {
    -      kind: 'encoded-literal',
    -      value: '636f7061796170692e686f7374',
    -      location: [Array]
    -    },
    -    {
    -      kind: 'encoded-literal',
    -      value: '3131312e39302e3135312e313334',
    -      location: [Array]
    -    },
    -    {
    -      kind: 'short-identifiers',
    -      location: [Array],
    -      value: 1
    -    }
    -  ],
    -  idsLengthAvg: 1,
    -  stringScore: 0,
    -  isOneLineRequire: false
    -}
    -
    -

    That's what JS-X-Ray return. We find the dependencies that were required within the script and some warnings:

    -
      -
    • Two encoded literals.
    • -
    • A warning telling us that identifiers in the code are too short (below an average of 1.5).
    • -
    -

    What might give us a clue here is the nature of the warnings and the used dependencies...Of course tools such as Node-secure will give you a much better view when the need is to analyse a complete project.

    -

    -

    Warnings

    -

    All warnings are explained on the README of the github. Advanced documentation on how they work and how they are implemented can be found here.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    namedescription
    parsing-errorAn error occured when parsing the JavaScript code with meriyah. It mean that the conversion from string to AST as failed. If you encounter such an error, please open an issue.
    unsafe-importUnable to follow an import (require, require.resolve) statement/expr.
    unsafe-regexA RegEx as been detected as unsafe and may be used for a ReDoS Attack. Under the hood we use the package safe-regex.
    unsafe-stmtUsage of dangerous statement like eval() or Function("").
    unsafe-assignAssignment of a protected global like process or require.
    encoded-literalAn encoded literal has been detected (it can be an hexa value, unicode sequence, base64 string etc)
    short-identifiersThis mean that all identifiers has an average length below 1.5. Only possible if the file contains more than 5 identifiers.
    suspicious-literalThis mean that the sum of suspicious score of all Literals is bigger than 3.
    obfuscated-code (experimental)There's a very high probability that the code is obfuscated...
    -

    unsafe-import

    -

    What do we mean when it is impossible to follow an expression or statement? Let's take the following example:

    -
    function boo() {
    -  // something is going on here!
    -}
    -
    -require(boo());
    -
    -

    Here the analysis is not able to follow because it would be too painful and time consuming to know what the function really returns.

    -

    unsafe-assign

    -

    A fairly common pattern among hackers is to assign global variables to new variables to hide the use of a require or eval. JS-X-Ray is able to trace the use of these variables and will consider this pattern as dangerous.

    -

    Example:

    -
    const g = global.process;
    -const r = g.mainModule;
    -const c = r.require;
    -c("http");
    -r.require("fs");
    -
    -

    obfuscated-code

    -

    He's the new kid. However the results are not yet perfect and a lot of work will be necessary in the coming months to allow the detection of more obfuscated codes.

    - -

    On the future

    -

    I wish I could iterate over the entire npm registry. I think that this project could provide us valuable insight on packages and maybe even prevent a lot of malicious code to reach npm users.

    -

    This is already what I do personally with Node-secure which allows me to secure and improve the SlimIO solution.

    -

    Beyond the security aspect, this project allows to detect and understand the use of a set of bad patterns/practices. We could also eventually guide and prevent these practices to improve the ecosystem as a whole.

    -

    At the moment I'm investing my free time to work on this project... But I would obviously like to invest myself professionally in it!

    -

    Conclusion

    -

    There's still a lot of work to be done. One of the blocking points I'm encountering at the moment is the analysis of common patterns in identifiers (which can be diverse and varied depending on the generation method).

    -

    The current version is not yet implemented on Node-secure and it might take a few weeks (I'm a bit too busy at the moment).

    -

    Hope you enjoy this article to keep you up to date with the developments and progress I have made!

    -

    Thank you for reading this series and see you soon for an article on Node-secure :)

    -

    Best Regards, -Thomas

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/JS-X-Ray-3.0.html b/blog/JS-X-Ray-3.0.html deleted file mode 100644 index 0b07406..0000000 --- a/blog/JS-X-Ray-3.0.html +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    JS-X-Ray 3.0

    -

    Hello!

    -

    I have been working every night of the week on a new major version of my open-source JavaScript SAST JS-X-Ray. I've been looking forward to making significant changes to the code for several months now...

    -

    Why ?

    -

    Because I'm still learning every day and the project has grown quite large since 2.0.0. Also when I started the project I lacked a certain rigor in the way I documented the code (and also on some speculations).

    -

    It became necessary to make changes in order to continue to evolve the project.

    -

    So what's new ?

    -

    sec-literal

    -
    npm i sec-literal
    -
    -

    I started to work on a package to analyze ESTree Literals and JavaScript strings. This is a very important part that could be separated in its own package (which simplifies my documentation and testing).

    -

    Some of the features of this package:

    -
      -
    • Detect Hexadecimal, Base64 and Unicode sequences.
    • -
    • Detect patterns (prefix, suffix) on groups of identifiers.
    • -
    • Detect suspicious string and return advanced metrics on it (with char diversity etc).
    • -
    -

    It's a start... I plan to extend the features of the package in the coming months (but also to re-invest some time in documentation and testing).

    -

    new project structure

    -

    image

    -

    Still very far from the perfection I imagine but it's a good start. The code had become messy and it was almost impossible to reason properly.

    -

    The new version is now much easier to maintain and evolve. I will surely continue to improve it for the next major release.

    -

    More documentation, more tests

    -

    I took advantage of the refacto to reinsert a whole set of documentation and unit tests. It also allowed me to fix a number of issues that had not been resolved in version 2.3.

    -

    Obfuscation detection is hard

    -

    I knew it! But I swear to you that it is much more complex than anyone can imagine. I had to rewind my steps several times.

    -

    But if there were no challenges it wouldn't be fun.

    -

    ESM Import evaluation

    -

    Version 3 now throw an unsafe-import for import with javascript code evaluation.

    -
    import 'data:text/javascript;base64,Y29uc29sZS5sb2coJ2hlbGxvIHdvcmxkJyk7Cg==';
    -
    -

    For more info: https://2ality.com/2019/10/eval-via-import.html

    -

    Conclusion

    -

    Nothing incredible for this new version. But the project continues to progress step by step and I hope to be able to add a whole bunch of new detections by the end of the year.

    -

    Best Regards, -Thomas

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/JS-X-Ray-6.0.html b/blog/JS-X-Ray-6.0.html deleted file mode 100644 index 6aacc71..0000000 --- a/blog/JS-X-Ray-6.0.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    JS-X-Ray 6.0

    -

    Hello πŸ‘‹

    -

    It's been a while since the last article on JS-X-Ray 😲!

    -

    β†ͺ Read article

    -

    In this article I will present you the latest major version πŸ‘€. I didn't do an article on version 4 and 5 because they didn't introduce new features (only breaking changes on the API).

    -

    πŸ“’ What is JS-X-Ray ?

    -

    If you are new in town, JS-X-Ray is an open source JavaScript SAST (Static Application Security Testing). The tool analyzes your JavaScript sources for patterns that may affect the security and quality of your project 😎.

    -

    Among the notable features:

    -
      -
    • Retrieving dependencies (CJS & ESM support) and detecting suspicious import/require.
    • -
    • Detecting unsafe RegEx.
    • -
    • Detecting obfuscated source (and provide hints on the tool used).
    • -
    -

    As well as a lot of other detections.

    -

    Major release 4 and 5

    -

    These versions introduced changes on warnings (and we improved how we manage them in the codebase). We added new descriptors for each of them:

    -
      -
    • i18n (for translation in CI or CLI).
    • -
    • experimental
    • -
    • severity (Information, Warning, Critical)
    • -
    -

    Those information are visible in the NodeSecure CLI interface:

    -

    NodeSecure

    -

    Major release 6

    -

    🐬 Ok, let's dive into this major release to discover the surprises πŸŽ‰ it has in store for us.

    -

    πŸš€ Introducing VariableTracer

    -

    Almost a year of work on this new mechanism / class that brings a whole new dimension to JS-X-Ray.

    -
    const tracer = new VariableTracer()
    -  .enableDefaultTracing()
    -  .trace("crypto.createHash", {
    -    followConsecutiveAssignment: true, moduleName: "crypto"
    -  });
    -
    -tracer.walk(node);
    -
    -

    This class is able to follow all declarations, assignments and patterns (and those even through very obscure patterns).

    -
    const aA = Function.prototype.call;
    -const bB = require;
    -
    -const crypto = aA.call(bB, bB, "crypto");
    -const cr = crypto.createHash;
    -cr("md5"); // weak-crypto warning is throw here
    -
    -

    This allows us to implement Probes in a much simpler way (which makes maintenance and testing much easier).

    -

    Here an example with the isWeakCrypto probe:

    -
    function validateNode(node, { tracer }) {
    -  const id = getCallExpressionIdentifier(node);
    -  if (id === null || !tracer.importedModules.has("crypto")) {
    -    return [false];
    -  }
    -
    -  const data = tracer.getDataFromIdentifier(id);
    -
    -  return [
    -    data !== null &&
    -    data.identifierOrMemberExpr === "crypto.createHash"
    -  ];
    -}
    -
    -

    By default the Tracer follows all ways of requiring dependencies with CJS and also usage of eval or Function.

    -

    🚧 Removing unsafe-assign warning

    -

    This warning was required at the beginning of the project because it was difficult for me to correctly identify some malicious patterns.

    -

    NodeSecure

    -

    However, with the introduction of the new Tracer, which is very complete and precise, this warning no longer makes sense has it only generates unnecessary noise and false positives.

    -

    πŸ“œ Better ESM source parsing

    -

    We previously had a lot of parsing-error warnings because the NodeSecure scanner failed to detect if the file was using either CJS or ESM.

    -

    That new version will automatically retry with ESM enabled if it fails with CJS.

    -

    πŸ“‰ Reducing false positives

    -

    To continue the momentum of the previous sections. This version drops a lot of warnings and significantly improves others.

    -
      -
    • Reducing false positives for encoded-literal warning by introducing new way of detecting safe values.
    • -
    • Improve short-identifiers by also storing ClassDeclaration, MethodDefinition and Function parameters.
    • -
    -

    We are also introducing a new suspicious-file warning when a file contain more than 10 encoded-literal warnings to avoid having file with hundreds or thousands of warnings.

    -

    Of the 500 most popular NPM packages, we previously had 24k warnings with version 5. The latest version brings that number down to approximatively 5k warnings.

    -

    πŸ”¬ Improving coverage

    -

    A lot of work has been done to add unit tests on all the probes of the project. We are near 100% of coverage πŸ’ͺ.

    -

    NodeSecure

    -

    Thanks to the amazing work of our contributors:

    - -

    πŸ‘€ What's next ?

    -

    Here what I'm working for the next major release:

    -
      -
    • Adding support of TypeScript sources (probably by allowing a customization of the parser).
    • -
    • A new API that allows to dynamically extend the SAST with new custom probes (and custom warnings).
    • -
    • Introducing new built-in detections and warnings (unsafe URL etc).
    • -
    -

    I will continue to work to reduce the number of false positives and keep improving obfuscated codes detection.

    -
    -

    Please think to drop a star on github ❀️!

    -

    That's it for today! Thanks for reading me πŸ˜‰

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/NodeSecure-CLI-v2.0.0.html b/blog/NodeSecure-CLI-v2.0.0.html deleted file mode 100644 index bd140ab..0000000 --- a/blog/NodeSecure-CLI-v2.0.0.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    NodeSecure CLI v2.0.0

    -

    Hello πŸ‘‹,

    -

    I am writing this article with excitement and after several months of work. With the core team we are thrilled to announce that we are publishing a new version of the UI.πŸš€.

    -

    As you are reading these lines I am probably under the sun β˜€οΈ of Tel Aviv for the NodeTLV conference where I will give a talk about NodeSecure and some other tools.

    -

    NodeSecure

    -

    What an incredible journey 😍. Four years ago I was working on my tool alone πŸ˜₯... But now more than a dozen developers are contributing to the project and I can only thank all of you for your precious support πŸ™.

    -

    If you are new, then let me introduce you to the project

    -

    🐀 Getting started with NodeSecure

    -

    NodeSecure is an organization gathering a lot of individual projects that will allow you to improve the security and quality of your projects πŸ’ͺ. With our tools you can visually discover the dependencies you use on a daily basis and learn more about them πŸ“š.

    -

    Our most notable project is: -πŸ”— GitHub: NodeSecure/cli

    -

    How can you use it? It's easy, you just have to install globally the CLI with npm:

    -
    $ npm i @nodesecure/cli -g
    -
    -# Analyze a remote package on the NPM Registry.
    -# Note: also work with a private registry like gitlab or verdaccio
    -$ nsecure auto fastify
    -
    -# Analyze a local manifest (or local project).
    -# -> omit the package name to run it at the cwd.
    -$ cd /myproject
    -$ nsecure auto
    -
    -

    We have many other projects and many opportunities for you to contribute. Feel free to join us on Discord to discuss.

    -

    πŸ‘€ What's changed in v2.0.0 ?

    -

    A lot to be honest πŸ˜†. Our initial idea was simply to improve and complete the interface (We went a bit overboard I guess πŸ˜…).

    -

    One of the things that became problematic was the lack of space in the interface 😨. So we had to completely redesign the UX. I have to thank Medhi Bouchard, who spent dozens of hours designing UI on figma (Without him all this would have been much more difficult to achieve πŸ’ͺ).

    -

    Multiple views

    -

    This new interface offers several distinct views:

    -
      -
    • Home (global informations about the project you asked to analyze).
    • -
    • Network (where we are drawing the dependency tree).
    • -
    • Settings (which allows you to customize your experience with the tool)
    • -
    -
    -

    Note: It is also possible to switch between each view with a keyboard shortcut (which corresponds to the capitalized character).

    -
    -

    Home view

    -

    The home view is a replacement for the old Global stats button. We have been working to bring more attention to the information.

    -

    NodeSecure UI

    -

    To summarize the information we find in this view;

    -
      -
    • Global stats on the project (direct vs indirect, size, downloads)
    • -
    • Licenses and Extensions
    • -
    • Authors
    • -
    • Global warnings (not visible in the screenshot since there is none).
    • -
    • Links to Github and NPM.
    • -
    -

    NodeSecure UI

    -

    We plan to expand this view with even more information and really cool gadgets. We also want to bring more attention and information around the creators and maintainers.

    -

    πŸ”§ Settings view

    -

    This is the new kid in the town. There is not much to customize yet but that will come with time.

    -

    NodeSecure UI

    -

    One of the key ideas of NodeSecure is that each developer and maintainer can customize their experience with the tool.

    -
    -

    Some of our warnings have a lot of false positives that is real, so you will be able to ignore them if you don't find them relevant.

    -
    -

    Eventually the options will allow to make more clear-cut decisions like tagging a maintainer's library (which will be useful during incidents like the one with Faker.js or node-ipc).

    -

    🌎 Network view

    -

    We have slightly improved the network view and updated the colors for something more pleasant.

    -

    In version 1.4.0 of our Vis-network implementation, we have also implemented different theme for parent and child nodes (What you can see in the screenshot below).

    -

    NodeSecure UI

    -
    -

    Note: We have not abandoned the "Dark" theme. Eventually it will be possible to switch from a light to a dark theme in the settings.

    -
    -

    πŸš€ New left pannel

    -

    We wanted to keep the spirit of the old interface where we could retrieve information about a package very quickly. However we want to avoid as much as possible the need to scroll to get the information.

    -

    No more popup πŸ’ƒ. All information is now directly accessible in this new panel.

    -

    NodeSecure UI

    -

    This new design is divided into the following sub-panels:

    -
      -
    • Overview (Package informations, github stats, etc).
    • -
    • Files and size (with bundlephobia).
    • -
    • Scripts and Dependencies.
    • -
    • Threats and issues in JavaScript source.
    • -
    • Vulnerabilities.
    • -
    • Licenses conformance (SPDX).
    • -
    -

    There is also much more information than before. For example, I've been wanting to implement vulnerabilities in the interface for two years and it's now done:

    -

    NodeSecure vulnerabilities

    -
    -

    Note: I remind you that we support multiple strategy for vulnerabilities like Sonatype or Snyk.

    -
    -

    Scripts

    -

    This new version allows you to consult the scripts of a package. Really cool combined with the πŸ“¦ hasScript flag. Most supply chain attack uses a malicious script ... so it became important for us to be able to consult them in the UI.

    -

    NodeSecure scripts

    -

    Threats in source code

    -

    This version implements the latest release of JS-X-Ray which includes new features;

    -
      -
    • Detecting weak crypto algorithm (md5, sha1 ...).
    • -
    • Warnings now have a level of severity (like vulnerabilities).
    • -
    -

    NodeSecure UI

    -

    There is still a lot of work to be done on the interface, especially to better visualize the faulty code. You will notice that the links to access NPM and Unpkg are now always present in the header.

    -

    Licenses conformance

    -

    The information is still the same, but the design is a little more enjoyable. We have also added a small tooltip if you want to know more about SPDX.

    -

    NodeSecure SPDX

    -

    The title and file name are clickable. The first one will open the license page on the SPDX website and the second one the file itself on unpkg.

    -

    Others

    -

    We have slightly improved the short descriptions of the flags and they are now clickable (this will open the wiki directly to the relevant flag).

    -

    NodeSecure UI

    -
    -

    Also in the scripts & dependencies section you will find a show/hide button on the third-party dependencies.

    -

    NodeSecure UI

    -

    Still the same behavior as in the old version, it will hide in the network all the children of the package.

    -

    New documentation/wiki

    -

    We have developed a brand new documentation-ui module that allows us to implement a wiki on any of our projects.

    -

    In this new version you can open the wiki by clicking on the button with the book icon on the right side of the screen. We now also have documentation on the warnings of our static analyzer JS-X-RAY accessible in the SAST Warnings pannel of the wiki.

    -

    NodeSecure wiki

    -

    πŸ‘― Credits

    -

    All this work is possible thanks to the different contributors and contributions they made those last few months.

    - -

    Their simple presence, good mood and spirit were a source of inspiration and motivation for me. Thanks you very much ❀️

    -

    Conclusion

    -

    As always we move forward and evolve. We continue to work hard to improve security in the JavaScript ecosystem and we look forward to being joined by other developers with the same commitment.

    -

    Thanks for reading me and see you soon for another great story!

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/a-technical-tale-of-nodesecure-chapter1.html b/blog/a-technical-tale-of-nodesecure-chapter1.html deleted file mode 100644 index 407e14d..0000000 --- a/blog/a-technical-tale-of-nodesecure-chapter1.html +++ /dev/null @@ -1,185 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    A technical tale of NodeSecure - Chapter 1

    -

    Hello πŸ‘‹

    -

    I have been working on the NodeSecure project for almost three years now 😡. I have personally come a long way... At the beginning I didn't know much about the field in which I started 🐀.

    -

    That's why I thought that writing articles about "some" of the technical difficulties and the tools I used could be valuable πŸš€.

    -

    I will try to make articles that focus on one aspect 🎯. Let's get started πŸ’ƒ.

    -

    πŸ” Fetching the dependency tree

    -

    One of the first challenges I had to solve was how to get the dependency tree and all the information attached to the packages.

    -

    My first instinct was to work with the public API of the npm registry. -This sounds like a very good idea, but you will soon run into a set of problems (cache, private registry etc..).

    -

    What I wanted to do has already been implemented in the package named pacote.

    -
    -

    Note: Arborist did not exist yet. I will come back to this in a future article. The first versions of NodeSecure did not support the analysis of a local project anyway.

    -
    -

    Pacote

    -

    As its README suggests, Pacote is a library that allows you to retrieve various data for a given package. To be more precise:

    -
      -
    • A package manifest (A manifest is similar to a package.json file. However, it has a few pieces of extra metadata, and sometimes lacks metadata that is inessential to package installation.)
    • -
    • A packument (A packument is the top-level package document that lists the set of manifests for available versions for a package.)
    • -
    • A tarball (The archive containing the package itself with the published files)
    • -
    -

    These terms are really important and are explained in the pacote README.

    -
    -

    Note: There is a package with the type definitions @npm/types.

    -
    -

    In the NodeSecure/scanner these methods are used at different stages of the analysis. When we browse the dependency tree for example we use the manifest() method with the range version (or specifier) of the package.

    -
    await pacote.manifest(gitURL ?? packageName, {
    -  ...NPM_TOKEN,
    -  registry: getLocalRegistryURL(),
    -  cache: `${os.homedir()}/.npm`
    -});
    -
    -

    The library allows you to manage a whole set of things quite quickly without too much difficulty πŸ’ͺ.

    -

    Note that in the above code there is a notion of Git URL πŸ‘€.

    -

    πŸ”¬ Dependency resolution

    -

    You are probably used to see SemVer versions or ranges within your package.json. Quite similar to this:

    -
    "dependencies": {
    -    "@nodesecure/flags": "^2.2.0",
    -    "@nodesecure/fs-walk": "^1.0.0",
    -    "@nodesecure/i18n": "^1.2.0",
    -    "@nodesecure/js-x-ray": "^4.1.2",
    -    "@nodesecure/npm-registry-sdk": "^1.3.0"
    -}
    -
    -

    But there are many other ways to install/link a dependency within a package.json 😲:

    - -

    One of the advantages of pacote is that it handles most of these resolutions for you 😎. I discovered all this while working on the subject (because I had never dealt with those types of resolutions).

    -

    If you want to be able to spot them here is a regular expression:

    -
    if (/^([a-zA-Z]+:|git\+|\.\\)/.test(version)) {
    -  // Version with custom resolution
    -}
    -
    -

    This also explains why in NodeSecure we have a "hasCustomResolver" flag allowing quick identification of packages using resolutions to dependencies that diverge from the usual.

    -

    Pacote also exposes a resolve() method:

    -
    import pacote from "pacote";
    -
    -const tarURL = await pacote.resolve("@slimio/is@^1.0.0");
    -
    -

    It resolve a specifier like foo@latest or github:user/project all the way to a tarball url, tarball file, or git repo with commit hash.

    -

    πŸ“¦ Download and extract tarball

    -

    One of the steps is to retrieve the package on the local system to be able to analyze it and retrieve a set of information.

    -
    const spec = ref.flags.includes("isGit") ?
    -  ref.gitUrl : `${name}@${version}`;
    -
    -await pacote.extract(spec, dest, {
    -  ...NPM_TOKEN,
    -  registry: getLocalRegistryURL(),
    -  cache: `${os.homedir()}/.npm`
    -});
    -
    -

    The package will be extracted into a temporary directory generated when the scanner is launched.

    -
    -

    Note: see fs.mkdtemp

    -
    -

    Once the extraction is finished, we will retrieve the information we need:

    -
      -
    • Files, extensions, size on disk etc..
    • -
    • Execute NodeSecure/JS-X-Ray on each JavaScript files.
    • -
    • Fetch licenses and retrieve their SPDX conformance.
    • -
    -

    We will dig deeper into the steps of static code analysis in a future article.

    -

    😈 It can't be that simple

    -

    In all this there are things quite complex to manage:

    -
      -
    • Same packages but with different "range" of versions 🎭.
    • -
    • Ensure the integrity of the links (relations) between packages.
    • -
    -
    -

    The first one is hard because most of the time we are dealing with SemVer range and not with the EXACT version of the package. There is quite a bit of connection here with how npm handles conflict during installation (also how npm algorithms pick the right manifest).

    -

    I think I probably still lack some vision and experience on the subject. The current code is probably quite heavy too.

    -

    Today the cwd API of the Scanner use Arborist. For the from API i would like to avoid having to deal with a packument.

    -
    -

    For the second one it is mainly a problem with the behaviour of the walker that will browse asynchronously the tree. We must therefore avoid that a package already analyzed is taken into account again. The problem with this is that we will be missing relationship links between some packages in the tree.

    -

    The current scanner solves the problem by going through all the dependencies one last time to create the missing link.

    -
    for (const [packageName, descriptor] of payload.dependencies) {
    -  for (const verStr of descriptor.versions) {
    -    const verDescriptor = descriptor[verStr];
    -
    -    const fullName = `${packageName}@${verStr}`;
    -    const usedDeps = exclude.get(fullName) ?? new Set();
    -    if (usedDeps.size === 0) {
    -      continue;
    -    }
    -
    -    const usedBy = Object.create(null);
    -    const deps = [...usedDeps].map((name) => name.split(" "));
    -    for (const [name, version] of deps) {
    -      usedBy[name] = version;
    -    }
    -    Object.assign(verDescriptor.usedBy, usedBy);
    -  }
    -}
    -
    -

    ✨ Conclusion

    -

    That's it for this article where we have explored a little bit the difficulties around going through the dependency tree.

    -

    If you like the concept don't hesitate to like and share.

    -

    πŸ™ Thanks for reading and see you soon for a new article.

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/a-technical-tale-of-nodesecure-chapter2.html b/blog/a-technical-tale-of-nodesecure-chapter2.html deleted file mode 100644 index 20ebf2f..0000000 --- a/blog/a-technical-tale-of-nodesecure-chapter2.html +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    A technical tale of NodeSecure - Chapter 2

    -

    Hello πŸ‘‹,

    -

    I'm back at writing for a new technical article on NodeSecure. This time I want to focus on the SAST JS-X-Ray πŸ”¬.

    -

    I realized very recently that the project on Github was already more than two years old. It's amazing how time flies 😡.

    -

    It's been a long time since I wanted to share my experience and feelings about AST analysis. So let's jump in πŸ˜‰

    -

    πŸ’ƒ How it started

    -

    When I started the NodeSecure project I had almost no experience 🐀 with AST (Abstract Syntax Tree). My first time was on the SlimIO project to generate codes dynamically with the astring package (and I had also looked at the ESTree specification).

    -

    One of my first goals for my tool was to be able to retrieve the dependencies in each JavaScript file contained within an NPM tarball (By this I mean able to retrieve any dependencies imported in CJS or ESM).

    -

    I started the subject a bit naively 😏 and very quickly I set myself a challenge to achieve with my AST analyser:

    -
    function unhex(r) {
    -   return Buffer.from(r, "hex").toString();
    -}
    -
    -const g = Function("return this")();
    -const p = g["pro" + "cess"];
    -
    -const evil = p["mainMod" + "ule"][unhex("72657175697265")];
    -evil(unhex("68747470")).request
    -
    -

    The goal is to be able to output accurate information for the above code. At the time I didn't really know what I was getting into πŸ˜‚ (But I was passionate about it and I remain excited about it today).

    -
    -

    I thank Targos who at the time submitted a lot of code and ideas.

    -
    -

    To date the SAST is able to follow this kind of code without any difficulties 😎... But it wasn't always that simple.

    -

    🐀 Baby steps

    -

    One of the first things I learned was to browse the tree. Even for me today this seems rather obvious, but it wasn't necessarily so at the time πŸ˜….

    -

    I discovered the package estree-walker from Rich Harris which was compatible with the EStree spec. Combined with the meriyah package this allows me to convert a JavaScript source into an ESTree compliant AST.

    -
    import { readFile } from "node:fs/promises";
    -
    -import { walk } from "estree-walker";
    -import * as meriyah from "meriyah";
    -
    -export async function scanFile(location: string) {
    -  const strToAnalyze = await readFile(location, "utf-8");
    -
    -  const { body } = meriyah.parseScript(strToAnalyze, {
    -    next: true, loc: true, raw: true, module: true
    -  });
    -
    -  walk(body, {
    -    enter(node) {
    -      // Skip the root of the AST.
    -      if (Array.isArray(node)) {
    -        return;
    -      }
    -
    -      // DO THE WORK HERE
    -    }
    -  });
    -}
    -
    -

    I also quickly became familiar with the tool ASTExplorer which allows you to analyze the tree and properties for a specific code.

    -

    nodesecure

    -

    As a beginner, you can be quickly scared by the size and complexity of an AST. This tool is super important to better cut out and focus on what is important.

    -
    -

    I also had fun re-implementing the ESTree Specification in TypeScript. It helped me a lot to be more confident and comfortable with different concepts that were unknown to me until then.

    -
    -

    At the beginning of 2021 I also had the opportunity to do a talk for the French JS community (it's one more opportunity to study).

    -

    - β–Ά Watch on YouTube -

    -

    😫 MemberExpression

    -

    JavaScript member expression can be quite complicated to deal with at first. You must be comfortable with recursion and be ready to face a lot of possibilities.

    -

    Here is an example of possible code:

    -
    const myVar = "test";
    -foo.bar["hel" + "lo"].test[myVar]();
    -
    -

    nodesecure

    -

    Computed property, Binary expression, Call expression etc. The order in which the tree is built seemed unintuitive to me at first (and I had a hard time figuring out how to use the object and property properties).

    -

    Since i created my own set of AST utilities including getMemberExpressionIdentifier.

    -

    πŸš€ A new package (with its own API)

    -

    When NodeSecure was a single project the AST analysis was at most a few hundred lines in two or three JavaScript files. All the logic was coded with if and else conditions directly in the walker πŸ™ˆ.

    -

    nodesecure

    -

    To evolve and maintain the project, it became necessary to separate the code and make it a standalone package with its own API πŸ‘€.

    -

    I wrote an article at the time that I invite you to read. It contains some nice little explanations: -β†ͺ Read article

    -

    The thing to remember here is that you probably shouldn't be afraid to start small and grow into something bigger later. Stay pragmatic.

    -

    Easy to write, hard to scale 😭

    -

    It's easy to write a little prototype, but it's really hard to make it scale when you have to handle dozens or hundreds of possibilities. It requires a mastery and understanding of the language that is just crazy 😡. This is really what makes creating a SAST a complicated task.

    -

    For example, do you know how many possibilities there are to require on Node.js? In CJS alone:

    -
      -
    • require
    • -
    • process.mainModule.require
    • -
    • require.main.require
    • -
    -
    -

    I probably forget some 😈 (as a precaution I also trace methods like require.resolve).

    -
    -

    But as far as I'm concerned, it's really what I find exciting 😍. I've learned so much in three years. All this also allowed me to approach the language from an angle that I had never experienced or seen πŸ‘€.

    -

    Probes

    -

    On JS-X-Ray I brought the notion of "probe" into the code which will collect information on one or more specific node. The goal is to separate the AST analysis into lots of smaller pieces that are easier to understand, document and test.

    -
    -

    Very far from perfection 😞. However, it is much better than before and the team is now helping me to improve all this (by adding documentation and tests).

    -
    -

    It was for JS-X-Ray 3.0.0 and at the time i have written the following article (which includes many more details if you are interested). -β†ͺ Read article

    -

    VariableTracer

    -

    This is one of the new killer feature coming to JS-X-Ray soon. A code able to follow the declarations, assignment, destructuration, importating of any identifiers or member expression.

    -

    In my experience being able to keep track of assignments has been one of the most complex tasks (and I've struggled with it).

    -

    This new implementation/API will offer a new spectrum of tools to develop really cool new features.

    -
    const tracer = new VariableTracer().trace("crypto.createHash", {
    -  followConsecutiveAssignment: true
    -});
    -
    -// Use this in the tree walker
    -tracer.walk(node);
    -
    -

    This simple code will allow us, for example, to know each time the method createHash is used. We can use this for information purposes, for example to warn on the usage of a deprecated hash algorithm like md5.

    -

    Here an example:

    -
    const myModule = require("crypto");
    -
    -const myMethodName = "createHash";
    -const callMe = myModule[myMethodName];
    -callMe("md5");
    -
    -
    -

    The goal is not necessarily to track or read malicious code. The idea is to handle enough cases because developers use JavaScript in many ways.

    -
    -

    We can imagine and implement a lot of new scenarios without worries 😍.

    -

    By default we are tracing:

    -
      -
    • eval and Function
    • -
    • require, require.resolve, require.main, require.mainModule.require
    • -
    • Global variables (global, globalThis, root, GLOBAL, window).
    • -
    -

    ✨ Conclusion

    -

    Unfortunately, I could not cover everything as the subject is so vast. One piece of advice I would give to anyone starting out on a similar topic would be to be much more rigorous about documentation and testing. It can be very easy to get lost and not know why we made a choice X or Y.

    -

    Thanks for reading this new technical article. See you soon for a new article (something tells me that it will arrive soon 😏).

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/annoucing-new-nodesecure-backend.html b/blog/annoucing-new-nodesecure-backend.html deleted file mode 100644 index 4ba7d8e..0000000 --- a/blog/annoucing-new-nodesecure-backend.html +++ /dev/null @@ -1,163 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    Announcing new NodeSecure back-end

    -

    Hello πŸ‘‹

    -

    In the last article of the series I announced the future of NodeSecure. Well, we have just finished rebuilding our back-end 😲 (or at least a first version of it).

    -

    So what are the particularities of this new back-end? This is what we will discover in this article πŸ‘€.

    -

    But first let me make an introduction for the newcomers.

    -

    What is NodeSecure ❓

    -

    NodeSecure is an open source organization that aims to create free JavaScript security tools. Our biggest area of expertise is in npm package and code analysis.

    -

    Our most notable projects are:

    - -

    The main project is a CLI that will fetch and deeply analyze the dependency tree of a given npm package (Or a local project with a package.json) and output a .json file that will contain all metadata and flags about each package.

    -

    The CLI is able to open the JSON and draw a Network of all dependencies (UI and emojis flags will help you to identify potential issues and security threats).

    -

    image

    -

    More information on our Governance page.

    -

    New back-end πŸš€

    -

    Moving everything to the NodeSecure github org 🏠

    -

    All packages have been moved to the github organization. You will notice that we have a nice new logo ✨ (created by Tony).

    -

    image

    -

    This should make it simple to implement a new set of tools and collaborate more effectively. The integration of new maintainers should also be greatly simplified.

    -

    Moving to Node.js 16 and ESM

    -

    One of the major choices was to use ESM instead of CJS. Many maintainers like Sindresorhus made the choice to switch to ESM which prevented us from updating some of our packages 😭.

    -

    There are still a lot of things that are not stable, but we are convinced that it is the right choice for the future of our tools πŸ’ͺ.

    -

    Knowing that we still have time before completely finalizing the version 1 we also made the choice to have a limited support to the next LTS of Node.js.

    -

    New segmentation and packages πŸ“¦

    -

    We have segmented the back-end into a multitude of packages. That makes them reusable in other tools.

    -

    image

    -

    It will also greatly improve the quality of documentation and testing πŸ’Ž.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    namedescription
    scanner⚑️ A package API to run a static analysis of your module's dependencies.
    vulnNPM Audit, Snyk and Node.js Security WG vulnerability strategies built for NodeSecure.
    flagsNodeSecure security flags 🚩 (configuration and documentation)
    i18nNodeSecure Internationalization
    npm-registry-sdkNode.js SDK to fetch data from the npm API.
    -

    And there is still a lot more to discover (fs-walk, sec-literal , npm-tarball-license-parser etc).

    -

    Scanner API πŸ”¬

    -

    Even though we now have a dedicated package the API has not changed.

    -
    import * as scanner from "@nodesecure/scanner";
    -import fs from "fs/promises";
    -
    -// CONSTANTS
    -const kPackagesToAnalyze = ["mocha", "cacache", "is-wsl"];
    -
    -const payloads = await Promise.all(
    -  kPackagesToAnalyze.map((name) => scanner.from(name))
    -);
    -
    -const promises = [];
    -for (let i = 0; i < kPackagesToAnalyze.length; i++) {
    -  const data = JSON.stringify(payloads[i], null, 2);
    -
    -  promises.push(fs.writeFile(`${kPackagesToAnalyze[i]}.json`, data));
    -}
    -await Promise.allSettled(promises);
    -
    -

    The PDF & HTML report project has been updated to use this new back-end.

    -

    Team and contributors πŸ‘―

    -

    We are integrating Vincent Dhennin as a new maintainer. His help and contributions have been important and I can only thank him for this investment.

    -

    We are now three (including Tony Gorez and me).

    -

    I would like to thank the other contributors who participated a lot:

    - -

    What's next ?

    -

    To be clear, the objective is to prepare a version 0.9.0 of NodeSecure implementing the new back-end (already in progress).

    -

    This will allow us to continually improve and update the back-end features. It will also now be easier to work on the evolution of the CLI.

    -
    -

    We still don't have a roadmap or vision for the new interface. We will start working on it by October or November I think.

    -
    -
    -

    πŸ™ Thanks for reading and see you soon for an article on the next version of the CLI 😍.

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/announcing-nodesecure-vuln-era.html b/blog/announcing-nodesecure-vuln-era.html deleted file mode 100644 index 8f23a6f..0000000 --- a/blog/announcing-nodesecure-vuln-era.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    NodeSecure Vuln-era

    -

    Hello πŸ‘‹,

    -

    Back for a little article about the rebranding of one of the NodeSecure tools: Vulnera (previously vuln, the vuln-era has begun!).

    -

    An opportunity for me to also write about this wonderful project that was born with the redesign of the back-end less than a year ago ⌚. If you don't remember I wrote an article:

    -

    β†ͺ Read article

    -

    Don't wait and dive in 🌊 with me to discover this tool πŸ’ƒ.

    -

    What is Vulnera ? πŸ‘€

    -

    Vulnera is a package that allows you to programmatically fetch your Node.js project vulnerabilities from multiple sources or strategies:

    - -
    -

    πŸ“’ Feel free to push new sources (we have a guide on how to add/contribute one).

    -
    -

    The code was originally designed for vulnerability management within the Scanner. Yet, its API is evolving with the objective of making it a full-fledged project.

    -
    import * as vulnera from "@nodesecure/vulnera";
    -
    -const def = await vulnera.setStrategy(
    -  vulnera.strategies.NPM_AUDIT
    -);
    -
    -const vulnerabilities = await def.getVulnerabilities(process.cwd(), {
    -  useStandardFormat: true
    -});
    -console.log(vulnerabilities);
    -
    -

    Standard vulnerability format πŸ‘―

    -

    We have created a standard format to reconcile the different sources.

    -
    export interface StandardVulnerability {
    -  /** Unique identifier for the vulnerability **/
    -  id?: string;
    -  /** Vulnerability origin, either Snyk, NPM or NodeSWG **/
    -  origin: Origin;
    -  /** Package associated with the vulnerability **/
    -  package: string;
    -  /** Vulnerability title **/
    -  title: string;
    -  /** Vulnerability description **/
    -  description?: string;
    -  /** Vulnerability link references on origin's website **/
    -  url?: string;
    -  /** Vulnerability severity levels given the strategy **/
    -  severity?: Severity;
    -  /** Common Vulnerabilities and Exposures dictionary */
    -  cves?: string[];
    -  /** Common Vulnerability Scoring System (CVSS) **/
    -  cvssVector?: string;
    -  /** CVSS Score **/
    -  cvssScore?: number;
    -  /** The range of vulnerable versions */
    -  vulnerableRanges: string[];
    -  /** The set of versions that are vulnerable **/
    -  vulnerableVersions: string[];
    -  /** The set of versions that are patched **/
    -  patchedVersions?: string;
    -  /** Overview of available patches **/
    -  patches?: Patch[];
    -}
    -
    -

    You can always use the original formats of each source of course 😊. We have implemented and exposed TypeScript interfaces for each of them.

    -

    NodeSecure types

    -

    Usage in Scanner πŸ”¬

    -

    On the scanner we have all the necessary information because we go through the dependency tree πŸŽ„. At the end of the process, we recover all vulnerabilities by iterating spec by spec within the hydratePayloadDependencies strategy method.

    -
    const {
    -  hydratePayloadDependencies,
    -  strategy
    -} = await vulnera.setStrategy(
    -  userStrategyName // SNYK for example
    -);
    -await hydratePayloadDependencies(dependencies, {
    -  useStandardFormat: true,
    -  path: location
    -});
    -
    -payload.vulnerabilityStrategy = strategy;
    -
    -

    The following diagram explains the overall behavior and interactions between the Scanner and Vulnera. -NodeSecure

    -

    If you want to learn more about the Payload you can check the TypeScript interface here.

    -

    What's next ? πŸš€

    -

    Some sources are more difficult to exploit than others (for NPM we use Arborist which simplifies our lives).

    -
    const { vulnerabilities } = (await arborist.audit()).toJSON();
    -
    -

    However, we have to think and create mechanics to exploit sources like Sonatype 😨. This is required for API like getVulnerabilities().

    -

    Among the major subjects and ideas we are working on:

    -
      -
    • Create a private database to benchmark the sources between them (see #29).
    • -
    • Merging multiple sources in one (see #25).
    • -
    • Fetch vulnerabilities of a given remote package (with support for private registry like verdaccio). At the moment we only support the analysis of a local manifest or a payload of the scanner.
    • -
    -

    Credits πŸ™‡

    -

    This project owes much to our core collaborator Antoine COULON who invested a lot of energy to improve it πŸ’ͺ.

    -
    -

    Fun fact: its first contribution 🐀 on NodeSecure was also on the old version of the code Scanner that managed vulnerabilities.

    -
    -

    But I don't forget individual contributions πŸ‘

    - -
    -

    Thanks πŸ™ for reading me and see you soon for another article!

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/everything-you-need-to-know-about-package-managers.html b/blog/everything-you-need-to-know-about-package-managers.html deleted file mode 100644 index 35071f1..0000000 --- a/blog/everything-you-need-to-know-about-package-managers.html +++ /dev/null @@ -1,252 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    Everything you need to know: package managers

    -

    Welcome everyone! This article is the first one of the Everything you need to know, a Software Engineering series.

    -

    In this series, I will try to give you a solid basic understanding about Software Engineering concepts I consider important.

    -

    All modern computer systems include tools that automate the process of installing, uninstalling and updating software.

    -

    This responsibility is that of a package manager and several can intervene within the same computer system.

    -

    Operating system

    -

    The majority of Unix-based operating systems embed a package manager as standard, providing a multitude of different packages very simply.

    -

    If you have ever used a Linux distribution such as Ubuntu or Debian, you've probably used a package manager before. If I say apt-get update does that ring a bell?

    -

    This command tells APT to update all versions of packages installed. APT (Advanced Packaging Tool) is a package manager embedded very widely as standard on Linux operating systems. To install a package, you can for example enter the command apt-get install <package>.

    -

    Programming language

    -

    Most programming languages ​​can embed their own with package managers, either natively or provided within their respective ecosystem.

    -

    Take for example npm, the default package manager for Node.js. We can also mention pip for Python, NuGet for C#, Composer for PHP, etc. Similar to APT, npm makes it easy to install packages using the npm install <package> command.

    -
    -

    For this article, I decided to take npm as an example. -npm is indeed a very good support to highlight the advantages but also the disadvantages that a package manager can have. -The advantages and disadvantages listed in the following part are valid for all package managers.

    -
    -
    -

    npm is installed alongside Node.js. To reproduce these examples, [you only need to install Node.js here].

    -
    -

    In four parts, we will see what are the main reasons for such an expansion of package managers to all layers of a computer system.

    -

    1. Ease of use and maintenance of packages

    -

    The main interest of a package manager is obviously to simplify the installation of dependencies external to our application. Before the rise of npm in January 2010, the dependencies of a JavaScript application were mostly installed manually. By "manual installation" I mean:

    -
      -
    • downloading a zip archive from a remote server
    • -
    • unzipping the archive in the project
    • -
    • manual referencing of the installed version, and this with each update of a dependency.
    • -
    -

    With a package manager like npm, we therefore benefit from:

    -
      -
    • Simplified installation of a package npm install <package>
    • -
    • The simplified update of a package npm update <package>
    • -
    • The simplified removal of a package npm uninstall <package>
    • -
    -

    The packages are installed in a node_modules folder adjacent to the application and which is entirely managed by npm. All packages located in the node_modules folder can be directly imported from the application.

    -
    -

    In general, each programming language natively embeds its own module resolution management mechanism.

    -
    -

    1.1. Install

    -

    In order for a package to be installed, we first need a name which is in most cases used as a unique identifier. Naming conventions can differ from one ecosystem to another.

    -
    $ npm install rxjs 
    -
    -

    With this command, the package manager will search within the registry for a package that has the name rxjs. When the version is not specified, the package manager will usually install the latest available version.

    -

    1.2. Use

    -
    // ECMAScript Modules (ESM)
    -import { of } from "rxjs";
    -// CommonJS
    -const { of } = require("rxjs");
    -
    -

    The module systems integrated into the programming languages ​​make it possible to import a library installed locally and sometimes remotely (like Go or Deno for example). In this case with Node.js, the package must be installed locally in a node_modules folder. With Node.js, the module resolution algorithm allows the dependency to be in a node_modules folder either adjacent to the source code or in a parent folder (which sometimes leads to an unexpected behavior).

    -

    2. Managing the consistency of installed packages

    -

    Now, let's dive into a little more detail on one very important aspect that a package manager must manage: state consistency between installed packages. So far, installing a package looks like a trivial task, which is just to automate downloading a package of a certain version and making it available in a conventional folder that the application has access to.

    -

    However this management of consistency between packages turns out to be relatively difficult and the way of modeling the dependency tree varies according to the ecosystems. Most of the time, we talk about a dependency tree, but we can also talk about a dependency graph, in particular a directed graph.

    -

    If you are not familiar with the concept of directed graphs, I invite you to read the series of articles I wrote about it on dev.to with examples in JavaScript.

    -

    The implementations of these data structures can be drastically different depending on the ecosystem of a package manager, but also between package managers of the same ecosystem (npm, yarn, pnpm for Node.js for example).

    -
    -

    How to ensure that all developers share the same dependencies and therefore the same versions of each underlying library?

    -
    -

    Still in the context of npm, let's take for example a very simple list of dependencies, expressed as an object in the package.json file:

    -

    package.json

    -
    { 
    -  "dependencies": {
    -    "myDependencyA": "<0.1.0"
    -  }
    -}
    -
    -

    This object describes a dependency of our project on the myDependencyA library downloadable from the npm registry. Semantic Versioning here constrains the version of the library to be installed (here lower than 0.1.0).

    -
    -

    Semantic version management (commonly known as SemVer) is the application of a very precise specification to characterize the version of software. For more information on this subject, I invite you to take a look at the official specification https://semver.org/lang/fr/

    -
    -

    In our case, by remaining on the classic <major>.<minor>.<patch> scheme, we express the possibility of installing all the versions of myDependencyA from "0.0.1" to "0.0.9". This therefore means that any version of the dependency that respects the range is considered valid. On the other hand, this also means that if a developer A installs the dependency at 2 p.m. and a developer B installs the dependency at 5 p.m., they may both not have the same dependency tree if ever a new version of myDependencyA is released in the meantime.

    -

    The npm dependency resolution algorithm will by default favor the installation of the most recent dependency that respects the semantic management described in the package.json. By specifying npm install myDependencyA, the most recent version of myDependencyA will be installed respecting the constraint "<1.0.0" (version strictly lower than "1.0.0").

    -

    The major problem with this approach is the lack of stability and reproducibility of the dependency tree from one computer to another, for example between developers or even on the machine used in production. Imagine that version 0.0.9 of myDependencyA has just been released with a bug and your production machine is about to do an npm install on Friday at 5:59 PM…

    -

    Production deployment on friday night

    -

    The very simple example is often referred as version drift. This is why a single description file (in this case package.json) cannot be enough to guarantee an identical and reproducible representation of a dependency tree.

    -

    Other reasons include:

    -
      -
    • using a different version of the package manager whose dependency installation algorithm may change.
    • -
    • publishing a new version of an indirect dependency (the dependencies of the dependencies we list in the package.json here), which would result in the new version therefore being uploaded and updated.
    • -
    • the use of a different registry which for the same version of a dependency exposes two different libraries at a time T.
    • -
    -

    Lockfiles to the rescue

    -

    To ensure the reproducibility of a dependency tree, we therefore need more information that would ideally describe the current state of our dependency tree. This is exactly what lockfiles do. These are files created and updated when the dependencies of a project are modified.

    -

    A lockfile is generally written in JSON or YAML format to simplify the readability and understanding of the dependency tree by a human. A lockfile makes it possible to describe the dependency tree in a very precise way and therefore to make it deterministic and reproducible from one environment to another. So it's important to commit this file to Git and make sure everyone is sharing the same lockfile.

    -

    package-lock.json

    -
    {
    -  "name": "myProject",
    -  "version": "1.0.0",
    -  "dependencies": {
    -    "myDependencyA": {
    -      "version": "0.0.5",
    -      "resolved": "https://registry.npmjs.org/myDependencyA/-/myDependencyA-0.0.5.tgz",
    -      "integrity": "sha512-DeAdb33F+"
    -      "dependencies": {
    -        "B": {
    -          "version": "0.0.1",
    -          "resolved": "https://registry.npmjs.org/B/-/B-0.0.1.tgz",
    -          "integrity": "sha512-DeAdb33F+"
    -          "dependencies": {
    -            // dependencies of B
    -          }
    -        }
    -      }
    -    }
    -  }
    -}
    -
    -

    For npm, the basic lockfile is called package-lock.json. In the snippet above, we can precisely see several important information:

    -
      -
    • The version of myDependencyA is fixed at "0.0.5" so even if a new version is released, npm will install "0.0.5" no matter what.
    • -
    • Each indirect dependency describes its set of dependencies with versions that also describe their own versioning constraints.
    • -
    • In addition to the version, the contents of the dependencies can be checked with the comparison of hashes which can vary according to the registers used.
    • -
    -

    A lockfile therefore tries to accurately describes the dependency tree, which allows it to remain consistent and reproducible over time at each installation.

    -

    ⚠️ But...

    -

    Lockfiles don't solve all inconsistency problems! Package managers implementations of the dependency graph can sometimes lead to inconsistencies. For a long time, npm's implementation introduced Phantom Dependencies and also NPM doppelgangers which are very well explained on the Rush.js documentation website (advanced topics that are out of the scope of this blog post).

    -

    3. Provision of distributed and transparent databases via open-source

    -

    Distributed registries

    -

    A package manager is a client that acts as a gateway to a distributed database (often called a registry). This allows in particular to share an infinite number of open-source libraries around the world. It is also possible to define company-wide private registries in a secured network, within which libraries would be accessible.

    -
    -

    Verdaccio allows to setup a private proxy registry for Node.js

    -
    -

    The availability of registries has greatly changed the way software is developed by facilitating access to millions of libraries.

    -

    Transparent access to resources

    -

    The other benefit of open-source package managers is that they most often expose platforms or tools that allow browsing through published packages. Accessing source code and documentation has been trivialized and made very transparent. It is therefore possible for each developer to have an overview or even to fully investigate the code base of a published library.

    -

    4. Security and integrity

    -

    Using open-source registries with millions of publicly exposed libraries is pretty convenient, but what about security?

    -

    It is true that open-source registries represent ideal targets for hackers: all you have to do is take control of a widely used library (downloaded millions of times a week) and inject malicious code into it, and no one will realize!

    -

    In this part, we will see the solutions implemented by package managers and registries to deal with these attacks and limit the risks.

    -

    Integrity safety for each installed package

    -

    Given that a package can be installed from any registry, it is important to implement verification mechanisms at the level of the content of the downloaded package, to ensure that no malicious code has been injected during the download, regardless of its origin.

    -

    For this, integrity metadata is associated with each installed package. For example with npm, an integrity property is associated with each package in the lockfile. This property contains a cryptographic hash which is used to accurately represent the resource the user expects to receive. This allows any program to verify that the content of the resource matches what was downloaded. For example for @babel/core, this is how integrity is represented in package-lock.json:

    -
    "@babel/core": {
    -   "version": "7.16.10",
    -   "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.10.tgz",  
    -   "integrity": "sha512 pbiIdZbCiMx/MM6toR+OfXarYix3uz0oVsnNtfdAGTcCTu3w/JGF8JhirevXLBJUu0WguSZI12qpKnx7EeMyLA=="
    -}
    -
    -

    Let's take a closer look at how integrity can drastically reduce the risk of injecting malicious code by hashing source code.

    -

    As a reminder:

    -
    -

    We call hash function, a particular function which, from a datum supplied as input, calculates a digital fingerprint used to quickly identify the initial datum, in the same way as a signature to identify a person. Wikipedia

    -
    -

    Let's take for example a simple case:

    -
    // my-library
    -function someJavaScriptCode() {
    -  addUser();
    -}
    -
    -

    Let's imagine that this JavaScript code represents a resource that a user might want to download. Using the SHA1 hash function, we get the hash 7677152af4ef8ca57fcb50bf4f71f42c28c772be. -If ever malicious code is injected, the library's fingerprint will by definition change because the input (source code here) to the hash function will have changed:

    -
    // my-library
    -function someJavaScriptCode() {
    -  processMaliciousCode(); // this is injected, the user is not  expecting that
    -  addUser();
    -}
    -
    -

    After injecting the malicious code, still using the same SHA1 hash function, we obtain 28d32d30caddaaaafbde0debfcd8b3300862cc24 as the digital fingerprint. -So we get as results:

    -
      -
    • Original code = 7677152af4ef8ca57fcb50bf4f71f42c28c772be
    • -
    • Malicious code = 28d32d30caddaaaafbde0debfcd8b3300862cc24
    • -
    -

    All package managers implement strict specifications on this approach to integrity. For example, npm respects the W3C's "Subresource Integrity or SRI" specification, which describes the mechanisms to be implemented to reduce the risk of malicious code injection. -You can jump directly here to the specification document if you want to dig deeper.

    -

    Security constraints at the author level

    -

    To strengthen security at the level of open-source packages, more and more constraints are emerging on the side of project authors and maintainers. Recently, GitHub, which owns npm, announced that it is forcing two-factor authentication (2FA) for contributors to the 100 most popular packages. The main idea around these actions is to secure resources upstream by limiting write access to open-source packages and identifying people more precisely.

    -

    It's important to also mention that there are tools that can be used to perform automatically scans and audits continuously.

    -

    Built-in tools

    -

    In order to automate the detection of vulnerabilities, many package managers natively integrate tools allowing to scan the installed libraries. Typically, these package managers communicate with databases that list all known and referenced vulnerabilities. For example, GitHub Advisory Database is an open-source database that references thousands of vulnerabilities across multiple ecosystems (Go, Rust, Maven, NuGet, etc) e.g. npm audit command uses this database.

    -

    Third-party tools

    -

    NodeSecure

    -

    At NodeSecure we are building free open source tools to secure the Node.js & JavaScript ecosystem. Our biggest area of expertise is in package and code analysis.

    -

    Here are some example of the available tools:

    -
      -
    • @nodesecure/cli, a CLI that allow you to deeply analyze the dependency tree of a given package or local Node.js project
    • -
    • @nodesecure/js-x-ray, a SAST scanner (A static analyser for detecting most common malicious patterns)
    • -
    • @nodesecure/vulnera, a Software Component Analysis (SCA) tool
    • -
    • @nodesecure/ci, a tool allowing to run SAST, SCA and many more analysis in CI/CDs or in a local environment
    • -
    -

    Snyk

    -

    Snyk is the most popular all-around solution for securing applications or cloud-based infrastructures. Snyk offers a free-tier with SAST and SCA analysis.

    -

    To ensure continuous detection of vulnerabilities, it is recommended to run scans each time packages are installed/modified.

    -

    Conclusion

    -

    There you go, you now know what issues are addressed and solved by package managers!

    -

    Package managers are complex tools that aim to make life easier for us as developers, but can quickly become problematic if misused.

    -

    It is therefore important to understand the issues they deal with and the solutions provided in order to be able to put into perspective several package managers of the same ecosystem. In the end, it's a tool like any other and it must mobilize thinking in the same way as when libraries/frameworks/programming languages ​​are used.

    -

    Don't also forget to take into account security issues and use automated tools which can drastically reduce the attack surface!

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/index.html b/blog/index.html deleted file mode 100644 index f90ef23..0000000 --- a/blog/index.html +++ /dev/null @@ -1,842 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    - -
    - -
    - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Feb 19, 2023 - - - clock - 7 min read - - -
    -
    - - Securizing your GitHub org - -

    Learn hands-on strategies and real-world tips to boost the security of your GitHub organization. Perfect for open source maintainers and anyone serious about code safety!

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Jan 16, 2023 - - - clock - 4 min read - - -
    -
    - - JS-X-Ray 6.0 - -

    Discover what’s new in JS-X-Ray 6.0! Explore the latest features of this open source JavaScript security analyzer and see how it helps you write safer, cleaner code.

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Antoine - - - calendar - Oct 18, 2022 - - - clock - 13 min read - - -
    -
    - - Everything you need to know: package managers - -

    Curious about package managers? Explore their essential role in modern software, from Linux to npm, and learn why they’re the backbone of every developer’s workflow!

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Jul 21, 2022 - - - clock - 4 min read - - -
    -
    - - NodeSecure Vuln-era - -

    Dive into the rebranding of Vulnera, NodeSecure’s powerful tool for uncovering Node.js vulnerabilities from multiple sources. Discover its evolution and how it’s shaping the future of open source security!

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Jun 29, 2022 - - - clock - 7 min read - - -
    -
    - - NodeSecure CLI v2.0.0 - -

    TBC

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Jun 6, 2022 - - - clock - 7 min read - - -
    -
    - - A technical tale of NodeSecure - Chapter 2 - -

    TBC

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Feb 7, 2022 - - - clock - 4 min read - - -
    -
    - - NodeSecure - What's new in 2022 ? - -

    TBC

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Dec 7, 2021 - - - clock - 3 min read - - -
    -
    - - NodeSecure v0.9.0 - -

    TBC

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Nov 22, 2021 - - - clock - 5 min read - - -
    -
    - - A technical tale of NodeSecure - Chapter 1 - -

    TBC

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Sep 11, 2021 - - - clock - 4 min read - - -
    -
    - - Announcing new NodeSecure back-end - -

    TBC

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Feb 28, 2021 - - - clock - 2 min read - - -
    -
    - - JS-X-Ray 3.0 - -

    TBC

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Feb 21, 2021 - - - clock - 3 min read - - -
    -
    - - NodeSecure v0.8.0 - -

    TBC

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Jan 4, 2021 - - - clock - 3 min read - - -
    -
    - - NodeSecure - The future - -

    TBC

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Sep 12, 2020 - - - clock - 3 min read - - -
    -
    - - NodeSecure v0.7.0 and v0.8.0@next - -

    TBC

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Aug 19, 2020 - - - clock - 6 min read - - -
    -
    - - NodeSecure v0.7.0 and v0.8.0@next - -

    TBC

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Jul 30, 2020 - - - clock - 3 min read - - -
    -
    - - NodeSecure PDF Report - -

    TBC

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Apr 6, 2020 - - - clock - 6 min read - - -
    -
    - - NodeSecure release v0.6.0 - -

    TBC

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Mar 30, 2020 - - - clock - 3 min read - - -
    -
    - - JS-X-Ray 1.0 - -

    TBC

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Mar 2, 2020 - - - clock - 5 min read - - -
    -
    - - NodeSecure release v0.5.0 - -

    TBC

    -
    -
    - - -
    -
    -
    - - Thomas - -
    - Thomas - - - calendar - Jan 11, 2020 - - - clock - 4 min read - - -
    -
    - - NodeSecure release v0.4.0 - -

    TBC

    -
    -
    - -
    -
    - - - - - \ No newline at end of file diff --git a/blog/nodesecure-pdf-report.html b/blog/nodesecure-pdf-report.html deleted file mode 100644 index d04e64c..0000000 --- a/blog/nodesecure-pdf-report.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    NodeSecure PDF Report

    -

    Hello,

    -

    I had promised a little while ago to write an article about a SlimIO project that allows the generation of HTML & PDF security reports. It uses the Node-secure project API under the hood to fetch security data of npm packages and git repositories!

    -

    The initial objective was obviously to be able to automate the regular sending of a report on a set of projects (especially for our SlimIO agent packages and git). This provides an overview of the status of several projects on a regular basis.

    -

    The project is completely open-source and works with any npm/github organization. The git support has only been tested with github but it most likely works for gitlab as well.

    -

    What's the report look like?

    -

    - -

    -

    Data

    -

    All the data displayed in the report comes from Node-secure. The analysis is separated into two parts: npm packages and git repositories.

    -

    For each of them, the report will give you an assessment of:

    -
      -
    • The size (external, internal, all).
    • -
    • The dependency list.
    • -
    • The list of dependency with transitive (deep) dependencies.
    • -
    • The list of Node.js core modules used in these projects.
    • -
    • The list of authors (with their gravatar if available).
    • -
    • Charts about extensions, licenses, warnings and flags.
    • -
    -
    -

    At the moment I am not satisfied with the granularity of the information in graphics. I will work in the future to get a more accurate overview...

    -
    -

    Configuration

    -

    You just need to edit the configuration at data/config.json and run the project with the npm start command to go!

    -
    {
    -    "theme": "dark",
    -    "report_title": "SlimIO Security Report",
    -    "report_logo": "https://avatars0.githubusercontent.com/u/29552883?s=200&v=4",
    -    "npm_org_prefix": "@slimio",
    -    "npm_packages": [
    -        "@slimio/addon",
    -        "@slimio/scheduler",
    -        "@slimio/config",
    -        "@slimio/core",
    -        "@slimio/arg-parser",
    -        "@slimio/profiles",
    -        "@slimio/queue",
    -        "@slimio/sqlite-transaction",
    -        "@slimio/alert",
    -        "@slimio/metrics",
    -        "@slimio/units",
    -        "@slimio/ipc",
    -        "@slimio/safe-emitter"
    -    ],
    -    "git_url": "https://github.com/SlimIO",
    -    "git_repositories": [
    -        "Aggregator",
    -        "Alerting",
    -        "Socket",
    -        "Gate",
    -        "ihm"
    -    ],
    -    "charts": [
    -        {
    -            "name": "Extensions",
    -            "display": true,
    -            "interpolation": "d3.interpolateRainbow"
    -        },
    -        {
    -            "name": "Licenses",
    -            "display": true,
    -            "interpolation": "d3.interpolateCool"
    -        },
    -        {
    -            "name": "Warnings",
    -            "display": true,
    -            "type": "horizontalBar",
    -            "interpolation": "d3.interpolateInferno"
    -        },
    -        {
    -            "name": "Flags",
    -            "display": true,
    -            "type": "horizontalBar",
    -            "interpolation": "d3.interpolateSinebow"
    -        }
    -    ]
    -}
    -
    -

    The theme can be either dark or light. Themes are editable/extendable at public/css/themes. (feel free to PR new themes etc).

    -

    The npm_org_prefix is only useful to determine whether or not the package is internal or external.

    -
    -

    Charts only have four properties: name, display, type and interpolation. Interpolation is the function used for the chart background colors (all possible interpolation can be found on the D3 doc).

    -

    The type is by default equal to bar. You can configure it at horizontalBar or pie. (note: not worked much on pie support).

    -

    What's next?

    -

    I'm already pretty happy with the initial result but there's still a lot of work to be done. Some of the improvements I have in mind include:

    -
      -
    • A more complete and flexible configuration.
    • -
    • A better PDF generation (There are a lot of problems between the HTML and PDF versions).
    • -
    • Continue to improve the design of the report (both UI and UX).
    • -
    • Enhance the GIT config (allow local path and complete GIT url).
    • -
    • Add some modules to forward the report to an email or anything else (slack, discord etc.).
    • -
    -

    All contributions are of course welcome!

    -

    Conclusion

    -

    -

    As usual a great pleasure for me to extend the use of Node-secure and to be able to collect a set of statistics on my projects (it's always exciting to discover hidden things.).

    -

    I'm also quite happy that this project can be used by different companies (even if for the moment there is still some work to be done).

    -

    https://github.com/SlimIO/Security

    -

    Thank you for taking the time to read!

    -

    Best Regards, -Thomas

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/nodesecure-the-future.html b/blog/nodesecure-the-future.html deleted file mode 100644 index f4b81f8..0000000 --- a/blog/nodesecure-the-future.html +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    NodeSecure - The future

    -

    Hello πŸ‘‹

    -

    Today I'm writing to tell you about the future of NodeSecure πŸ‘€.

    -

    I have not been very active in the last few months because of my job which has taken up a lot of my time. But I'm back 😊.

    -

    Moving forward and updating the project has become much more complicated 😡. So it was time to announce and make major changes.

    -

    What is node-secure (or nsecure) ?

    -

    Node-secure is a CLI that will fetch and deeply analyze the dependency tree of a given npm package (Or a local project with a package.json) and output a .json file that will contains all metadata and flags about each packages.

    -

    The CLI is able to open the JSON and draw a Network of all dependencies (UI and emojis flags will help you to identify potential issues and security threats).

    -

    🏫 Creating an organization

    -

    NodeSecure is not only one tool anymore. The project is now a set of tools and packages that need to be maintained and extended. The project has also gained contributors on its way and many developers pushed me to go even further πŸš€.

    -

    That's why I decided to gather these different projects in the same github organization (and same for npm with @nodesecure). It will also be easier to integrate new collaborators into the project.

    -

    The URL to our new home: https://github.com/NodeSecure

    -

    πŸ“‹ Roadmap

    -

    Well, that's all very nice, but what is the objective in concrete terms? The goal is to release a version 1.0 with the following roadmap:

    -

    Move all the packages in the org

    -
      -
    • js-x-ray
    • -
    • sec-literal
    • -
    • size-satisfies
    • -
    • npm-tarball-license-parser
    • -
    • Migrating SlimIO/Security into the org and rename it @nodesecure/report.
    • -
    • Rewriting SlimIO/npm-registry from zero in the org (with undici as http client).
    • -
    -

    We will update these packages and they will use ESM by default.

    -

    Split Nsecure into three parts

    -

    We will rewrite the Nsecure back-end logic into an independent package named scanner. The CLI and the UI will also be separated in two distinct packages.

    -

    We will focus our efforts initially on the scanner. The objective is above all to simplify maintenance by separating the project into minimal parts that can be more easily documented, evolved and tested.

    -

    This should also reduce the number of dependencies for tools that only want to use the scanner without the CLI and UI.

    -
    -

    ⚠️ We will update the current nsecure package with the new components until the new version arrives.

    -
    -

    New UI

    -

    The NodeSecure web interface will be rewritten from scratch. This new project will use D3.js to generate the network graph.

    -

    It will also be a good opportunity to discuss what we will use for the new interface.

    -

    πŸ‘₯ The team

    -

    I am pleased to announce that I am launching this initiative with Tony Gorez who, as you know, has contributed a lot to the project in recent months.

    -

    Several developers have indicated their intention to actively participate... so the team will grow very quickly.

    -

    This is just the beginning and you are welcome to join us if you want to contribute.

    -
    -

    πŸ’¬ We use Discord to communicate. My Discord tag fraxken#8064.

    -
    -

    Thanks ❀️

    -

    And that's it! A lot of work ahead for us. The new interface will certainly take a few months to be created so don't expect V1 anytime soon.

    -

    However those changes should allow us to release a 0.9 and 0.10 version very quickly in the coming weeks.

    -

    Best Regards, -Thomas

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/nodesecure-v0.4.0.html b/blog/nodesecure-v0.4.0.html deleted file mode 100644 index da65824..0000000 --- a/blog/nodesecure-v0.4.0.html +++ /dev/null @@ -1,163 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    NodeSecure release v0.4.0

    -

    Hey !

    -

    Writing my first article on the platform to introduce a new release of a tool. I'm working on for few months with some members of the French JavaScript community.

    -

    https://github.com/ES-Community/nsecure

    -

    First, What is node-secure (or nsecure) ?

    -

    Node-secure is a CLI that will fetch and deeply analyze the dependency tree of a given npm package (Or a local project with a package.json) and output a .json file that will contains all metadata and flags about each packages.

    -

    The CLI is able to open the JSON and draw a Network of all dependencies (UI and emojis flags will help you to identify potential issues and security threats).

    -

    The package is usable as an API too if you want to achieve a security analysis on multiple non-related packages or projects (As we do in my team: https://github.com/SlimIO/Security).

    -

    Release v0.4.0

    -

    So what's new in this release ? This is what we will see below:

    -

    Enhanced license analysis with conformance

    -

    Thanks to Tierney Cyren for developing the conformance package which is allowing the tool to retrieve all spdx informations in the generated .json file.

    -
    {
    -    "uniqueLicenseIds": [
    -        "MIT"
    -    ],
    -    "hasMultipleLicenses": false,
    -    "licenses": [
    -        {
    -            "uniqueLicenseIds": [
    -                "MIT"
    -            ],
    -            "spdxLicenseLinks": [
    -                "https://spdx.org/licenses/MIT.html#licenseText"
    -            ],
    -            "spdx": {
    -                "osi": true,
    -                "fsf": true,
    -                "fsfAndOsi": true,
    -                "includesDeprecated": false
    -            },
    -            "from": "package.json"
    -        }
    -    ]
    -}
    -
    -

    All informations are not in the UI yet... But these are going to be useful for advanced conformance tests on a whole enterprise package/project stack.

    -

    New flags documentation and UI legends

    -

    While this is certainly not perfect yet, we have worked on improving the documentation and legends UI to allow developers to better understand the implication of all flags (and by the same way some road for resolving some of them).

    -

    -

    And emoji in the left "info" menu now show a little description on hover:

    -

    -
    -

    Help is welcome to improve these descriptions!

    -
    -

    New global stats

    -

    This release includes three new global stats:

    -
      -
    • Extensions types count
    • -
    • Licenses count
    • -
    • Maintainers (with Avatar and link when available).
    • -
    -

    The maintainers stat is not finished yet. (and this doesn't include git contributors and npm package publishers.). Right now this is more about packages owners rather than maintainers.

    -

    -

    New flag

    -

    πŸ“š hasMultipleLicenses

    -

    This flag has been created in case we detect different licenses in different files. For example:

    -
      -
    • package.json: MIT detected
    • -
    • LICENSE: ISC detected
    • -
    -

    So in this given case the package will be flagged has been having multiple licenses.

    -

    πŸ‘€ hasMissingOrUnusedDependency

    -

    The package has a missing dependency (in the package.json) or a dependency installed but not required in the code itself.

    -

    -

    However don't jump to conclusion to soon! Some packages use for good reason dev dependencies like @types/node or even use a package installed by a sub dependency (not a cool practice but it happens...).

    -

    New CLI commands

    -

    This version brings a new auto command to the CLI that allow to chain a cwd or from command with the command to open the json with an http server.

    -

    Before with v0.3.0:

    -
    $ nsecure from express
    -$ nsecure http
    -# still possible, but http has been replaced with the `open` command
    -
    -

    After with v0.4.0:

    -
    $ nsecure auto express
    -
    -

    Everything else

    -
      -
    • More tests (65% to 75%+ coverage).
    • -
    • new AST features (require.resolve, process.mainModule ...).
    • -
    • Enhance and cleanup vulnerabilities detection code (and execute hydrate-db automatically).
    • -
    -

    Installation ?

    -
    $ npm install nsecure -g
    -
    -

    Node.js v12.10.0 or higher is required to run the tool. Check the project page for all informations and usage example: https://github.com/ES-Community/nsecure

    -

    What's next ?

    -

    Still a lot of work around making the current implemented features dry (still a lot of edge cases where flags are not getting the situation).

    - -

    Thanks for reading me !

    -

    Best Regards, -Thomas

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/nodesecure-v0.5.0.html b/blog/nodesecure-v0.5.0.html deleted file mode 100644 index e986430..0000000 --- a/blog/nodesecure-v0.5.0.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    NodeSecure release v0.5.0

    -

    Hello !

    -

    The "new" release v0.5.0 of node-secure has been published few hours ago. This release includes new features and a lot of UI improvement.

    -

    Do not hesitate to check the article on the v0.4.0 (which include a presentation of the project too).

    -

    I have made a little video to show the new UI and some of the new features (click on the image). - - -

    -

    Release v0.5.0

    -

    πŸ’€ isDead flag

    -

    This is a new activity flag. This means that the dependency (the package) has not received any updates from at least one year and has at least one dependency that need to be updated.

    -
    -

    The condition and the period of one year is still experimental.

    -
    -

    In the payload the real name of the flag is hasOutdatedDependency. isDead is the composition of hasOutdatedDependency and the new metadata hasReceivedUpdateInOneYear.

    -

    New metadata in the payload

    -

    The payload has brand-new metadata that has been useful to create the new πŸ’€ flag.

    -
      -
    • dependencyCount (Number of dependencies of the package)
    • -
    • hasReceivedUpdateInOneYear
    • -
    -

    🎭 Emoji on the network graph

    -

    This emoji is not a real flag and is only added in the UI to indicate that the package is already somewhere else in the dependency tree (with different versions).

    -

    -

    New searchbar

    -

    The new search bar is still a prototype (the goal is to build a search bar with real query API like Discord or Github.). The complete search bar will land in v0.6.0 !

    -

    -

    And it is even possible to filter:

    -

    -

    Available filters are:

    -
      -
    • package (default)
    • -
    • version
    • -
    • license
    • -
    • ext
    • -
    • builtin (allow to search for usage of a given Node.js core dependency)
    • -
    • author
    • -
    • flag (the complete flag name)
    • -
    -

    Clickable list items

    -

    Some of the list items in the left menu are now clickable (showed in the presentation video). Depending on the kind of items, the action will be different:

    -
      -
    • Node.js dependencies (Open the Node.js documentation)
    • -
    • Third-party dependencies (Open and move to the dependency in the network graph)
    • -
    • Required Files (Open the file on github.. when possible).
    • -
    -

    Show more / Show less for list items

    -

    Only the first 5 rows are now displayed by default. Before this feature this was a nightmare to navigate when a given package had a LOT of dependencies and required files.

    -

    -

    License popup

    -

    This version allows to click on the License field in the left menu.

    -

    -

    This will open a popup with a table of all licenses used in the project with their conformance information.

    -

    -

    New warnings

    -

    Warnings emoji has been refactored and has a new meaning. Now the payload can contain a list of warnings. These warnings are:

    -
      -
    • unsafe-import (the AST analysis has failed to retrieve the required/imported package/file name).
    • -
    • unsafe-regex (a vulnerable regex can lead to a ReDos attack).
    • -
    • ast-error (when an error occur in the AST analysis of the package).
    • -
    -

    Unsafe-import and unsafe-regex are related to a file with the exact position of the problem. Like licenses these warnings are available in a popup:

    -

    -

    In the JSON it will produce an object like the following one

    -
    "warnings": [{
    -    "kind": "unsafe-regex",
    -    "start": {
    -        "line": 81,
    -        "column": 20
    -    },
    -    "end": {
    -        "line": 81,
    -        "column": 76
    -    },
    -    "file": "old.js"
    -}]
    -
    -

    Improved flags: πŸ‘€ and πŸ”¬

    -

    The AST analysis has been updated to support new patterns:

    -
      -
    • exclude dependency required in a try statement
    • -
    • exclude the package itself from the dependency list (case detected on ajv).
    • -
    • exclude one line CJS require from being detected as "minified" file.
    • -
    -

    Example

    -
    modules.exports = require("./src/file.js");
    -
    -

    Better CLI

    -

    The CLI will now give you a clear state of what is going on under the hood with some new lazy spinners!

    -

    -

    --keep for nsecure auto command

    -

    By default the .json file will be removed when the CLI is closed with the auto command. This can be disabled with the --keep (-k) flag.

    -

    This makes the default behavior of auto more consistent.

    -
    nsecure auto express --keep
    -
    -

    A lot more...

    -

    A lot of refactoring has been done and new tests has been added to the project!

    -

    What's next ?

    -

    The next release will "surely" include:

    -
      -
    • The final search-bar prototype with a complete query API.
    • -
    • A new CLI command to run an AST analysis on a given npm package.
    • -
    • New warnings ? (I want to implement a secrets detection.. not sure "how" yet).
    • -
    • More tests, more stability etc.
    • -
    -

    One of the next major features to implement is the support of package-lock.json (the current analysis may not match the current locked project dependency tree).

    -

    And surely more with the feedbacks of those who use the tool.

    -

    Bonus

    -

    With my team we are working on a customizable open-source Security report that use node-secure under the hood to analyze a given list of packages and git repositories. I will write a complete article when the project will be done (soon).

    -

    The project on github: https://github.com/SlimIO/Security

    -

    Preview of the design report (white theme available too).

    -

    -

    -
    -

    Thanks for reading me and see you for the next release :)

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/nodesecure-v0.6.0.html b/blog/nodesecure-v0.6.0.html deleted file mode 100644 index f422331..0000000 --- a/blog/nodesecure-v0.6.0.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    NodeSecure release v0.6.0

    -

    Hello world!

    -

    I recently published the release v0.6.0 of Node-secure. If you missed the previous articles:

    - -

    These past weeks I have worked hard on exporting the AST Analysis in is own npm package js-x-ray. I have written an article on this subject recently if you want to know more.

    -

    As usual we will review the new features that version 0.6.0 brings.

    -

    New features

    -
    -

    no more AST analysis and more coverage

    -

    The AST analysis has been moved to the js-x-ray package. This notably allowed to reduce the number of tests to maintain.

    -

    Even more tests have been added to enhance the coverage by ten percent (95%).

    -

    webpack

    -

    All front-end assets is now bundled with webpack. This slightly improves the maintainability of front assets and codes.

    -

    The configuration is surely not perfect, and a lot of space could surely be saved for the package tarball.

    -

    i18n

    -

    This version allows for new languages to be added. The current version support both English and French (which is my native language).

    -

    -

    The tokens cover all the parts of Node-secure (CLI, API and UI). However, the UI is not entirely finished because a lot of text is added through the JavaScript code (I will work on improving the surface for the next version.).

    -

    Feel free to pull-request your own language (or help with existing one). There is a root i18n directory on the Github.

    -

    The lang command has been added to be able to switch between languages.

    -
    $ nsecure lang
    -
    -

    used by + npm home page

    -

    Move between parent and children easily with the left menu (used by / third-party dependencies).

    -

    And a new link to open the npm package page.

    -

    -

    multiple filters searchbar

    -

    The new searchbar allows to search anything on the tree (graph) by multiple criteria (filters). The current available filters are:

    -
      -
    • package (the default filter if there is none).
    • -
    • version (take a semver range as an argument).
    • -
    • flag (list of available flags in the current payload/tree).
    • -
    • license (list of available licenses in the current payload/tree).
    • -
    • author (author name/email/url).
    • -
    • ext (list of available file extensions in the current payload/tree).
    • -
    • builtin (available Node.js core module name).
    • -
    -

    Exemple of query:

    -
    version: >=1.2 | 2, ext: .js, builtin: fs
    -
    -

    The searchbar and some of the filters still require a huge amount of work to work properly (example: there is missing flags). So don't worry we will work to improve it for the next version!

    -

    -

    new verify command

    -
    $ nsecure verify express
    -
    -

    This new command has only been fully implemented as API but not yet full featured for the CLI. I created the command to run complete and advanced analysis on a given npm package.

    -

    Why ?

    -
      -
    • Better precision on the SourceLocation of each required dependency.
    • -
    • More metadata (which we should normally avoid to not make the json too heavy).
    • -
    -

    And maybe more in the future. In CLI the command only print the JSON payload to the terminal.

    -
    interface VerifyPayload {
    -    files: {
    -        list: string[];
    -        extensions: string[];
    -        minified: string[];
    -    };
    -    directorySize: number;
    -    uniqueLicenseIds: string[];
    -    licenses: License[];
    -    ast: {
    -        dependencies: {
    -            [fileName: string]: Dependencies;
    -        };
    -        warnings: Warning[];
    -    };
    -}
    -
    -

    global warnings

    -

    The root of the Node-secure JSON has been completely refactored to allow new metadata to appear in the future.

    -
    {
    -  "id": "7743b4ef",
    -  "rootDepencyName": "express",
    -  "warnings": [],
    -  "dependencies": {}
    -}
    -
    -

    And one of the new root metadata is warnings. At the moment these are just simple warning messages.

    -

    -
    -

    Example with @scarf/scarf which is a package that collect data against your will by default.

    -
    -

    These warnings will obviously evolve over time!

    -

    New warnings

    -

    New experimental warnings were added by the js-x-ray AST analysis:

    -
      -
    • unsafe-stmt (eval or Function("..."))
    • -
    • hexa-value (An hex value has been detected in a Literal)
    • -
    • short-ids (This mean that all identifiers has an average length below 1.5. Only possible if the file contains more than 5 identifiers).
    • -
    • suspicious-string
    • -
    -

    Hexa-value is not a much relevant as we want yet (we will work to remove 80-90% of false positives).

    -
    -

    Please feel free to feedback on these warnings! Making them as precise as possible is essential to achieve the goal of Node-secure.

    -
    -

    Better AST Analysis

    -

    At least 20 to 30 hours of work have been invested on the js-x-ray package. The current release detects major security threats in ALL Node.js code payload of the precedent attacks and issues (some are hosted on badjs.).

    -
    -

    If you think you have a code that is not detected then open an issue (We'll make sure to detect it in the future.).

    -
    -

    At the beginning of the project we laughed about how cool it would be to be able to detect what's going on in the following code:

    -
    function unhex(r) {
    -    return Buffer.from(r, "hex").toString();
    -}
    -
    -const g = eval("this");
    -const p = g["pro" + "cess"];
    -
    -const evil = p["mainMod" + "ule"][unhex("72657175697265")];
    -evil(unhex("68747470")).request
    -
    -

    But it's no longer a dream...

    -
    required:
    -[ 'http' ]
    -
    -warnings:
    -[
    -  'unsafe-stmt -> eval',
    -  'unsafe-assign -> g.process',
    -  'unsafe-assign -> p.mainModule.require',
    -  'hexa-value -> require',
    -  'unsafe-import -> http'
    -]
    -
    -

    (this is a simple log, there a much more available informations like SourceLocation etc)

    -

    New flag βš”οΈ hasBannedFile

    -

    No more inspiration for emoji πŸ˜…

    -

    This new flag uses the API entry of the package ban-sensitive-files. This highlight that the project has at least one sensitive file (or a file with sensitive information in it).

    -

    File like .pem or .key are considered sensitive.

    -

    A lot of fix and improvement

    -
      -
    • Fix UI popup overflow-y and add a max-height.
    • -
    • Fix Node.js fs ENOENT error with the auto-command when the nsecure-result.json file is manually deleted.
    • -
    • Add child_process to the list of dependencies for 🌍 hasExternalCapacity flag.
    • -
    • Remove all @types/ from unused dependencies list.
    • -
    -

    What's next ?

    -

    The next version will mainly be used to stabilize and complete the functionality of this version.

    -
      -
    • Add an history to the searchbar.
    • -
    • Add a new size filter (ex: size: >= 32KB).
    • -
    • Fix all bugs and add translation tokens (searchbar).
    • -
    • Add the CLI output for verify command.
    • -
    • Add more i18n tokens for the UI.
    • -
    • Add the list of "sensitive" files in the JSON (and the left menu in the UI).
    • -
    -

    One of the next major feature will be to walk the dependency tree by using the package-lock.json (only with the cwd command). This feature will bring a lot of new flags to match as possible the usage of lockfile-lint.

    -

    How to use it ?

    -
    $ npm i nsecure -g
    -$ nsecure auto express
    -
    -

    Please take a look at the complete documentation here.

    -

    Conclusion

    -

    Thank to all of those who give me valuable feedback. Thank you for taking the time to read my articles too!

    -

    https://github.com/ES-Community/nsecure

    -

    Think to put a star on the github!

    -

    Best Regards, -Thomas

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/nodesecure-v0.7.0.html b/blog/nodesecure-v0.7.0.html deleted file mode 100644 index 185929b..0000000 --- a/blog/nodesecure-v0.7.0.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    NodeSecure v0.7.0 and v0.8.0@next

    -

    Hi,

    -

    I'm writing this article a bit late because version 0.7.0 has already been published 3 months ago. So I'm going to take this opportunity to make the link with the next version already testable with the @next tag.

    -

    For those who don't know the tool yet: https://github.com/ES-Community/nsecure#about

    -

    Version 0.7.0

    -

    Let's discover the new features of version 0.7.0

    -

    verify command CLI output

    -

    The command now work with CLI. Although it will certainly require some iteration and long-term work to improve the stdout.

    -
    -

    As a reminder, this command allows you to have a much more complete report of the result of the AST analysis for a given npm package.

    -
    -

    -

    Popups improvement

    -

    Warnings and licenses popups design has been enhanced. Also the tables in these popups will now by default be filterable when clicking on a column name.

    -

    Warnings popup new features

    -

    The warnings popup has been greatly improved with:

    -
      -
    • New top buttons to allow you to quickly browse the sources on npm and unpkg.
    • -
    • A search input when there a lot of warnings.
    • -
    • Clicking on the name of the file now opens it on unpkg..
    • -
    -

    -

    New way to walk the tree with cwd command

    -

    Before the cwd command was walking the tree in the same way as the from command. It was however impossible to get the tree from the package-lock.json file.

    -

    This release will now read and walk with the local package-lock.json by default (can always be disabled using an option).

    -

    Lot of hotfix and code refactoring

    -

    This version includes a lot of bugfixes and code improvements of all kinds.

    -
    -

    Version @next (v0.8.0)

    -

    This version is still under development but brings important improvements.

    -

    @npmcli/arborist

    -

    In the previous version we used a home-made implementation to browse package-lock.json. But now we use one of the new npm packages: @npmcli/arborist.

    -

    The implementation of this version is much faster and accurate.

    -

    It never end

    -

    We corrected an issue that caused CLI in some cases to never complete the analysis. The process was blocked indefinitely and the counters stopped moving.

    -

    JS-X-Ray 2.0

    -

    😱😱😱! This new version of Node-secure includes the latest version of JS-X-Ray.

    -

    I wrote a whole article recently about this new version that I highly recommend you to read if you haven't already done so: https://dev.to/fraxken/js-x-ray-2-0-1mk0

    -
    -

    What's next ?

    -
      -
    • New :size filter for the searchbar (already implemented on master).
    • -
    • Verify command now work for local project too (already implemented on master).
    • -
    • I'm working on the possibility to draw the network tree with D3.js instead of Vis.js (The idea is to achieve a much more complete experience).
    • -
    • Maybe a new flag to identify native addon.
    • -
    • Continue to iterate on all current features.
    • -
    -
    -

    Don't hesitate to provide us feedbacks which are precious to us to improve or invent functionalities.

    -
    -

    Conclusion

    -

    The project continues to move forward little by little and I'm still very satisfied with the tool.. And I hope that the people who follow and use it are are also satisfied.

    -

    Thanks for reading !

    -

    Best Regards, -Thomas

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/nodesecure-v0.8.0.html b/blog/nodesecure-v0.8.0.html deleted file mode 100644 index f3fd234..0000000 --- a/blog/nodesecure-v0.8.0.html +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    NodeSecure v0.8.0

    -

    Hello,

    -

    It's been a while since I've had the opportunity to write an article here (Slightly less free time for open-source at the moment).

    -

    Today I released the version 0.8.0 of Node-secure (not a pre-release this time).

    -

    Let's dive directly into what's new since the last article;

    -

    JS-X-Ray 2.3.0

    -

    A lot of improvement has been made on the static analysis. The number of "encoded-literals" warnings has been reduced by 50%!

    -

    The analysis is also capable to detect Morse code πŸ˜† (not a joke). -

    -

    Verify command on a local project

    -

    It is now possible to run the verify command on a local project. You just have to omit the package name (as for the auto command).

    -
    $ nsecure verify
    -
    -

    Search packages by size

    -

    The search bar now allows you to filter packages by their size. Example with express:

    -

    image

    -

    Under the hood it use a package i created: size-satisfies

    -

    Inspect and show warning code

    -

    This new version add an "inspect" column to the warnings popup. If you make a click it will load and display the code in a little block.

    -

    image

    -
    -

    Thanks to tony for his work on the feature. It took us several weeks to get a result we were happy with.

    -
    -

    Replacing webpack with esbuild

    -

    The UI build with esbuild instead of webpack. Now the build is done in about 200ms and we have removed all dependencies related to webpack.

    -

    New flag for native addons 🐲

    -

    We added the flag hasNativeCode 🐲 if the package contains anything related to a native addon:

    -
      -
    • .c, .cpp, .gyp file extensions
    • -
    • a dependency known to be useful for native addon (node-gyp, node-addon-api, prebuildify... things like this).
    • -
    • "gypfile" property is true in the package.json
    • -
    -

    image

    -

    Summary command

    -

    A new "beta" command we added to show a summary for a given Nsecure JSON payload (as we do in the interface).

    -

    image

    -
    -

    Thanks again to tony who worked on the feature. ⚠️ There are still missing elements that will certainly be added in the next version.

    -
    -

    The github issue is available here.

    -

    Other contributions

    -
      -
    • Global warnings are now also displayed at CLI runtime so that they don't go unnoticed.
    • -
    • Global warnings are also part of the i18n.
    • -
    • Use Github actions instead of Travis.
    • -
    • Add the version of Node-secure in the JSON payload.
    • -
    • Enhance flags description (HTML).
    • -
    -

    Thanks to Tony, Targos, Mickeal and kecsou for all the contributions.

    -

    Release available here.

    -

    What's next ?

    -
      -
    • Adding support for Snyk and Npm audit to detect and fetch CVE.
    • -
    • Taking into account the compatibility of the version when loading the json - PR open by Tony.
    • -
    • Rework part of the UI with web component (i'm already working on a POC).
    • -
    • Use D3.js instead of Vis.js (no POC on how we will do this yet).
    • -
    • Working a lot to enhance JS-X-Ray and the static analysis.
    • -
    -

    If you think you have ideas don't hesitate to come talk and contribute.

    -

    Conclusion

    -

    A version that took a long time to be published but in the end I am still satisfied with the progress made.

    -

    Thanks for reading!

    -

    Best Regards, -Thomas

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/nodesecure-v0.9.0.html b/blog/nodesecure-v0.9.0.html deleted file mode 100644 index 2a90072..0000000 --- a/blog/nodesecure-v0.9.0.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    NodeSecure v0.9.0

    -

    Hello πŸ‘‹,

    -

    After more than ten long months of work we are finally there 😡! Version 0.9.0 has been released on npm πŸš€.

    -

    This is a version that required a lot of effort. Thank you to everyone who contributed and made this possible πŸ™.

    -

    So what are the features of this new release v0.9.0? This is what we will discover in this article πŸ‘€.

    -
    -

    For newcomers you can learn more about NodeSecure here or by reading the series.

    -
    -

    V0.9.0 πŸ’ͺ

    -

    This new version uses the new back-end and especially version 3 of the scanner.

    -

    ESM instead of CJS

    -

    This is a choice we explained in a previous article. This version has been completely rewritten in ESM.

    -

    We also made the choice to abandon Jest which causes too many problems 😟. We now use tape.

    -

    Better CLI

    -

    All commands are now separated by file and the bin/index.js file has been cleaned of all unnecessary code.

    -

    CLI

    -

    We are also working on adding UT for each command (which should avoid regressions and allow better contributions).

    -

    New front-end network management

    -

    This release heavily improves the front-end code with the addition of a package dedicated to vis-network management.

    -

    πŸ”— GitHub: NodeSecure/vis-network

    -

    This should also allow us to migrate more easily to D3.js in 2022 πŸš€.

    -

    Better resolver support

    -

    The new version of the scanner has support for github: and git: spec.

    -

    The scanner is now able to analyze the following dependencies:

    -
    "dependencies": {
    -  "zen-observable": "^0.8.15",
    -  "nanoid": "github:ai/nanoid",
    -  "js-x-ray": "git://github.com/NodeSecure/js-x-ray.git",
    -  "nanodelay": "git+ssh://git@github.com:ai/nanodelay.git",
    -  "nanoevents": "git+https://github.com/ai/nanoevents.git"
    -}
    -
    -

    Better payload structure

    -

    The structure of JSON has been improved to be more consistent (especially on the management of versions by dependency).

    -

    The latest version of the scanner also corrects many inconsistencies in the management of authors and maintainers.

    -
    "author": {
    -  "name": "GENTILHOMME Thomas",
    -  "email": "gentilhomme.thomas@gmail.com"
    -},
    -"publishers": [
    -  {
    -    "name": "fraxken",
    -    "email": "gentilhomme.thomas@gmail.com",
    -    "version": "2.2.0",
    -    "at": "2021-11-11T18:18:06.891Z"
    -  }
    -],
    -"maintainers": [
    -  {
    -    "name": "kawacrepe",
    -    "email": "vincent.dhennin@viacesi.fr"
    -  },
    -  {
    -    "name": "fraxken",
    -    "email": "gentilhomme.thomas@gmail.com"
    -  },
    -  {
    -    "name": "tonygo",
    -    "email": "gorez.tony@gmail.com"
    -  }
    -]
    -
    -

    Brand new vulnerabilities management

    -

    We have already presented it, but now we use our own package that allows to recover vulnerabilities using several strategies (Security WG, NPM Audit etc..).

    -

    πŸ”— GitHub: NodeSecure/vuln

    -

    This is just the beginning and I think it will soon be a fully featured project. Among the new features there is a new standard format dedicated for NodeSecure:

    -
    export interface StandardVulnerability {
    -    id?: string;
    -    origin: Origin;
    -    package: string;
    -    title: string;
    -    description?: string;
    -    url?: string;
    -    severity?: Severity;
    -    cves: string[];
    -    cvssVector?: string;
    -    cvssScore?: number;
    -    vulnerableRanges: string[];
    -    vulnerableVersions: string[];
    -    patchedVersions?: string;
    -    patches?: Patch[];
    -}
    -
    -

    Trojan source detection with JS-X-Ray 4.2.0

    -

    The new backend implements the version 4 of JS-X-Ray. In this latest release we added a warning for Trojan source.

    -

    Documentation and tests

    -

    A lot of effort has been put into adding documentation and unit testing to all of the projects.

    -

    There is still a long way to go to make this even more accessible and you are welcome to help us.

    -

    What's next ?

    -

    We are now working as a group on different topics. We have many ongoing projects/subjects:

    - -

    Conclusion πŸ™

    -

    We should be able to produce more frequent releases until the new UI comes.

    -

    Thanks again to the core contributors of the project without whom we would not have arrived here today!

    -

    See you soon for the release v0.10.0 πŸ’ƒ.

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/nodesecure-whats-new-in-2022.html b/blog/nodesecure-whats-new-in-2022.html deleted file mode 100644 index d598a23..0000000 --- a/blog/nodesecure-whats-new-in-2022.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    NodeSecure - What's new in 2022 ?

    -

    Hello πŸ‘‹,

    -

    Back for a different article than usual. This is the opportunity for me to talk about the NodeSecure project and to tell you about what's new since the beginning of the year πŸ’ƒ.

    -

    The project has grown significantly and we are now several active contributors on the project 😍. This opens up great opportunities for the organization and our tools as a whole.

    -

    Above all, many thanks to all those who participate in this adventure 😘. If you also follow the project and want to contribute and learn, do not hesitate πŸ™Œ.

    -

    Release 1.0.0 πŸš€

    -

    We have moved and renamed the main project. It became necessary to bring the project into the org to allow everyone to discover our other tools.

    -

    Now available on the NodeSecure github under the cli name. The old package has been deprecated and the new release can be downloaded with the name @nodesecure/cli.

    -

    Changing the name was necessary. It all started with one tool but now NodeSecure is a family of tools, contributors πŸ‘― etc.

    -

    This also marks the beginning of the first major release πŸŽ‰.

    -
    $ npm install -g @nodesecure/cli
    -
    -

    πŸ”— GitHub: NodeSecure/cli

    -

    And by the way: this new release include support for Workspaces with the cwd command 😎.

    -

    NodeSecure ci πŸ“Ÿ

    -

    Image description

    -

    A remarkable work from Antoine who has been actively working on the project for a good month πŸ’ͺ. This will bring a whole new dimension to the NodeSecure project and meet to at least some needs long requested by developers.

    -

    He wrote an article to present the tool and explain how to set it up πŸ‘€, I recommend you to read it:

    -

    β†ͺ Read article

    -

    There is still work to do, don't hesitate to come and contribute to this beautiful project which promises a lot for the future.

    -

    πŸ”— GitHub: NodeSecure/ci

    -

    NodeSecure preview

    -

    Working on security accessibility for developers within the JavaScript ecosystem is important to us.

    -

    This is why Tony Gorez has taken it upon himself to design the Preview project which will allow to scan online npm packages. We still have some difficulties to put it online but we are working on it.

    -

    The goal of the project is to highlight some of the benefits and metrics reported by the NodeSecure tools and why not make more developers sensitive to security subjects.

    -

    πŸ”— GitHub: NodeSecure/preview

    -

    NodeSecure authors

    -

    In light of the recent events with Marak Squares it is I think quite important to have some insight on the maintainers of the packages we use.

    -

    β†ͺ Read article

    -

    We must have better tools to warn developers in case of incident like Faker. But also to highlight these maintainers who also need funding.

    -

    This could also allow some developers to realize the dependence they have on certain projects and why not encourage them to contribute to help.

    -

    That's why we are working on a new package with Vincent Dhennin to optimize and fetch additional metadata for package authors.

    -

    πŸ”— GitHub: NodeSecure/authors

    -

    Our goal is to implement these improvements in future releases of Scanner. I'm excited about this because personally I like to get to know the maintainers of the packages I use.

    -

    NodeSecure RC

    -

    We are working on adding a runtime configuration for our tools (especially the CI project).

    -
    import assert from "node:assert/strict";
    -import * as RC from "@nodesecure/rc";
    -
    -const writeOpts: RC.writeOptions = {
    -  payload: { version: "2.0.0" },
    -  partialUpdate: true
    -};
    -
    -const result = (
    -  await RC.write(void 0, writeOpts)
    -).unwrap();
    -assert.strictEqual(result, void 0);
    -
    -

    This should improve the experience for many of our tools where we had a CLI with complex settings and commands or pseudo configuration within the project (like report).

    -
    -

    That's it for this article. We continue to work and listen to your various feedbacks to improve our tools.

    -

    See you soon for another article πŸ˜‰.

    -

    Best Regards, -Thomas

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/blog/securizing-your-github-org.html b/blog/securizing-your-github-org.html deleted file mode 100644 index e297b13..0000000 --- a/blog/securizing-your-github-org.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - NodeSecure - Blog - - - - - -
    -
    -
    - NodeSecure Logo -

    - NodeSecure Blog -

    -

    - Building a safer Node.js and JavaScript ecosystem -

    -

    We are a community of developers building free open source tools to secure the Node.js & JavaScript ecosystem. Our area of expertise is SCA (Software Composition Analysis).

    - -
    -
    -
    - -
    -
    -

    Securizing your GitHub org

    -

    Hello πŸ‘‹

    -

    I started open source a bit naively (like everyone I guess 😊).

    -

    But the more I progress and the more important/popular some of my projects become 😎. That's great, but at some point you have to deal with a lot of things related to security (like Vulnerability disclosure).

    -

    You start to hear and see a lot of scary stories around you 😱. Not to mention all the acronyms where you don't understand anything at first 😡 (VMT, CVE, SAST, SCA, CNA ...).

    -

    As I was working on an open source security project, I put pressure on myself to be ready. Also as a member of the Node.js Security WG I thought it was an interesting topic and that I was probably not the only one who was worried about not being up to the task πŸ˜–.

    -

    So I rolled up my sleeves and tackled the problem πŸ’ͺ. Here is my feedback/journey on how I improved the security of my NodeSecure GitHub organization.

    -
    -

    πŸ‘€ We use Node.js and JavaScript (but most recommendations are valid for other ecosystems).

    -
    -

    Security Policy and Vulnerability Disclosure

    -

    Adding a root SECURITY.md file explaining how developers and security researchers should report vulnerability is important. You don't want a security threat to be turned into a public issue (This gives you time to analyze and possibly fix before disclosure).

    -
    -

    ⚠️ If you are a developer, never report a security threat using a public GitHub issue. This is a serious mistake. This could even put your business/team at risk.

    -
    -

    I don't want to bullshit you, so let me share with you the OpenSSF guide that helped me set up my first reporting strategy: Guide to implementing a coordinated vulnerability disclosure process for open source projects.

    -

    I started from scratch by reading this guide and taking inspiration from their templates 🐀. As a small open source team we don't especially have DNS or mail servers (not even a defined Vulnerability Management Team A.K.A VMT).

    -

    I was a bit puzzled to put my personal email as I'm not alone 😟.

    -

    I quickly learned that Github added a new feature to report/create private security issue 😍. You can enable it in the Security tab (I think it's also now possible to enable it on every repositories at once).

    -

    And this is what it finally looks like: -NodeSecure SECURITY.md

    -

    Use OpenSSF scorecard

    -

    scorecard

    -

    The OSSF scorecard initiative is really good to assess your project against security best practices. I am not the first to write about this.

    -

    You can easily setup the GitHub action workflow by following those instructions.

    -

    Once configured, you will have a set of alerts available in the Security tab.

    -

    Scorecard scanning alerts

    -

    This will give you an overview of the different subjects to improve (workflows, dependencies etc). Each of these alerts contains a full description of the actions to be taken to fix the problem.

    -

    OSSF Scorecard

    -

    I have personally used these recommendations to dig and train myself. The next chapters will help you improve your score.

    -
    -

    πŸ“’ By the way NodeSecure CLI has a first-class support of the scorecard.

    -
    -

    πŸ”“ Enable branch protection

    -

    I am a bad student 😳. Almost all of my projects had no branch protection on the main / master branch πŸ™ˆ.

    -
    -

    To set up the protection, go to Settings > Branches and edit your main branch.

    -
    -

    GitHub has quite a few options on the subject 😡. If you don't know what to choose in terms of options, don't check anything (it's ok to begin βœ”οΈ).

    -

    If you want to be more restrictive, be careful because it could block you (some options are only viable in projects with many contributors/reviewers).

    -

    As far as I am concerned I often choose:

    -
      -
    • Require a pull request before merging
    • -
    • Require conversation resolution before merging
    • -
    • Require status checks to pass before merging
    • -
    -

    🐲 Workflows Hardening

    -

    I fell down when I saw all that it was necessary to know to secure workflows with GitHub actions 😲.

    - -

    Fortunately there is a great free online tool that help you by doing all the hard work (it will open a pull-request and automatically fix issues).

    -

    {% tweet https://twitter.com/fraxken/status/1617557370728767488 %}

    -

    The tool was created by StepSecurity. I had the opportunity to talk with the CEO and they listen to the maintainers which is really cool. -Thanks to them ❀️!

    -

    Configure Dependabot

    -

    It is recommended to use Dependabot for updating your dependencies and GitHub actions (yes, it also supports updating workflows in a secure way 😍).

    -

    You only need to add a .github/dependabot.yml config file. Personally I recommend a weekly interval (with a lot of projects daily is a bit horrible).

    -
    version: 2
    -updates:
    -  - package-ecosystem: github-actions
    -    directory: /
    -    schedule:
    -      interval: weekly
    -
    -  - package-ecosystem: npm
    -    directory: /
    -    schedule:
    -      interval: weekly
    -
    -

    The StepSecurity tool we have seen in the previous chapter is also capable of doing it πŸš€.

    -
    -

    Also, think to enable Dependabot alerts in the Security tab. This will allow the bot to open pull-request to fix known vulnerabilities by looking at your dependencies (referenced in package.json or others).

    -

    πŸ”¬ Adding CodeQL scanning

    -

    To enhance security even more you can add a SAST tool like CodeQL. Like scorecard it will report security scanning alert but for your codebase.

    -

    Here an example: -prototype-pollution

    -

    A great way to make sure that newly added code does not contain vulnerabilities that were obvious to detect.

    -
    -

    πŸ‘€ Note that once again StepSecurity can set up the workflow for you.

    -
    -

    πŸ“œ Enable Security advisories (and others)

    -

    Github Security tab as a lot of cool features that help you maintain the security of your project. If you have followed all my previous chapters, most of them should be enabled now.

    -

    Make sure to also enable Secret scanning alerts.

    -

    Github Security

    -

    For an organization many of these parameters can be forced on all repositories. Go to Settings > Code security and analysis. You will have the options to enable/disable all.

    -

    Github Security

    -

    πŸ’‘ OpenSSF Best Pratices program

    -

    Previously known as CII-Best-Practices, this program indicates that the project uses a set of security-focused best development practices for open source software.

    -

    So I registered my first project on the website. It was a good surprise because it allowed me to question the quality of my documentation and tests 😬.

    -

    Seeing the different levels and questions really helps you think about what you're missing (and possibly learn about the concepts you don't know about yet.. Like SBOM).

    -

    CII-Best-Practices

    -

    I am still working on completing the first step/badge for the CLI project which now has a score of 8.7 out of 10 πŸŽ‰ on the OpenSSF scorecard.

    -

    🎯 Conclusion

    -

    That's it for this article. I've covered what I've done/learned in the last couple of months. Here are some really cool additional links πŸ’ƒ:

    - -

    If you work with NPM, I invite you to read our latest article about package managers:

    -

    β†ͺ Read article

    -

    Obviously, I probably still have a lot to learn. But I hope this will help other maintainers/developers ❀️.

    -

    πŸ™ Thanks for reading me πŸ™

    - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/public/css/blog.css b/public/css/blog.css index 6e6e17b..12557d4 100644 --- a/public/css/blog.css +++ b/public/css/blog.css @@ -139,11 +139,11 @@ h1.article-title { } .article-content > pre code.language-yml::before { - content: 'YAML' + content: "YAML" } .article-content > pre code.language-bash::before { - content: 'BASH' + content: "BASH" } .article-content code { diff --git a/src/build-articles.js b/src/build-articles.js index 423067f..dc0fd5a 100644 --- a/src/build-articles.js +++ b/src/build-articles.js @@ -21,7 +21,7 @@ export function convertAllMarkdownArticles(authors) { const articles = files.map((file) => { const filePath = path.join(inputDir, file); - return generateBlogPost(filePath, outputDir); + return generateBlogPost(filePath); }); // Generate index page @@ -113,7 +113,7 @@ function parseYamlFile(content) { return { metadata: {}, content }; } - // extract frontformatter + // extract frontmatter const frontmatterLines = lines.slice(1, endLineIndex); const markdownLines = lines.slice(endLineIndex + 1);