Skip to content

Commit a1fbb31

Browse files
committed
f
1 parent 752f1af commit a1fbb31

3 files changed

Lines changed: 50 additions & 3 deletions

File tree

lib/core/fetch_factory.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,36 @@ const debug = require('util').debuglog('egg:lib:core:httpclient_next');
22

33
const mainNodejsVersion = parseInt(process.versions.node.split('.')[0]);
44
let FetchFactory;
5+
let safeFetch;
6+
let ssrfFetchFactory;
7+
58
if (mainNodejsVersion >= 18) {
69
// urllib@4 only works on Node.js >= 18
710
try {
811
const urllib4 = require('urllib4');
912
FetchFactory = urllib4.FetchFactory;
1013
debug('urllib4 enable');
14+
15+
safeFetch = function safeFetch(url, init) {
16+
if (!ssrfFetchFactory) {
17+
const ssrfConfig = this.config.security.ssrf;
18+
const clientOptions = {};
19+
if (ssrfConfig?.checkAddress) {
20+
clientOptions.checkAddress = ssrfConfig.checkAddress;
21+
} else {
22+
this.logger.warn('[egg-security] please configure `config.security.ssrf` first');
23+
}
24+
ssrfFetchFactory = new FetchFactory();
25+
ssrfFetchFactory.setClientOptions(clientOptions);
26+
}
27+
return ssrfFetchFactory.fetch(url, init);
28+
};
1129
} catch (err) {
1230
debug('require urllib4 error: %s', err);
1331
}
1432
}
1533

16-
module.exports = FetchFactory;
34+
module.exports = {
35+
FetchFactory,
36+
safeFetch,
37+
};

lib/egg.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const Messenger = require('./core/messenger');
1414
const DNSCacheHttpClient = require('./core/dnscache_httpclient');
1515
const HttpClient = require('./core/httpclient');
1616
const HttpClientNext = require('./core/httpclient_next');
17-
const FetchFactory = require('./core/fetch_factory');
17+
const { FetchFactory, safeFetch } = require('./core/fetch_factory');
1818
const createLoggers = require('./core/logger');
1919
const Singleton = require('./core/singleton');
2020
const utils = require('./core/utils');
@@ -56,6 +56,7 @@ class EggApplication extends EggCore {
5656
if (FetchFactory) {
5757
this.FetchFactory.setClientOptions();
5858
this.fetch = FetchFactory.fetch;
59+
this.safeFetch = safeFetch.bind(this);
5960
}
6061

6162
this.loader.loadConfig();

test/lib/core/fetch_factory.test.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const assert = require('node:assert');
22
const mm = require('egg-mock');
3-
const FetchFactory = require('../../../lib/core/fetch_factory');
3+
const { FetchFactory, safeFetch } = require('../../../lib/core/fetch_factory');
44
const utils = require('../../utils');
55

66
describe('test/lib/core/fetch_factory.test.js', () => {
@@ -17,4 +17,29 @@ describe('test/lib/core/fetch_factory.test.js', () => {
1717
const { status } = await FetchFactory.fetch(url);
1818
assert(status === 200);
1919
});
20+
21+
it('should support safeFetch', async () => {
22+
let ip;
23+
let family;
24+
let host;
25+
const fetch = safeFetch.bind({
26+
config: {
27+
security: {
28+
ssrf: {
29+
checkAddress(aIp, aFamily, aHost) {
30+
ip = aIp;
31+
family = aFamily;
32+
host = aHost;
33+
return true;
34+
},
35+
},
36+
},
37+
},
38+
logger: console,
39+
});
40+
await fetch(url);
41+
assert(ip);
42+
assert(family);
43+
assert(host);
44+
});
2045
});

0 commit comments

Comments
 (0)