Update dependency axios to v1.18.0 [SECURITY]#2452
Open
renovate[bot] wants to merge 1 commit into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
1.16.0→1.18.0Axios: Prototype pollution auth subfields can inject Basic auth
GHSA-xj6q-8x83-jv6g
More information
Details
Summary
Axios versions after the
GHSA-q8qp-cvcw-x6jjfix still contain prototype-pollution read-side gadgets in Basic auth subfield handling. If a host application is already affected by prototype pollution and then makes an axios request with an ownauthobject that omitsusernameorpassword, axios reads inheritedObject.prototype.usernameandObject.prototype.passwordvalues and uses them to construct an outboundAuthorization: Basic ...header.This does not mean axios itself pollutes prototypes. Exploitation requires a separate prototype-pollution primitive in the host process, plus an axios call pattern such as
auth: opts.auth || {}.Impact
An attacker who can pollute
Object.prototype.usernameand/orObject.prototype.passwordcan influence the Basic auth header on affected axios requests that pass an empty or partial ownauthobject.The practical impact is outbound request tampering. The attacker can inject attacker-chosen Basic auth credentials, replace an existing
Authorizationheader because axios removes it whenauthis used, or cause downstream authorization failures.This should not be described as automatic credential exfiltration. In the minimal reproduced case, the Basic auth values are attacker-controlled values, not secrets read from axios. Credential disclosure requires an additional application-specific condition, such as a request destination observable by the attacker and a partial real auth object with a missing polluted subfield.
Affected Functionality
Affected functionality:
lib/adapters/http.js.lib/helpers/resolveConfig.js.config.authis an own object butusernameand/orpasswordare absent own properties.Unaffected or not accepted as core impact:
authobject aftermergeConfig().auth.usernameandauth.passwordvalues.params/paramsSerializerafter the null-prototypemergeConfig()hardening.paramsSerializerfunctions from JSON-only prototype pollution, because JSON pollution cannot create functions. If attacker-controlled code can install functions in the process, that is outside axios’ runtime boundary.Technical Details
mergeConfig()returns a null-prototype top-level config object, which prevents top-level reads such asconfig.authfrom inheriting polluted values. However, nested plain objects returned byutils.merge()still haveObject.prototype.In
lib/adapters/http.js, axios correctly reads the top-levelauthvalue throughown('auth'), but then reads subfields directly:If the caller passes auth: {} and Object.prototype.username/password are polluted, those direct subfield reads walk the prototype chain.
The same pattern exists in
lib/helpers/resolveConfig.js:The fix should guard
usernameandpasswordwithutils.hasOwnProp, matching the proxy-auth pattern already used elsewhere.Proof of Concept of Attack
Safe local PoC against published
axios@1.16.1:Expected output:
{ "url": "/api", "authorization": "Basic dmljdGltLXVzZXI6dmljdGltLXBhc3N3b3JkLWxlYWtlZA==" }The base64 value decodes to
victim-user:victim-password-leaked.Workarounds
Avoid passing empty or partial
authobjects. Only setauthwhen the application has own username and password values.Applications that merge untrusted input should filter
__proto__,constructor, andprototype, and should read optional user options with own-property checks rather thanopts.auth || {}.Where a wrapper must materialize optional auth, use a null-prototype object or explicitly copy only own fields.
Original Report
Summary
After GHSA-q8qp-cvcw-x6jj / PR #10779 (shipped in
v1.15.2) and the further proxy-side hardening inPR #10833 (merged 2026-05-02), the top-level
config.authand the proxy authsub-fields are correctly read viautils.hasOwnProp. The regular request auth sub-fields (config.auth.usernameandconfig.auth.password) and theconfig.params/config.paramsSerializerreads insideresolveConfig.jsare still unguarded against a pollutedObject.prototype.When a polluted host process makes an axios call with the common "optional override" pattern (
auth: opts.auth || {}— an empty own{}), the sub-field readsconfigAuth.usernameandconfigAuth.passwordwalk the prototype chain and return the attacker-controlled values. Same forparamsandparamsSerializer. The outbound HTTP request then carries an attacker-chosenAuthorization: Basic <base64>header and an attacker-chosen querystring, leaking credentials and exfiltrating data to whichever host the request goes to (often attacker-influenced too — i.e. the amplifier is wired into many credential-stuffing chains).Reproduces against
axiosmainHEAD (34723be, dated 2026-05-24)as well as the released
v1.16.1.Details
Three still-unguarded read sites on
mainHEAD:(1)
lib/adapters/http.jslines 737–740 (Node http adapter):own('auth')correctly applieshasOwnPropto the top-levelauthkey. But once
configAuthis the empty object the caller passed(
auth: {}),configAuth.usernamewalks the prototype chain andpicks up
Object.prototype.username.Contrast with the proxy-auth path that PR #10833 fixed (lines 322–324):
This is the exact pattern needed at lines 739–740 too.
(2)
lib/helpers/resolveConfig.jslines 50 + 68 (xhr/fetch adapter shared resolver):Same shape — top-level guarded, sub-fields walk prototype.
(3)
lib/helpers/resolveConfig.jslines 58–59 (params + paramsSerializer):This third site is already proposed for fix in open PR #10922 by @Mohammad-Faiz-Cloud-Engineer (status: open, currently mergeable: false). That PR's
own('params')/own('paramsSerializer')change is exactly correct; this report flags the auth sub-field sites that PR #10922 does not cover.PoC
This PoC contains zero direct
Object.prototype.x = ywrites. Thepollution flows entirely from attacker-shaped JSON through a real
deep-merge utility (
defaults-deep@0.2.4, ~50k weekly downloads,still walks
constructor.prototype). A hand-rolled deep merge —the canonical insecure backend pattern — exhibits the same pollution
via
__proto__and is more common in real codebases than any namedutility.
Reproduction:
Captured output (verified against released
1.16.1AND againstmainat34723be, 2026-05-24):{ "method": "GET", "url": "/api/widget?leak=ATTACKER_QUERY_TOKEN", "authorization": "Basic dmljdGltLXVzZXI6dmljdGltLXBhc3N3b3JkLWxlYWtlZA==" }dmljdGltLXVzZXI6dmljdGltLXBhc3N3b3JkLWxlYWtlZA==base64-decodes tovictim-user:victim-password-leaked. The querystring carries?leak=ATTACKER_QUERY_TOKEN, which can be a full data-exfil channelin real chains (CSRF token, session cookie via
req.headers, etc.).Impact
request. If the request URL is attacker-influenced too (common in
webhook/oauth-callback patterns), the credentials flow directly to
the attacker. If not, they flow to the legitimate destination but
expose victim credentials in any logs / proxies along the path.
params/paramsSerializer. WithparamsSerializerpolluted to an attackerfunction, axios will execute that function with each
paramsinvocation — same-process code execution from a pollution primitive.
precondition is "deep-merges attacker JSON into a config object
without
__proto__/constructorfiltering, then uses the empty-fallback wrapper
auth: opts.auth || {}/params: opts.params || {}."Both halves are very common in real codebases (we tested
defaults-deep, hand-rolled merges, and several lodash-familyutilities; many still pollute).
Attributes — amplifier sink).
Proposed fix
Two-line change in
http.js, matching the proxy-auth pattern PR#10833 already established:
Same pattern in
resolveConfig.js:The
params/paramsSerializerhalf is already handled by openPR #10922's
own('params')/own('paramsSerializer')change — thatPR should be rebased / merged.
Relationship to recent prototype-pollution work
Same vulnerability class as the existing public hardening, just at
sub-field granularity:
mergeConfigdirect-key reads. Fixed in v1.15.2.mergeDirectKeysin→hasOwnProp. Fixed in v1.15.x.auth.username/passwordsub-fields. Fixed post-1.16.1.formDataToJSONdefense-in-depth. Fixed post-1.16.1.socketPathguard. Merged 2026-05-24.params/paramsSerializerown()guard. Proposed; not merged.This report adds: regular-request
auth.username/auth.passwordsub-field reads in both the http adapter (lines 737–740) and
resolveConfig.js (line 68).
Reporter notes
findings. The bundle's public tracking entry (without the working
exploit chain) is at
georgian-io/package-runtime-security-findings/advisories/AXIOS-002-prototype-pollution-config-fields.md.prefer to fold this into open PR #10922 (whose author is actively
responding to comments), please let me know and I'll coordinate.
requires a separate prototype-pollution primitive elsewhere in the
host process. That's how the existing GHSA-q8qp-cvcw-x6jj and
PR #10833 were framed too, so the precedent for "in-scope as a
hardening fix" is established.
Severity
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:L/SC:N/SI:N/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Axios: NO_PROXY bypass for 0.0.0.0 local addresses in axios
GHSA-f4gw-2p7v-4548
More information
Details
Summary
Axios versions containing
lib/helpers/shouldBypassProxy.jsdo not treat0.0.0.0as a local address when evaluatingNO_PROXYrules. In Node.js applications that useHTTP_PROXYorHTTPS_PROXYtogether withNO_PROXY=localhost,127.0.0.1,::1or similar, a request tohttp://0.0.0.0:<port>/can be routed through the configured proxy instead of bypassing it.The issue is exploitable when an attacker can influence the axios request URL or a followed redirect target, and when the proxy can reach or relay
0.0.0.0to local services. This is a Node.js runtime proxy-routing issue, not a browser, install-time, or development-tooling issue.Impact
Applications are affected when all of the following are true:
HTTP_PROXYorHTTPS_PROXY.NO_PROXYentries such aslocalhost,127.0.0.1, or::1to keep local traffic out of the proxy path.0.0.0.0and can reach the local destination.For plain HTTP targets, the proxy can receive the full request URL, headers, and body, and may be able to observe the local service response. HTTPS targets are less exposed because axios uses CONNECT tunneling in current versions.
Affected Functionality
Affected functionality is limited to environment-derived proxy selection in the Node HTTP adapter:
lib/adapters/http.jscallsgetProxyForUrl(location)and thenshouldBypassProxy(location)before applying the proxy.lib/helpers/shouldBypassProxy.jsnormalizes and comparesNO_PROXYentries.config.proxyremains trusted caller configuration.Technical Details
lib/helpers/shouldBypassProxy.jsdefines local loopback equivalence throughisLoopback(). The current implementation recognizeslocalhost, IPv4127.0.0.0/8, IPv6::1, and IPv4-mapped loopback forms, but it does not include0.0.0.0.At
lib/helpers/shouldBypassProxy.js:176, axios treats two hosts as matching when both are considered loopback:Because
isLoopback('0.0.0.0')returnsfalse,NO_PROXY=localhost,127.0.0.1,::1does not matchhttp://0.0.0.0:<port>/.lib/adapters/http.js:185-193then applies the environment proxy.Proof of Concept of Attack
Expected safe behavior: both
127.0.0.1and0.0.0.0bypass the proxy when theNO_PROXYpolicy is intended to cover local destinations.Observed behavior:
127.0.0.1bypasses the proxy, while0.0.0.0is sent through the proxy.Workarounds
0.0.0.0explicitly toNO_PROXYwhere local addresses must bypass proxies.0.0.0.0in application URL validation before calling axios.proxy: falseon axios requests that must never use environment proxies.0.0.0.0, loopback, link-local, and internal address ranges.Original Report
Summary
axiosversions 1.15.0–1.16.1 contain an incomplete loopback-address check inlib/helpers/shouldBypassProxy.js. TheisLoopback()function correctly identifies127.0.0.0/8and::1as loopback addresses but does not recognise0.0.0.0— the IPv4 unspecified address, which routes to the local machine on Linux and macOS.An attacker who controls a URL passed to axios can use
http://0.0.0.0/<path>to bypass proxy-based SSRF filtering that the application relies upon.Details
Affected versions
>= 1.15.0, <= 1.16.1The vulnerability was introduced in v1.15.0 when the
shouldBypassProxyhelper was added as a security improvement (PR #10661).Root cause
File:
lib/helpers/shouldBypassProxy.jsWorkarounds
For
axios >=1.15.1, setmaxRedirects: 0on affected HTTP/2 streamed upload calls. HTTP/2 redirects are not currently supported by the axios HTTP/2 adapter, so this is a practical per-call mitigation for this path.For earlier affected versions, pre-limit the stream with a byte-counting transform before passing it to axios, reject oversized uploads before forwarding them, or avoid
httpVersion: 2for untrusted streamed uploads.### SummaryOn Node.js, axios's maxBodyLength is documented as a hard cap on outbound request bodies. For streamed uploads sent over httpVersion: 2, axios never enforces this cap: the entire body is transmitted regardless of size. Severity: medium.
Original Report
Details
In lib/adapters/http.js, transport selection is unconditional for HTTP/2:
http.js Lines 937-956
maxBodyLength is then stored on the request options:
http.js Lines 958-963
…but options.maxBodyLength is only honored by the follow-redirects transport. Node's native http2.request does not read it. The only stream-level cap in this file is the byte-counting Transform wrapper for streamed uploads, which is gated on config.maxRedirects === 0:
http.js Lines 1270-1304
For the HTTP/2 path, neither branch fires: the http2Transport is always selected, and follow-redirects is never used. The byte-counting transform also doesn't fire unless the caller happens to pin maxRedirects: 0. As a result, uploadStream.pipe(req) streams the full body into the HTTP/2 request unbounded.
PoC
Impact
Severity
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:LReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Axios form serializer maxDepth bypass via {} metatoken
GHSA-hcpx-6fm6-wx23
More information
Details
Summary
Axios versions in the fixed lines for GHSA-62hf-57xw-28j9 still contain an incomplete depth-limit bypass in
lib/helpers/toFormData.js. When serializing an object with a top-level key ending in{}, axios callsJSON.stringify()on that value before theformSerializer.maxDepthguard can inspect the nested structure.An attacker who can control object keys and nested values passed by an application into axios form or parameter serialization can trigger a raw
RangeError: Maximum call stack size exceeded, causing a denial of service in the affected request path.Impact
The impact is availability only. No confidentiality or integrity impact was confirmed.
Server-side applications are the primary concern when they accept user-controlled input and pass it into axios as
dataorparamsformultipart/form-data,application/x-www-form-urlencoded, or default parameter serialization. Browser impact is limited to the page or request context unless the application builds a broader failure mode around the thrown exception.The attack requires control over a top-level object key ending in
{}and a deeply nested object value. The optionformSerializer.metaTokens: falseis not a workaround because it only changes the emitted key name; the value is still stringified.Affected Functionality
Affected paths include:
lib/helpers/toFormData.jswhen a top-level key ends with{}.lib/helpers/toURLEncodedForm.js, which delegates tohelpers.defaultVisitor.lib/helpers/AxiosURLSearchParams.js, used by default params serialization.lib/defaults/index.jswhen object data is serialized asmultipart/form-dataorapplication/x-www-form-urlencoded.Unaffected paths include:
FormDataorURLSearchParamsvalues that axios does not walk withtoFormData.paramsSerializer.serializeimplementations that do not call axiostoFormData.{}deeply nested values intoFormData, which hitERR_FORM_DATA_DEPTH_EXCEEDEDas intended.Technical Details
In
lib/helpers/toFormData.js,defaultVisitor()handles top-level keys ending in{}before recursive traversal:The depth guard is in
build():For
{}metatoken values,build()only sees the top-level property. The nested value is handed directly to nativeJSON.stringify(), which recurses internally and can throwRangeErrorbefore axios emits the intendedAxiosError.Proof of Concept of Attack
Safe local PoC with no network I/O:
Expected fixed behavior is an
AxiosErrorwith codeERR_FORM_DATA_DEPTH_EXCEEDED.Workarounds
Reject or depth-limit untrusted objects before passing them to axios serialization.
Strip or reject top-level keys ending in
{}from untrusted objects when using axios form serialization.For query parameters, use a custom
paramsSerializer.serializethat enforces a depth limit.For form bodies, construct
FormDataorURLSearchParamsmanually after validating input depth.Original Report
Summary
The
maxDepth=100guard added in axios 1.15.0 to fix GHSA-62hf-57xw-28j9 lives inside thebuild()recursion inlib/helpers/toFormData.js. The default visitor atlib/helpers/toFormData.js:166-170still has a top-level shortcut that callsJSON.stringify(value)whenever a key ends in'{}', beforebuild()ever sees the nested value. JSON.stringify on a deeply nested object stack-overflows withRangeError: Maximum call stack size exceeded, which propagates synchronously out of the axios call. The exact attacker-data flow that the original advisory described (proxy-style code that forwards client JSON intoaxios({ data, params })) still crashes the process at depth ~3000 on a default Node.js stack, despite v1.16.0 being patched.Details
Affected: axios 1.15.0 - 1.16.0 (every released version that carries the GHSA-62hf-57xw-28j9 fix). The bug is reachable from any code path that hits
toFormData, which includes:axios.post(url, data, { headers: { 'content-type': 'application/x-www-form-urlencoded' } })->defaults.transformRequest->toURLEncodedForm(data)->toFormDataaxios.post(url, data, { headers: { 'content-type': 'multipart/form-data' } })-> same path viatoFormDataaxios.get(url, { params })->buildURL->new AxiosURLSearchParams(params)->toFormDataVulnerable code,
lib/helpers/toFormData.js:build()later does enforcemaxDepth:The
'{}'shortcut runs indefaultVisitor, which is invoked from insidebuild()for top-level keys (the!pathclause at line 165 means the shortcut only triggers at top level, wherepathisundefined). At that pointdepth === 0and the maxDepth check has already passed; the recursion-aware guard never sees the nested value becausedefaultVisitorreassignsvalue = JSON.stringify(value)and returns the rendered string straight toformData.append. JSON.stringify itself is recursive in V8 and stack-overflows on deeply nested objects, throwingRangeErrorsynchronously.The behaviour is independent of the
metaTokensoption: line 168 only changes whether'{}'stays on the key name, line 170 stringifies regardless.toURLEncodedForm's wrapper visitor inlib/helpers/toURLEncodedForm.js:11-14falls through to the samedefaultVisitor, so the form-encoded path is also affected.The attacker payload is a single top-level key ending in
'{}'whose value is a nested object. The keys themselves do not have to be deep, so the payload is small to send (a few KB of{"x":{"x":...}}produces enough nesting to overflow). The original advisory's threat model -- a server that forwardsreq.bodyorreq.queryinto axios -- is unchanged:The error is not an
AxiosError; it is a rawRangeErrorthrown from the stringifier, so handlers that look forerr.code === 'ERR_FORM_DATA_DEPTH_EXCEEDED'(the documented signal that the maxDepth guard fired) do not see it. Synchronous startup paths or worker threads still take the whole process down.The fix is to also depth-limit (or pre-walk) the value before calling
JSON.stringifyon line 170, or to remove the top-level'{}'shortcut and rely on the depth-checkedbuild()recursion to handle it. A minimal patch that preserves observable behaviour for legal payloads:if (utils.endsWith(key, '{}')) { // eslint-disable-next-line no-param-reassign key = metaTokens ? key : key.slice(0, -2); + // Reject objects that would exceed maxDepth before handing to JSON.stringify, + // which is recursive in V8 and stack-overflows on deeply nested input. + (function checkDepth(v, d) { + if (d > maxDepth) { + throw new AxiosError( + 'Object is too deeply nested (' + d + ' levels). Max depth: ' + maxDepth, + AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED + ); + } + if (v && typeof v === 'object') { + for (const k in v) checkDepth(v[k], d + 1); + } + })(value, 0); // eslint-disable-next-line no-param-reassign value = JSON.stringify(value); }(The recursion in
checkDepthitself is bounded bymaxDepth, so it cannot itself overflow.)PoC
Reproduces against a clean clone of
axios/axiosat v1.16.0 withnpm installalready run.targets/axios/poc_jsonstringify_dos.mjsis the script:3/3 runs reproduce the same
RangeErroronaxios@1.16.0with Node.js 24:safeAdapteris a stub that returns a fake response, so the crash is provably inside axios's serialization layer, not in HTTP I/O. Removing the'{}'suffix from the key and re-running gives the expectedAxiosError: Object is too deeply nested ... ERR_FORM_DATA_DEPTH_EXCEEDEDfrom the maxDepth guard, confirming the fix is wired correctly elsewhere -- it just does not cover this branch.Crash threshold on a default-stack Node.js process is roughly depth 2500-3000; 8000 is comfortably above that, and the payload is a few KB.
Impact
A remote, unauthenticated attacker who can influence an object that the application passes to axios as request
dataorparamstriggers an uncaughtRangeErrorfrom inside the synchronousJSON.stringifycall indefaultVisitor. In server-side applications that proxy or re-forward client JSON through axios -- the same threat model that motivated GHSA-62hf-57xw-28j9 -- this crashes the request handler and, in worker/cluster setups, the whole process. The previously shippedmaxDepthguard does not stop it because the'{}'suffix path bypassesbuild()entirely. Same severity class as the original advisory (CWE-674 Uncontrolled Recursion, network-reachable DoS); the only difference is the attacker has to suffix one of their object keys with'{}'to land on the unguarded code path.Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Axios Node HTTP adapter can use an inherited proxy after interceptor config cloning
GHSA-gcfj-64vw-6mp9
More information
Details
Summary
Axios’ Node.js HTTP adapter can route requests through an attacker-controlled proxy when
Object.prototype.proxyis polluted and request configuration is materialized as a regular object before dispatch.Recent axios releases harden merged request config by creating a null-prototype object. However, request interceptors run after that merge and may return a replacement config. A common immutable interceptor pattern such as
{...config}orObject.assign({}, config)converts the hardened config back into a normal object. Axios then dispatches that object without re-hardening it, and the Node HTTP adapter readsconfig.proxythrough the prototype chain.Impact
In a Node.js deployment using the HTTP adapter, an attacker who can trigger prototype pollution elsewhere in the process can route affected HTTP requests through an attacker-controlled proxy.
The highest confirmed impact is for plaintext HTTP requests. The proxy can observe explicit
Authorizationheaders, axios-generated Basic auth fromconfig.auth, request method, absolute URL,Host, and request body content. The proxy can also return its own response to axios for the affected request.This does not establish browser impact. It also does not establish HTTPS header or body disclosure under normal TLS validation.
Affected Functionality
Affected functionality is limited to axios requests that use the Node.js HTTP adapter, including default Node usage when the HTTP adapter is selected and explicit
adapter: 'http'usage.The relevant configuration path is
config.proxyin the Node HTTP adapter. The hardened-bypass path requires a request interceptor such as:Unaffected or mitigating conditions include browser adapters, the Node fetch adapter, no polluted
Object.prototype.proxy, an ownproxy: falseor safe ownproxyvalue on the config, and hardened releases where interceptors return the original null-prototype config instead of a regular object clone.Technical Details
lib/core/mergeConfig.jscreates a null-prototype merged config and uses own-property reads for merged values. This is intended to prevent pollutedObject.prototypevalues from affecting config behavior.lib/core/Axios.jsruns request interceptors after the merge. In both the asynchronous and synchronous interceptor paths, axios passes the interceptor-returned config into dispatch.lib/core/dispatchRequest.jsaccepts that returned config, transforms request data, selects the adapter, and calls the adapter without re-hardening or re-normalizing the config.lib/adapters/http.jsuses own-property reads for several sensitive fields, but the initial proxy dispatch path still passesconfig.proxydirectly intosetProxy(). If an interceptor returned a regular object,config.proxycan resolve to inheritedObject.prototype.proxy.Proof of Concept of Attack