Dev.to Security πŸ” Cybersecurity πŸ‘ 0 πŸ“– 3 min read

The Hard Part of Leaving `request` is the App Built Around It

Disclosure: I maintain request-to-axios. This is a migration guide from the perspective of someone maintaining legacy Node.js code, not an independent review of my own package. When a project uses request, replacing the

Disclosure: I maintain request-to-axios. This is a migration guide from the perspective of someone maintaining legacy Node.js code, not an independent review of my own package.

When a project uses request, replacing the dependency can look like a one-line change. The hard part usually isn't translating request.get() to axios.get(). It's finding all the assumptions accumulated around the old call: callbacks that expect (error, response, body), stream piping, formData, qs, cookies, default headers, odd redirects, and tests that depend on the response being text unless json is enabled.

A broad rewrite can turn a small security task into a risky application migration. That is why I built a compatibility wrapper around Axios: to make an incremental transition possible for common request patterns, while keeping unsupported behavior visible.

Why the Dependency Deserves Attention

The latest upstream request release is still 2.88.2. The maintainers marked the project deprecated in 2020 and say no new changes are expected. That fact alone does not mean every application is exploitable. The more useful question is what versions your install resolves and whether your code reaches an affected behavior.

On 2026-11-02, I installed [email protected] into a temporary project and ran npm audit. It resolved [email protected], [email protected], [email protected], and [email protected], alongside the deprecated request package. npm reported five vulnerable package nodes, with multiple advisories applying to some nodes.

A few examples from that graph:

  • CVE-2023-28155 is an SSRF mitigation bypass in request through 2.88.2 involving cross-protocol redirects. It matters when an application relies on URL or redirect restrictions to protect requests to internal services.
  • CVE-2025-7783 affects old form-data boundary generation. Exploitation depends on an attacker being able to observe Math.random() outputs and influence multipart content.
  • CVE-2026-12143 concerns CRLF injection through untrusted multipart field names or filenames in affected form-data versions.
  • CVE-2023-26136 is a tough-cookie prototype-pollution issue, with a specific cookie-jar configuration precondition.

There are also qs and uuid advisories in the resolved tree. Their practical impact depends on the application's own parse/stringify flow or UUID API use. A dependency audit is a signal to investigate, not proof that a particular endpoint is exploitable.

Why Not Just Translate Every Call to Axios?

A direct rewrite changes more than syntax. Axios returns a promise and a response object with data; request commonly uses a callback and passes the body as a separate argument. The projects may also differ on redirects, streaming, cookie jars, timeout details, form serialization, and error handling. Those differences are where the regression work hides.

For a large legacy codebase, the safer sequence is usually:

  1. Inventory the actual options and helper patterns in use.
  2. Add characterization tests around important request and response behavior.
  3. Replace the transport behind the current import name.
  4. Migrate unsupported edge cases separately, with explicit tests.

For a gradual trial, npm supports an alias:

npm install request@npm:request-to-axios

Existing require('request') statements can continue resolving while the installed implementation comes from the wrapper. A representative callback call looks familiar:

const request = require('request');

request.get({
  url: 'https://api.example.test/items',
  qs: { page: 2 },
  json: true
}, (error, response, body) => {
  if (error) return console.error(error);
  console.log(response.statusCode, body);
});

A Compatibility Layer, Not a Security Guarantee

The wrapper covers common callback/stream usage, method helpers, defaults, query strings, JSON, URL-encoded and multipart forms, immediate Basic/Bearer auth, redirects, a small in-memory cookie jar, TLS settings, and common transport options. It does not implement OAuth/Hawk/AWS/HTTP signing, HAR import, digest retries, multipart/related, or exact legacy redirect semantics. The cookie jar is deliberately limited and does not replace a full browser cookie implementation.

That distinction matters. Migrating off an unmaintained client removes one set of risks; it does not make an application secure by itself. Review redirect destinations, validate user-controlled URLs, keep TLS verification enabled, and run npm audit on the resulting dependency graph. Add tests for the options your service actually uses before deploying the alias.

The package and its current compatibility notes are on npm and GitHub. If a legacy option is important to your migration, check the documented limits first and open an issue with a minimal example.

πŸ“° Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.