[Bug]: ABS crashes when fetching podcast RSS-feed #1883

Closed
opened 2026-04-25 00:00:54 +02:00 by adam · 5 comments
Owner

Originally created by @ScuttleSE on GitHub (Apr 13, 2024).

Describe the issue

A little background... I wrote a short python-script to generate a XML-feed from a folder of files. Used a few different online RSS-feed validators to make sure it was actually "legit".

I put up the file on a website only accessible from inside my network. Trying to add that URL in ABS crashes ABS.
If I put the file on a internet-facing webserver, it seems to work

curl:ing the url to the xml-file from inside the ABS-container works fine

This is the errormessage I get

[2024-04-13 08:51:45.873] DEBUG: [podcastUtils] getPodcastFeed for "https://cronjobs.example.se/filter/podcast.xml" (podcastUtils.js:229)
[2024-04-13 08:51:45.881] FATAL: [Server] Uncaught exception origin: uncaughtException, error: Error [ERR_INTERNAL_ASSERTION]: This is caused by either a bug in Node.js or incorrect usage of Node.js internals.
Please open an issue with this stack trace at https://github.com/nodejs/node/issues

    at assert (node:internal/assert:14:11)
    at internalConnect (node:net:1037:3)
    at defaultTriggerAsyncIdScope (node:internal/async_hooks:464:18)
    at GetAddrInfoReqWrap.emitLookup [as callback] (node:net:1481:9)
    at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:130:8) {
  code: 'ERR_INTERNAL_ASSERTION'
} (Server.js:158)
node:internal/assert:14
    throw new ERR_INTERNAL_ASSERTION(message);
    ^

Error [ERR_INTERNAL_ASSERTION]: This is caused by either a bug in Node.js or incorrect usage of Node.js internals.
Please open an issue with this stack trace at https://github.com/nodejs/node/issues

    at assert (node:internal/assert:14:11)
    at internalConnect (node:net:1037:3)
    at defaultTriggerAsyncIdScope (node:internal/async_hooks:464:18)
    at GetAddrInfoReqWrap.emitLookup [as callback] (node:net:1481:9)
    at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:130:8) {
  code: 'ERR_INTERNAL_ASSERTION'
}

Node.js v20.11.1

Steps to reproduce the issue

Audiobookshelf version

v2.8.1

How are you running audiobookshelf?

Docker

Originally created by @ScuttleSE on GitHub (Apr 13, 2024). ### Describe the issue A little background... I wrote a short python-script to generate a XML-feed from a folder of files. Used a few different online RSS-feed validators to make sure it was actually "legit". I put up the file on a website only accessible from inside my network. Trying to add that URL in ABS crashes ABS. If I put the file on a internet-facing webserver, it seems to work curl:ing the url to the xml-file from inside the ABS-container works fine This is the errormessage I get ``` [2024-04-13 08:51:45.873] DEBUG: [podcastUtils] getPodcastFeed for "https://cronjobs.example.se/filter/podcast.xml" (podcastUtils.js:229) [2024-04-13 08:51:45.881] FATAL: [Server] Uncaught exception origin: uncaughtException, error: Error [ERR_INTERNAL_ASSERTION]: This is caused by either a bug in Node.js or incorrect usage of Node.js internals. Please open an issue with this stack trace at https://github.com/nodejs/node/issues at assert (node:internal/assert:14:11) at internalConnect (node:net:1037:3) at defaultTriggerAsyncIdScope (node:internal/async_hooks:464:18) at GetAddrInfoReqWrap.emitLookup [as callback] (node:net:1481:9) at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:130:8) { code: 'ERR_INTERNAL_ASSERTION' } (Server.js:158) node:internal/assert:14 throw new ERR_INTERNAL_ASSERTION(message); ^ Error [ERR_INTERNAL_ASSERTION]: This is caused by either a bug in Node.js or incorrect usage of Node.js internals. Please open an issue with this stack trace at https://github.com/nodejs/node/issues at assert (node:internal/assert:14:11) at internalConnect (node:net:1037:3) at defaultTriggerAsyncIdScope (node:internal/async_hooks:464:18) at GetAddrInfoReqWrap.emitLookup [as callback] (node:net:1481:9) at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:130:8) { code: 'ERR_INTERNAL_ASSERTION' } Node.js v20.11.1 ``` ### Steps to reproduce the issue 1. ### Audiobookshelf version v2.8.1 ### How are you running audiobookshelf? Docker
adam added the bug label 2026-04-25 00:00:54 +02:00
adam closed this issue 2026-04-25 00:00:54 +02:00
Author
Owner

