CVE-2023-28155
Description
The Request package through 2.88.1 for Node.js allows a bypass of SSRF mitigations via an attacker-controller server that does a cross-protocol redirect (HTTP to HTTPS, or HTTPS to HTTP). NOTE: This vulnerability only affects products that are no longer supported by the maintainer.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
The Request package for Node.js before 3.0.0 allows SSRF bypass via cross-protocol redirects due to insecure redirect handling.
Vulnerability
Description CVE-2023-28155 resides in the Request package for Node.js, up to version 2.88.1. The library, while deprecated by its original maintainer [1], remains widely used. The core issue is the default acceptance of cross-protocol redirects (HTTP→HTTPS or HTTPS→HTTP) without proper validation. This allows an attacker-controlled server to redirect a request initiated by the library to a different protocol, effectively bypassing Server-Side Request Forgery (SSRF) mitigations that rely on protocol validation [2].
Exploitation
Exploitation is straightforward: an attacker hosts a server that initially responds to a legitimate request (e.g., to an allowed HTTP endpoint) but subsequently returns a redirect to a different protocol (e.g., HTTPS). The Request package, by default, follows this redirect without checking if the protocol change is safe. The attacker does not need authentication or special privileges beyond the ability to serve a malicious redirect from a controlled host [2].
Impact
Successful exploitation allows an attacker to force the server-side application to make requests to arbitrary endpoints, potentially including internal services or those on different protocols that would otherwise be blocked by SSRF filters. This can lead to data exfiltration, internal network scanning, or further exploitation of internal systems [2]. The vulnerability is particularly dangerous because it bypasses common SSRF defenses that check only the initial request protocol.
Mitigation
The vulnerability is addressed in version 3.0.0 of the Request package (maintained as a fork by cypress-io) by introducing an allowInsecureRedirect option that defaults to false [3][4]. Users are strongly advised to upgrade to version 3.0.0 or later, or migrate to an alternative HTTP client library. The original package has been fully deprecated since February 2020 and will not receive any further patches [1].
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
requestnpm | <= 2.88.2 | — |
@cypress/requestnpm | < 3.0.0 | 3.0.0 |
Affected products
53- Node.js/Requestdescription
- osv-coords52 versionspkg:apk/chainguard/kubeflow-pipelinespkg:apk/chainguard/nodejs-14pkg:apk/chainguard/opensearch-dashboards-2pkg:apk/chainguard/opensearch-dashboards-2-alerting-dashboards-pluginpkg:apk/chainguard/opensearch-dashboards-2-anomaly-detection-dashboards-pluginpkg:apk/chainguard/opensearch-dashboards-2-compatpkg:apk/chainguard/opensearch-dashboards-2-configpkg:apk/chainguard/opensearch-dashboards-2-dashboards-mapspkg:apk/chainguard/opensearch-dashboards-2-dashboards-notificationspkg:apk/chainguard/opensearch-dashboards-2-dashboards-observabilitypkg:apk/chainguard/opensearch-dashboards-2-dashboards-query-workbenchpkg:apk/chainguard/opensearch-dashboards-2-dashboards-reportingpkg:apk/chainguard/opensearch-dashboards-2-dashboards-search-relevancepkg:apk/chainguard/opensearch-dashboards-2-dashboards-visualizationspkg:apk/chainguard/opensearch-dashboards-2-fipspkg:apk/chainguard/opensearch-dashboards-2-fips-alerting-dashboards-pluginpkg:apk/chainguard/opensearch-dashboards-2-fips-anomaly-detection-dashboards-pluginpkg:apk/chainguard/opensearch-dashboards-2-fips-configpkg:apk/chainguard/opensearch-dashboards-2-fips-dashboards-mapspkg:apk/chainguard/opensearch-dashboards-2-fips-dashboards-notificationspkg:apk/chainguard/opensearch-dashboards-2-fips-dashboards-observabilitypkg:apk/chainguard/opensearch-dashboards-2-fips-dashboards-query-workbenchpkg:apk/chainguard/opensearch-dashboards-2-fips-dashboards-reportingpkg:apk/chainguard/opensearch-dashboards-2-fips-dashboards-search-relevancepkg:apk/chainguard/opensearch-dashboards-2-fips-dashboards-visualizationspkg:apk/chainguard/opensearch-dashboards-2-fips-index-management-dashboards-pluginpkg:apk/chainguard/opensearch-dashboards-2-fips-ml-commons-dashboardspkg:apk/chainguard/opensearch-dashboards-2-fips-security-analytics-dashboards-pluginpkg:apk/chainguard/opensearch-dashboards-2-fips-security-dashboards-pluginpkg:apk/chainguard/opensearch-dashboards-2-index-management-dashboards-pluginpkg:apk/chainguard/opensearch-dashboards-2-ml-commons-dashboardspkg:apk/chainguard/opensearch-dashboards-2-security-analytics-dashboards-pluginpkg:apk/chainguard/opensearch-dashboards-2-security-dashboards-pluginpkg:apk/wolfi/kubeflow-pipelinespkg:apk/wolfi/opensearch-dashboards-2pkg:apk/wolfi/opensearch-dashboards-2-alerting-dashboards-pluginpkg:apk/wolfi/opensearch-dashboards-2-anomaly-detection-dashboards-pluginpkg:apk/wolfi/opensearch-dashboards-2-compatpkg:apk/wolfi/opensearch-dashboards-2-configpkg:apk/wolfi/opensearch-dashboards-2-dashboards-mapspkg:apk/wolfi/opensearch-dashboards-2-dashboards-notificationspkg:apk/wolfi/opensearch-dashboards-2-dashboards-observabilitypkg:apk/wolfi/opensearch-dashboards-2-dashboards-query-workbenchpkg:apk/wolfi/opensearch-dashboards-2-dashboards-reportingpkg:apk/wolfi/opensearch-dashboards-2-dashboards-search-relevancepkg:apk/wolfi/opensearch-dashboards-2-dashboards-visualizationspkg:apk/wolfi/opensearch-dashboards-2-index-management-dashboards-pluginpkg:apk/wolfi/opensearch-dashboards-2-ml-commons-dashboardspkg:apk/wolfi/opensearch-dashboards-2-security-analytics-dashboards-pluginpkg:apk/wolfi/opensearch-dashboards-2-security-dashboards-pluginpkg:npm/%40cypress/requestpkg:npm/request
< 2.14.3-r3+ 51 more
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 14.21.3-r1
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 2.19.1-r0
- (no CPE)range: < 3.0.0
- (no CPE)range: <= 2.88.2
Patches
1c5bcf21d40fbfeat: Add allowInsecureRedirect option
7 files changed · +26 −3
lib/redirect.js+5 −1 modified@@ -14,6 +14,7 @@ function Redirect (request) { this.redirects = [] this.redirectsFollowed = 0 this.removeRefererHeader = false + this.allowInsecureRedirect = false } Redirect.prototype.onRequest = function (options) { @@ -40,6 +41,9 @@ Redirect.prototype.onRequest = function (options) { if (options.followOriginalHttpMethod !== undefined) { self.followOriginalHttpMethod = options.followOriginalHttpMethod } + if (options.allowInsecureRedirect !== undefined) { + self.allowInsecureRedirect = options.allowInsecureRedirect + } } Redirect.prototype.redirectTo = function (response) { @@ -113,7 +117,7 @@ Redirect.prototype.onResponse = function (response, callback) { request.uri = url.parse(redirectTo) // handle the case where we change protocol from https to http or vice versa - if (request.uri.protocol !== uriPrev.protocol) { + if (request.uri.protocol !== uriPrev.protocol && self.allowInsecureRedirect) { delete request.agent }
README.md+1 −0 modified@@ -707,6 +707,7 @@ The first argument can be either a `url` or an `options` object. The only requir - `followOriginalHttpMethod` - by default we redirect to HTTP method GET. you can enable this property to redirect to the original HTTP method (default: `false`) - `maxRedirects` - the maximum number of redirects to follow (default: `10`) - `removeRefererHeader` - removes the referer header when a redirect happens (default: `false`). **Note:** if true, referer header set in the initial request is preserved during redirect chain. +- `allowInsecureRedirect` - allows cross-protocol redirects (HTTP to HTTPS and vice versa). **Warning:** may lead to bypassing anti SSRF filters (default: `false`) ---
tests/test-httpModule.js+1 −1 modified@@ -70,7 +70,7 @@ function runTests (name, httpModules) { tape(name, function (t) { var toHttps = 'http://localhost:' + plainServer.port + '/to_https' var toPlain = 'https://localhost:' + httpsServer.port + '/to_plain' - var options = { httpModules: httpModules, strictSSL: false } + var options = { httpModules: httpModules, strictSSL: false, allowInsecureRedirect: true } var modulesTest = httpModules || {} clearFauxRequests()
tests/test-redirect-auth.js+1 −0 modified@@ -18,6 +18,7 @@ request = request.defaults({ user: 'test', pass: 'testing' }, + allowInsecureRedirect: true, rejectUnauthorized: false })
tests/test-redirect-complex.js+1 −0 modified@@ -67,6 +67,7 @@ tape('lots of redirects', function (t) { request({ url: (i % 2 ? s.url : ss.url) + '/a', headers: { 'x-test-key': key }, + allowInsecureRedirect: true, rejectUnauthorized: false }, function (err, res, body) { t.equal(err, null)
tests/test-redirect.js+14 −1 modified@@ -445,7 +445,8 @@ tape('http to https redirect', function (t) { hits = {} request.get({ uri: require('url').parse(s.url + '/ssl'), - rejectUnauthorized: false + rejectUnauthorized: false, + allowInsecureRedirect: true }, function (err, res, body) { t.equal(err, null) t.equal(res.statusCode, 200) @@ -454,6 +455,18 @@ tape('http to https redirect', function (t) { }) }) +tape('http to https redirect should fail without the explicit "allowInsecureRedirect" option', function (t) { + hits = {} + request.get({ + uri: require('url').parse(s.url + '/ssl'), + rejectUnauthorized: false + }, function (err, res, body) { + t.notEqual(err, null) + t.equal(err.code, 'ERR_INVALID_PROTOCOL', 'Failed to cross-protocol redirect') + t.end() + }) +}) + tape('should have referer header by default when following redirect', function (t) { request.post({ uri: s.url + '/temp',
tests/test-tunnel.js+3 −0 modified@@ -356,6 +356,7 @@ function addTests () { 'https->http over http, tunnel=true', { url: ss.url + '/redirect/http', + allowInsecureRedirect: true, proxy: s.url, tunnel: true }, @@ -372,6 +373,7 @@ function addTests () { 'https->http over http, tunnel=false', { url: ss.url + '/redirect/http', + allowInsecureRedirect: true, proxy: s.url, tunnel: false }, @@ -388,6 +390,7 @@ function addTests () { 'https->http over http, tunnel=default', { url: ss.url + '/redirect/http', + allowInsecureRedirect: true, proxy: s.url }, [
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
13- github.com/advisories/GHSA-p8p7-x288-28g6ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-28155ghsaADVISORY
- doyensec.com/resources/Doyensec_Advisory_RequestSSRF_Q12023.pdfghsaWEB
- github.com/cypress-io/request/blob/master/lib/redirect.jsghsaWEB
- github.com/cypress-io/request/commit/c5bcf21d40fb61feaff21a0e5a2b3934a440024fghsaWEB
- github.com/cypress-io/request/pull/28ghsaWEB
- github.com/cypress-io/request/releases/tag/v3.0.0ghsaWEB
- github.com/github/advisory-database/pull/2500ghsaWEB
- github.com/request/request/blob/master/lib/redirect.jsghsaWEB
- github.com/request/request/issues/3442ghsaWEB
- github.com/request/request/pull/3444ghsaWEB
- security.netapp.com/advisory/ntap-20230413-0007ghsaWEB
- security.netapp.com/advisory/ntap-20230413-0007/mitre
News mentions
0No linked articles in our index yet.