ZBLOG

openresty如何利用babel插件将上游响应的JS文件中所有location对象删除,需要识别出location对象,代码可能经过混淆

使用OpenResty删除上游响应中的location对象

要在OpenResty中通过Babel插件删除上游响应JS文件中的所有location对象,你需要编写一个Lua脚本来处理响应体,并使用JavaScript解析器来识别和修改AST。以下是实现方案:

解决方案

  1. 安装必要的依赖

    opm install babel/core
    opm install babel/parser
    opm install babel/generator
    
  2. Lua脚本实现

local parser = require("babel.parser")
local generator = require("babel.generator")
local traverse = require("babel.traverse")

-- 自定义Babel插件:删除location对象
local remove_location_visitor = {
    MemberExpression = function(path)
        local node = path.node
        if node.object and node.object.name == "location" then
            path:remove()
        end
    end,
    Identifier = function(path)
        if path.node.name == "location" and path.parent.type ~= "MemberExpression" then
            path:remove()
        end
    end
}

function process_js_content(content)
    -- 解析JS代码为AST
    local ast, err = parser.parse(content, {
        sourceType = "unambiguous",
        plugins = {
            "jsx",
            "typescript"
        }
    })
    
    if not ast then
        ngx.log(ngx.ERR, "Failed to parse JS: ", err)
        return content -- 返回原始内容以防出错
    end
    
    -- 遍历并修改AST
    traverse(ast, remove_location_visitor)
    
    -- 生成新的JS代码
    local new_code, map = generator(ast, {
        retainLines = true,
        compact = false,
        comments = true,
        sourceMaps = true,
    }, content)
    
    return new_code.code or content -- 返回处理后的代码或原始内容作为回退方案
end

-- OpenResty响应体过滤器回调函数
function filter_response_body(r)
    local content_type = r.headers_out["Content-Type"] or ""
    
    if string.find(content_type:lower(), "javascript") or 
       string.find(content_type:lower(), "ecmascript") then
        
        local body = r.body
        
        -- 只处理非空JS文件(大于1KB才处理)
        if body and #body > 1024 then
            
            -- 尝试解码可能的混淆代码(如十六进制编码)
            local decoded_body
            
            -- 检查是否是十六进制编码的字符串(常见混淆技术)
            if body:match('^%s*["\']([0-9a-fA-F]+)["\']%s*;?%s*$') then                
                decoded_body = body:gsub('(["\'\\])([0-9a-fA-F]+)(["\'\\])', function(open, hex, close)
                    return open .. hex_to_str(hex) .. close                    
                end)
                
                decoded_body = decoded_body or body                
                ngx.log(ngx.DEBUG, "Decoded possible hex-encoded JS")
            
            else                
                decoded_body = body            
            end
            
            -- 处理JS内容            
            r.body = process_js_content(decoded_body)        
         end    
     end
    
     return r.body 
end 

-- Helper函数:十六进制转字符串 
function hex_to_str(hex)     
     return (hex:gsub('..', function (cc)         
          return string.char(tonumber(cc,16))     
     end)) 
end 

--注册过滤器 
return {     
      name="js_location_remover",     
      desc="Remove location objects from JS responses",     
      init=function()         
           ngx.log(ngx.NOTICE,"JS Location Remover filter initialized")     
      end ,      
      body_filter=filter_response_body  
}

部署方式

  1. 在nginx.conf中配置:
http {
    lua_package_path "/path/to/your/lua/scripts/?.lua;;";
    
    init_by_lua_block {
        require("resty.core")
        
         -加载我们的过滤器模块        
         local js_filter=require("js_location_remover")        
         js_filter.init()   
     }
     
     server {         
          listen80;          
          location / {              
               proxy_pass http://backend;              
               header_filter_by_lua_block{                  
                   ngx.header.content_length=nil              
               }              
               body_filter_by_lua_block{                  
                   require("js_location_remover").body_filter()              
               }          
          }     
     } 
}

注意事项

  1. 性能考虑

    • JavaScript解析和AST操作是CPU密集型任务,建议只对特定路径或特定大小的文件应用此过滤器。
    • 可以添加缓存机制,避免重复处理相同的内容。
  2. 错误处理

    • Babel解析可能会失败(特别是对于混淆代码),脚本包含回退机制以返回原始内容。
  3. 更复杂的混淆检测

    • 上面的示例仅检测了简单的十六进制编码,实际应用中可能需要更复杂的反混淆逻辑。
  4. 测试验证

    • 在生产环境部署前,应充分测试以确保不会破坏合法的JavaScript功能。

这个解决方案结合了OpenResty的高性能和Babel的精确AST操作能力,能够有效识别和删除各种形式的location对象引用。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=23160

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?