@advplyr commented on GitHub (Apr 13, 2024):

Duplicate of https://github.com/advplyr/audiobookshelf/issues/2752

@advplyr commented on GitHub (Apr 13, 2024): Duplicate of https://github.com/advplyr/audiobookshelf/issues/2752
Author
Owner

@ScuttleSE commented on GitHub (Jun 3, 2024):

I get a new error now

[2024-06-03 03:55:09.053] DEBUG: [podcastUtils] getPodcastFeed for "https://cronjobs.hemma.lokal/filter/podcast.xml" (podcastUtils.js:229)
[2024-06-03 03:55:09.058] ERROR: [podcastUtils] getPodcastFeed Error AxiosError: Call to 192.168.0.66 is blocked.
at TLSSocket. (/node_modules/ssrf-req-filter/lib/index.js:38:29)
at TLSSocket.emit (node:events:519:28)
at GetAddrInfoReqWrap.emitLookup [as callback] (node:net:1438:14)
at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:132:8) {
config: {
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false
},
adapter: [Function: httpAdapter],
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 12000,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: { FormData: [Function] },
validateStatus: [Function: validateStatus],
headers: {
Accept: 'application/rss+xml, application/xhtml+xml, application/xml, /;q=0.8',
'User-Agent': 'axios/0.27.2'
},
url: 'https://cronjobs.hemma.lokal/filter/podcast.xml',
method: 'get',
responseType: 'arraybuffer',
httpAgent: Agent {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object: null prototype],
requests: [Object: null prototype] {},
sockets: [Object: null prototype] {},
freeSockets: [Object: null prototype] {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
scheduling: 'lifo',
maxTotalSockets: Infinity,
totalSocketCount: 0,
maxCachedSessions: 100,
_sessionCache: [Object],
createConnection: [Function (anonymous)],
[Symbol(shapeMode)]: false,
[Symbol(kCapture)]: false,
[Symbol(active)]: true
},
httpsAgent: Agent {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object: null prototype],
requests: [Object: null prototype] {},
sockets: [Object: null prototype],
freeSockets: [Object: null prototype] {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
scheduling: 'lifo',
maxTotalSockets: Infinity,
totalSocketCount: 1,
maxCachedSessions: 100,
_sessionCache: [Object],
createConnection: [Function (anonymous)],
[Symbol(shapeMode)]: false,
[Symbol(kCapture)]: false,
[Symbol(active)]: true
},
data: undefined
},
request: <ref *1> Writable {
_events: {
close: undefined,
error: [Function: handleRequestError],
prefinish: undefined,
finish: undefined,
drain: undefined,
response: [Function: handleResponse],
socket: [Array],
timeout: undefined,
abort: undefined
},
_writableState: WritableState {
highWaterMark: 16384,
length: 0,
corked: 0,
onwrite: [Function: bound onwrite],
writelen: 0,
bufferedIndex: 0,
pendingcb: 0,
[Symbol(kState)]: 17580812,
[Symbol(kBufferedValue)]: null
},
_maxListeners: undefined,
_options: {
maxRedirects: 21,
maxBodyLength: 10485760,
protocol: 'https:',
path: '/filter/podcast.xml',
method: 'GET',
headers: [Object],
agent: [Agent],
agents: [Object],
auth: undefined,
hostname: 'cronjobs.hemma.lokal',
port: null,
nativeProtocols: [Object],
pathname: '/filter/podcast.xml'
},
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 0,
_requestBodyBuffers: [],
_eventsCount: 3,
_onNativeResponse: [Function (anonymous)],
_currentRequest: ClientRequest {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
strictContentLength: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: false,
socket: [TLSSocket],
_header: 'GET /filter/podcast.xml HTTP/1.1\r\n' +
'Accept: application/rss+xml, application/xhtml+xml, application/xml, /;q=0.8\r\n' +
'User-Agent: axios/0.27.2\r\n' +
'Host: cronjobs.hemma.lokal\r\n' +
'Connection: close\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: [Agent],
socketPath: undefined,
method: 'GET',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
joinDuplicateHeaders: undefined,
path: '/filter/podcast.xml',
_ended: false,
res: null,
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'cronjobs.hemma.lokal',
protocol: 'https:',
_redirectable: [Circular *1],
[Symbol(shapeMode)]: false,
[Symbol(kCapture)]: false,
[Symbol(kBytesWritten)]: 0,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype],
[Symbol(errored)]: null,
[Symbol(kHighWaterMark)]: 16384,
[Symbol(kRejectNonStandardBodyWrites)]: false,
[Symbol(kUniqueHeaders)]: null
},
_currentUrl: 'https://cronjobs.hemma.lokal/filter/podcast.xml',
_timeout: null,
[Symbol(shapeMode)]: true,
[Symbol(kCapture)]: false
}
} (podcastUtils.js:265)

