Skip to content

WAF rules

Alexander Polakov edited this page Oct 25, 2021 · 2 revisions

cacherpc supports filters written in Lua since v0.1.34. They can be used to filter requests before they're processed.

A waf module currently consists of one function waf.request(data) where data is a structure with 3 fields:

  • jsonrpc - string (jsonrpc version)
  • method - string (jsonrpc request method, currently one of getAccountInfo or getProgramAccounts)
  • params - string (params field of the json request)

waf.request must return a pair of (bool, string) where true means request should be passed for further processing and false means processing should be stopped returning message in the second element.

Example:

local waf = { }

local json = require 'json'

function waf.request(data)
        if data.method == 'getProgramAccounts' then
                --- parse parameters
                local params = json.decode(data.params)
                --- only interested in 9xQ... requests
                if params[1] == '9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin' then
                        --- options are required
                        if params[2] == nil then return false, 'No params' end
                        --- retrieve filters field
                        local filters = params[2].filters
                        if filters == nil then
                                return false, 'Rejected for no filters'
                        else                     
                                --- setup filter counters                            
                                local counts = { memcmp = 0, dataSize = 0 }
                                --- iterate over filters
                                for i,filter in ipairs(filters) do
                                        for name, _ in pairs(filter) do
                                                counts[name] = counts[name] + 1
                                        end
                                end
                                --- pass if both filters found                                                 
                                if counts.memcmp > 0 and counts.dataSize > 0 then
                                        return true, ''
                                else 
                                        return false, 'Rejected for no data_size/memcmp'
                                end
                        end
                end
        end
    return true, ''
end

return waf

How to test filters

To test filters without running cacherpc one can use a local lua interpreter with test data. Put your waf code in waf.lua file, get json.lua and put it in the same directory. Then start lua:

$ lua 
Lua 5.4.2  Copyright (C) 1994-2020 Lua.org, PUC-Rio
> json = require 'json'
> waf = require 'waf'
> --- provide test data
> r = { method = 'getProgramAccounts', params = '["9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin",{"commitment":"confirmed","filters":[{"memcmp":{"offset":13,"bytes":"3hwH1txjJVS8qv588tWrjHfRxdqNjBykM1kMcit484up"}},{"memcmp":{"offset":45,"bytes":"DgfZuKR4NcVhqnwcmMFxVSf58z32NwuYdhyAekNKNofh"}},{"dataSize":3228}],"encoding":"base64"}]' }
> --- call request
> print(waf.request(r))
true

as we can see it returns true as expected

Clone this wiki locally