* fix: http tool

* fix: http tool

* fix: test

* fix: test

* fix: test

* fix: test
This commit is contained in:
Archer
2026-03-13 17:24:15 +08:00
committed by GitHub
parent df04515b1c
commit dbc443a770
15 changed files with 494 additions and 93 deletions
+4 -4
View File
@@ -1,6 +1,6 @@
import { SERVICE_LOCAL_HOST } from './tools';
import { isIP } from 'net';
import * as dns from 'node:dns/promises';
import { SERVICE_LOCAL_HOST } from './tools';
export const isInternalAddress = async (url: string): Promise<boolean> => {
const isInternalIPv6 = (ip: string): boolean => {
@@ -138,9 +138,8 @@ export const isInternalAddress = async (url: string): Promise<boolean> => {
return true;
}
// 3. 默认启用内部 IP 检查(安全优先)
// 只有显式设置 CHECK_INTERNAL_IP=false 时才禁用检查
if (process.env.CHECK_INTERNAL_IP === 'false') {
// 3. 只有显式设置 CHECK_INTERNAL_IP=true 时才启用私有 IP 检查
if (process.env.CHECK_INTERNAL_IP !== 'true') {
return false;
}
@@ -185,3 +184,4 @@ export const isInternalAddress = async (url: string): Promise<boolean> => {
return false;
}
};
export const PRIVATE_URL_TEXT = 'Request to private network not allowed';
+12 -6
View File
@@ -6,7 +6,7 @@ import type { RequireOnlyOne } from '@fastgpt/global/common/type/utils';
import type { HttpToolConfigType } from '@fastgpt/global/core/app/tool/httpTool/type';
import { contentTypeMap, ContentTypes } from '@fastgpt/global/core/workflow/constants';
import { replaceEditorVariable } from '@fastgpt/global/core/workflow/runtime/utils';
import { isInternalAddress } from '../../common/system/utils';
import { isInternalAddress, PRIVATE_URL_TEXT } from '../../common/system/utils';
export type RunHTTPToolParams = {
baseUrl: string;
@@ -138,15 +138,20 @@ export const runHTTPTool = async ({
}: RunHTTPToolParams): Promise<RunHTTPToolResult> => {
try {
// Construct full base URL
const fullBaseUrl =
baseUrl.startsWith('http://') || baseUrl.startsWith('https://')
const fullBaseUrl = !baseUrl
? ''
: baseUrl.startsWith('http://') || baseUrl.startsWith('https://')
? baseUrl
: `https://${baseUrl}`;
// SSRF Protection: Validate URL before making request
const fullUrl = new URL(toolPath, fullBaseUrl).toString();
// When baseUrl is empty, toolPath must be a complete URL
const fullUrl = fullBaseUrl
? new URL(toolPath, fullBaseUrl).toString()
: new URL(toolPath).toString();
if (await isInternalAddress(fullUrl)) {
return { errorMsg: 'Access to internal addresses is not allowed' };
return { errorMsg: PRIVATE_URL_TEXT };
}
const { headers, body, queryParams } = buildHttpRequest({
@@ -170,7 +175,8 @@ export const runHTTPTool = async ({
});
return { data };
} catch (error: any) {
} catch (error) {
console.log(error);
return { errorMsg: getErrText(error) };
}
};
@@ -1,4 +1,4 @@
import { isInternalAddress } from '../../../../../../../common/system/utils';
import { isInternalAddress, PRIVATE_URL_TEXT } from '../../../../../../../common/system/utils';
import axios from 'axios';
import { serverRequestBaseUrl } from '../../../../../../../common/api/serverRequest';
import { parseFileExtensionFromUrl } from '@fastgpt/global/common/string/tools';
@@ -59,7 +59,7 @@ export const dispatchFileRead = async ({
return {
index,
name: '',
content: Promise.reject('Url is invalid')
content: Promise.reject(PRIVATE_URL_TEXT)
};
}
// Get file buffer data
@@ -26,7 +26,7 @@ import type { StoreSecretValueType } from '@fastgpt/global/common/secret/type';
import { getLogger, LogCategories } from '../../../../common/logger';
import { SERVICE_LOCAL_HOST } from '../../../../common/system/tools';
import { formatHttpError } from '../utils';
import { isInternalAddress } from '../../../../common/system/utils';
import { isInternalAddress, PRIVATE_URL_TEXT } from '../../../../common/system/utils';
import { serviceRequestMaxContentLength } from '../../../../common/system/constants';
import { axios } from '../../../../common/api/axios';
@@ -496,7 +496,7 @@ async function fetchData({
timeout: number;
}) {
if (await isInternalAddress(url)) {
return Promise.reject('Url is invalid');
return Promise.reject(PRIVATE_URL_TEXT);
}
const { data: response } = await axios({
@@ -13,7 +13,7 @@ import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
import { type ChatItemType } from '@fastgpt/global/core/chat/type';
import { addDays } from 'date-fns';
import { getNodeErrResponse } from '../utils';
import { isInternalAddress } from '../../../../common/system/utils';
import { isInternalAddress, PRIVATE_URL_TEXT } from '../../../../common/system/utils';
import { replaceS3KeyToPreviewUrl } from '../../../dataset/utils';
import { getFileS3Key } from '../../../../common/s3/utils';
import { S3ChatSource } from '../../../../common/s3/sources/chat';
@@ -188,7 +188,7 @@ export const getFileContentFromLinks = async ({
try {
if (await isInternalAddress(url)) {
return Promise.reject('Url is invalid');
return Promise.reject(PRIVATE_URL_TEXT);
}
// Get file buffer data