@ScuttleSE commented on GitHub (Jun 3, 2024): I get a new error now [2024-06-03 03:55:09.053] DEBUG: [podcastUtils] getPodcastFeed for "https://cronjobs.hemma.lokal/filter/podcast.xml" (podcastUtils.js:229) [2024-06-03 03:55:09.058] ERROR: [podcastUtils] getPodcastFeed Error AxiosError: Call to 192.168.0.66 is blocked. at TLSSocket.<anonymous> (/node_modules/ssrf-req-filter/lib/index.js:38:29) at TLSSocket.emit (node:events:519:28) at GetAddrInfoReqWrap.emitLookup [as callback] (node:net:1438:14) at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:132:8) { config: { transitional: { silentJSONParsing: true, forcedJSONParsing: true, clarifyTimeoutError: false }, adapter: [Function: httpAdapter], transformRequest: [ [Function: transformRequest] ], transformResponse: [ [Function: transformResponse] ], timeout: 12000, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, env: { FormData: [Function] }, validateStatus: [Function: validateStatus], headers: { Accept: 'application/rss+xml, application/xhtml+xml, application/xml, */*;q=0.8', 'User-Agent': 'axios/0.27.2' }, url: 'https://cronjobs.hemma.lokal/filter/podcast.xml', method: 'get', responseType: 'arraybuffer', httpAgent: Agent { _events: [Object: null prototype], _eventsCount: 2, _maxListeners: undefined, defaultPort: 443, protocol: 'https:', options: [Object: null prototype], requests: [Object: null prototype] {}, sockets: [Object: null prototype] {}, freeSockets: [Object: null prototype] {}, keepAliveMsecs: 1000, keepAlive: false, maxSockets: Infinity, maxFreeSockets: 256, scheduling: 'lifo', maxTotalSockets: Infinity, totalSocketCount: 0, maxCachedSessions: 100, _sessionCache: [Object], createConnection: [Function (anonymous)], [Symbol(shapeMode)]: false, [Symbol(kCapture)]: false, [Symbol(active)]: true }, httpsAgent: Agent { _events: [Object: null prototype], _eventsCount: 2, _maxListeners: undefined, defaultPort: 443, protocol: 'https:', options: [Object: null prototype], requests: [Object: null prototype] {}, sockets: [Object: null prototype], freeSockets: [Object: null prototype] {}, keepAliveMsecs: 1000, keepAlive: false, maxSockets: Infinity, maxFreeSockets: 256, scheduling: 'lifo', maxTotalSockets: Infinity, totalSocketCount: 1, maxCachedSessions: 100, _sessionCache: [Object], createConnection: [Function (anonymous)], [Symbol(shapeMode)]: false, [Symbol(kCapture)]: false, [Symbol(active)]: true }, data: undefined }, request: <ref *1> Writable { _events: { close: undefined, error: [Function: handleRequestError], prefinish: undefined, finish: undefined, drain: undefined, response: [Function: handleResponse], socket: [Array], timeout: undefined, abort: undefined }, _writableState: WritableState { highWaterMark: 16384, length: 0, corked: 0, onwrite: [Function: bound onwrite], writelen: 0, bufferedIndex: 0, pendingcb: 0, [Symbol(kState)]: 17580812, [Symbol(kBufferedValue)]: null }, _maxListeners: undefined, _options: { maxRedirects: 21, maxBodyLength: 10485760, protocol: 'https:', path: '/filter/podcast.xml', method: 'GET', headers: [Object], agent: [Agent], agents: [Object], auth: undefined, hostname: 'cronjobs.hemma.lokal', port: null, nativeProtocols: [Object], pathname: '/filter/podcast.xml' }, _ended: true, _ending: true, _redirectCount: 0, _redirects: [], _requestBodyLength: 0, _requestBodyBuffers: [], _eventsCount: 3, _onNativeResponse: [Function (anonymous)], _currentRequest: ClientRequest { _events: [Object: null prototype], _eventsCount: 7, _maxListeners: undefined, outputData: [], outputSize: 0, writable: true, destroyed: false, _last: true, chunkedEncoding: false, shouldKeepAlive: false, maxRequestsOnConnectionReached: false, _defaultKeepAlive: true, useChunkedEncodingByDefault: false, sendDate: false, _removedConnection: false, _removedContLen: false, _removedTE: false, strictContentLength: false, _contentLength: 0, _hasBody: true, _trailer: '', finished: true, _headerSent: true, _closed: false, socket: [TLSSocket], _header: 'GET /filter/podcast.xml HTTP/1.1\r\n' + 'Accept: application/rss+xml, application/xhtml+xml, application/xml, */*;q=0.8\r\n' + 'User-Agent: axios/0.27.2\r\n' + 'Host: cronjobs.hemma.lokal\r\n' + 'Connection: close\r\n' + '\r\n', _keepAliveTimeout: 0, _onPendingData: [Function: nop], agent: [Agent], socketPath: undefined, method: 'GET', maxHeaderSize: undefined, insecureHTTPParser: undefined, joinDuplicateHeaders: undefined, path: '/filter/podcast.xml', _ended: false, res: null, aborted: false, timeoutCb: null, upgradeOrConnect: false, parser: null, maxHeadersCount: null, reusedSocket: false, host: 'cronjobs.hemma.lokal', protocol: 'https:', _redirectable: [Circular *1], [Symbol(shapeMode)]: false, [Symbol(kCapture)]: false, [Symbol(kBytesWritten)]: 0, [Symbol(kNeedDrain)]: false, [Symbol(corked)]: 0, [Symbol(kOutHeaders)]: [Object: null prototype], [Symbol(errored)]: null, [Symbol(kHighWaterMark)]: 16384, [Symbol(kRejectNonStandardBodyWrites)]: false, [Symbol(kUniqueHeaders)]: null }, _currentUrl: 'https://cronjobs.hemma.lokal/filter/podcast.xml', _timeout: null, [Symbol(shapeMode)]: true, [Symbol(kCapture)]: false } } (podcastUtils.js:265)
Author
Owner

@advplyr commented on GitHub (Jun 3, 2024):

That was blocked by SSRF request filter that was added due to a security vulnerability reported. It blocks internal IP address. Is this an internally hosted RSS feed?

@advplyr commented on GitHub (Jun 3, 2024): That was blocked by SSRF request filter that was added due to a security vulnerability reported. It blocks internal IP address. Is this an internally hosted RSS feed?
Author
Owner

@ScuttleSE commented on GitHub (Jun 4, 2024):

Yes, it is

@ScuttleSE commented on GitHub (Jun 4, 2024): Yes, it is
Author
Owner

@advplyr commented on GitHub (Jun 4, 2024):

Sounds good. Check out https://github.com/advplyr/audiobookshelf/issues/2266 and my most recent comment. I added a ENV variable you can use in the next release or in the edge docker image now.

@advplyr commented on GitHub (Jun 4, 2024): Sounds good. Check out https://github.com/advplyr/audiobookshelf/issues/2266 and my most recent comment. I added a ENV variable you can use in the next release or in the `edge` docker image now.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/audiobookshelf#1883