mirror of
https://github.com/labring/FastGPT.git
synced 2026-05-05 01:02:59 +08:00
Fix share (#6554)
* fix: http tool * fix: http tool * fix: test * fix: test * fix: test * fix: test
This commit is contained in:
@@ -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';
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user