You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BULK INSERT报错3:路径无法找到及SQL注入防护问题排查

问题:SQL注入防护后OPENROWSET(BULK)无法正常解析路径
  • 初始代码(运行正常但存在SQL注入风险):
select @CHEMIN_FICHIER = 'C:\\crm_tmp\\Images\\Equipements\\' + @NOM_FICHIER;
  • 为防注入修改后的代码(PRINT验证路径一致,但BULK INSERT无法运行):
select @CHEMIN_FICHIER = 'C:\\rm_tmp\\Images\\Equipements\\' + REPLACE(REPLACE(QUOTENAME(@NOM_FICHIER) , '[', ''), ']', '');

对应的动态执行语句:

select @COMMANDE = 'INSERT INTO [image] (nom, donnees) SELECT '''' + @NOM_FICHIER + ''', BulkColumn FROM OPENROWSET(Bulk ''''+ @CHEMIN_FICHIER + ''', SINGLE_BLOB) AS BLOB';
  • 尝试参数化方案B(@NOM_FICHIER未被解析,路径错误):
set @ParamDefinition = '@NOM_FICHIER nvarchar(255)'
select @CHEMIN_FICHIER = 'C:\\crm_tmp\\Images\\Equipements\\@NOM_FICHIER';
select @COMMANDE = 'INSERT INTO [image] (nom, donnees) SELECT '''' + @NOM_FICHIER + ''', BulkColumn FROM OPENROWSET(Bulk ''''+ @CHEMIN_FICHIER + ''', SINGLE_BLOB) AS BLOB';
    
execute sp_executesql @COMMANDE, @ParamDefinition, @NOM_FICHIER

错误提示:Cannot bulk load because the file, BULK INSERT error code 3: The system cannot find the path specified,生成的路径为C:\\crm_tmp\\Images\\Equipements\\@NOM_FICHIER而非预期的C:\\crm_tmp\\Images\\Equipements\\test.png


解决方案

方法1:安全拼接文件名+合法性验证

通过严格过滤非法字符、验证文件存在性,在可控范围内拼接路径:

-- 过滤文件名中的路径遍历/非法字符
set @NOM_FICHIER = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
    @NOM_FICHIER, '\', ''), '/', ''), ':', ''), '*', ''), '?', ''), '"', ''), '<', ''), '>', ''), '|', '');

-- 拼接合法路径
select @CHEMIN_FICHIER = 'C:\\crm_tmp\\Images\\Equipements\\' + @NOM_FICHIER;

-- 验证文件是否存在(需确保SQL Server账户有路径访问权限)
declare @fileExists int;
exec xp_fileexist @CHEMIN_FICHIER, @fileExists output;

if @fileExists = 1
begin
    -- 转义单引号避免SQL语法错误
    select @COMMANDE = 'INSERT INTO [image] (nom, donnees) SELECT ''' + REPLACE(@NOM_FICHIER, '''', '''''') + ''', BulkColumn FROM OPENROWSET(Bulk ''' + REPLACE(@CHEMIN_FICHIER, '''', '''''') + ''', SINGLE_BLOB) AS BLOB';
    execute sp_executesql @COMMANDE;
end
else
begin
    raiserror('文件不存在或路径非法', 16, 1);
end

方法2:参数化路径(SQL Server 2017+支持)

从SQL Server 2017开始,OPENROWSET支持直接使用参数传递路径,彻底避免拼接风险:

declare @COMMANDE nvarchar(max);
declare @ParamDefinition nvarchar(max);
declare @CHEMIN_FICHIER nvarchar(500);

-- 先过滤非法字符
set @NOM_FICHIER = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
    @NOM_FICHIER, '\', ''), '/', ''), ':', ''), '*', ''), '?', ''), '"', ''), '<', ''), '>', ''), '|', '');
select @CHEMIN_FICHIER = 'C:\\crm_tmp\\Images\\Equipements\\' + @NOM_FICHIER;

-- 构造参数化动态SQL
set @ParamDefinition = '@FilePath nvarchar(500), @FileName nvarchar(255)';
set @COMMANDE = N'INSERT INTO [image] (nom, donnees) 
                  SELECT @FileName, BulkColumn 
                  FROM OPENROWSET(BULK @FilePath, SINGLE_BLOB) AS BLOB';

execute sp_executesql @COMMANDE, @ParamDefinition, @FilePath = @CHEMIN_FICHIER, @FileName = @NOM_FICHIER;

注意:需确保SQL Server服务账户拥有目标文件路径的读取权限。


内容的提问来源于stack exchange,提问作者user609511

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 04:10:13