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

Atlassian Connect应用JWT认证漏洞修复求助(Ruby on Rails)

修复Atlassian Connect应用JWT认证漏洞(Ruby on Rails)

问题背景

我在Atlassian应用市场上架的Connect应用未通过JWT认证漏洞扫描工具检测,漏洞描述如下:

Connect安全要求测试工具的EcoScanner检查项“应用资源认证”报告了以下问题:
一个或多个端点在未提供认证信息的情况下返回了<400状态码。这可能表明您的应用未执行认证与授权检查。扫描工具使用的JWT令牌为测试用伪造令牌。注意:若您认为报告的端点确实无需认证,请在漏洞工单中发起复核,Atlassian EcoAppSec团队将进行核查。

我的应用基于Ruby on Rails开发,已尝试编写校验POST请求JWT令牌的方法并在Webhook端点使用,但问题仍未解决。当前校验代码如下:

def check_jwt(user)
  authorization_header = request.headers['Authorization']

  # Ensure the Authorization header exists and starts with "JWT "
  if authorization_header&.start_with?('JWT ')
    jwt_token = authorization_header[4..-1]
    shared_secret = user.shared_secret

    begin
      decoded_token = JWT.decode(jwt_token, shared_secret, true, algorithm: 'HS256')
      rescue JWT::DecodeError => e
      render json: { error: 'Unauthorized' }, status: :unauthorized
      raise e # Raise an exception to halt further execution
   end

   # Continue processing with the decoded token
   # ...
   else
     render json: { error: 'Unauthorized' }, status: :unauthorized
     raise JWT::DecodeError, 'Missing or invalid Authorization header'
   end    
 end

修复方案

1. 覆盖所有HTTP方法

扫描工具可能测试了GET、PUT等非POST方法的端点,仅针对POST做校验远远不够。必须确保所有对外暴露的端点,无论请求方法,都执行JWT认证校验。

2. 修复校验逻辑的核心缺陷

  • 状态码合规性:未认证请求必须返回401 Unauthorized,而非400。你的代码虽指定了:unauthorized,但要确认无中间件篡改状态码(Rails默认映射401,需排查)。
  • 异常处理全覆盖:JWT.decode会抛出多种异常(如JWT::ExpiredSignature、JWT::InvalidIssuerError),当前仅捕获JWT::DecodeError,需统一处理所有JWT相关异常。
  • 确保请求彻底终止:render后raise异常可能被其他rescue捕获,导致请求继续处理。建议用head :unauthorized后直接return,或在Rails控制器中用throw :abort彻底终止请求。

修改后的校验方法示例:

def check_jwt(user)
  authorization_header = request.headers['Authorization']

  # 校验Authorization头格式
  unless authorization_header&.start_with?('JWT ')
    head :unauthorized
    return
  end

  jwt_token = authorization_header[4..-1]
  shared_secret = user.shared_secret

  begin
    decoded_token = JWT.decode(jwt_token, shared_secret, true, algorithm: 'HS256')
    # 可选增强:校验令牌的issuer、audience等字段符合Atlassian规范
    # issuer = decoded_token[0]['iss']
    # unless issuer == "https://#{user.atlassian_domain}"
    #   head :unauthorized
    #   return
    # end
  rescue JWT::DecodeError, JWT::ExpiredSignature, JWT::InvalidIssuerError => e
    head :unauthorized
    return
  end

  # 校验通过,继续处理请求
end

3. 全局应用认证校验(推荐)

不要仅在Webhook端点手动调用校验,建议用Rails的before_action全局应用到所有控制器,或指定路由组:

# 在ApplicationController中添加全局前置校验
before_action :check_jwt

private

def check_jwt
  # 根据租户标识获取对应用户(比如从请求头或令牌解析)
  tenant_id = request.headers['X-Atlassian-Tenant-Id']
  user = User.find_by(tenant_id: tenant_id)

  unless user
    head :unauthorized
    return
  end

  # 执行JWT校验逻辑
  authorization_header = request.headers['Authorization']
  unless authorization_header&.start_with?('JWT ')
    head :unauthorized
    return
  end

  jwt_token = authorization_header[4..-1]
  shared_secret = user.shared_secret

  begin
    JWT.decode(jwt_token, shared_secret, true, algorithm: 'HS256')
  rescue JWT::DecodeError, JWT::ExpiredSignature, JWT::InvalidIssuerError => e
    head :unauthorized
    return
  end
end

4. 排查未覆盖的端点

  • 检查所有路由是否都应用了校验,包括静态资源、健康检查端点(若健康检查无需认证,需在漏洞工单中说明并申请复核)。
  • 重新运行扫描工具,确认所有未认证请求均返回401状态码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 01:21:15