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

如何通过参数白名单防范constantize引发的远程代码执行漏洞?

解决Brakeman检测到的UnsafeReflection风险(参数白名单实现)

问题根源

你的代码直接对用户可控的new_entity_type参数调用camelize.constantize和upcase.constantize,这属于不安全的反射操作——攻击者可以构造恶意的实体类型值,触发任意代码执行,所以Brakeman给出了高风险的远程代码执行警告。

解决方案:实现参数白名单

通过创建允许的实体类型白名单,只对合法的类型执行反射操作,彻底阻断恶意输入的攻击路径。

步骤1:定义合法实体类型白名单

根据你的业务需求,列出所有允许的实体类型(对应实际的Rails模型类),比如:

# 可放到控制器顶部作为常量,或抽入配置文件/模型中统一维护
ALLOWED_ENTITY_TYPES = %w[user organization property] # 替换为你实际的合法类型

步骤2:修改代码加入白名单校验

在执行constantize之前,先检查输入是否在白名单内,非法输入直接返回错误:

def create_reassign_entity
  @house = House.find(params[:id])
  new_entity_id = params[:house].try(:[], :entity_id).presence
  new_entity_type = params[:house].try(:[], :entity_type).presence

  if new_entity_id.blank? || new_entity_type.blank?
    flash[:error] = t('Please_select_an_entity')
  elsif !ALLOWED_ENTITY_TYPES.include?(new_entity_type.downcase)
    flash[:error] = t('Invalid_entity_type') # 新增非法类型提示
  else
    # 仅对白名单内的类型执行反射操作
    new_entity_model = new_entity_type.camelize.constantize
    # 优化建议:若new_entity_type_num对应模型常量,可直接在白名单维护映射,避免重复反射
    new_entity_type_num = new_entity_type.upcase.constantize
    new_entity = new_entity_model.find_cached(new_entity_id) rescue nil

    if new_entity.is_a?(new_entity_model)
      @house.update_attributes(entity_id: new_entity_id, entity_type: new_entity_type_num)
      @house.update_entity_state_county
      flash[:notice] = t('This_house_will_be_reassigned_to_entity_') + new_entity.to_label
    else
      flash[:error] = t('Unable_to_find')
    end
  end

  respond_to do |format|
    format.html { redirect_to(house_path(@house)) }
    format.json { render json: @house, status: :ok }
    format.xml  { render xml: @house.as_json, status: :ok }
  end
end

额外优化建议

  • 白名单全局维护:把ALLOWED_ENTITY_TYPES抽入config/initializers/entity_types.rb配置文件,方便全局修改和团队协作维护。
  • 完全避免反射调用:如果new_entity_type_num对应的是模型常量(如USER),可以直接在白名单里维护映射关系,比如:
    ALLOWED_ENTITY_MAPPINGS = {
      'user' => { model: User, type_num: USER },
      'organization' => { model: Organization, type_num: ORGANIZATION }
    }
    
    后续直接通过ALLOWED_ENTITY_MAPPINGS[new_entity_type]获取模型类和类型常量,彻底去掉constantize调用,进一步降低风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 08:25:30