Sindbad~EG File Manager
--[[
Code responsible for creating/managing the Javascript anti-bot challenge
Contains 3 types of challenge :
* JS Challenge : send a 503 to the browser with a javascript code that will auto-execute, make an ajax request to
retrieve the JS Challenge to another endpoint, execute the challenge, send the response, redirect to the
original page (improved)
* Captcha : send a 503 to the browser with a javascript code that contains a captcha to solve. Send the response to
the o2switch endpoint and redirect
* Cookie challenge : send a 307 response and ask the browser to set a cookie
We must pass a 'challengetype' nginx variable to check what king a challenge we use
--]]
-- Right, we support just 3 types of challenges
-- Early test / exit (probably better performance wise, this code is executed A LOT)
local challengeType = ngx.var.challengetype
if challengeType ~= 'js' and challengeType ~= 'cookie' and challengeType ~= 'captcha' then
ngx.exit(418)
end
local o2utils = require "lib/o2switch_utils"
local o2debug = require "lib/o2switch_debug"
local ck = require "resty.cookie"
local jsChl = require "lib/o2switch_js_challenge_v2"
local captchaChl = require "lib/o2switch_captcha"
local cookieChl = require "lib/o2switch_cookie_challenge"
local o2counter = require "lib/o2switch_counter"
local ngx = ngx
local clientIp = ngx.var.remote_addr
local ua = ngx.var.http_user_agent or '-'
local cookieName = 'o2s-chl'
local uniqueId = ngx.var.request_id
local type = type
local domain = o2utils.extractDomain(o2utils.extractDomainWww(ngx.var.host))
local cookie, err = ck:new()
--[[
New, improved, JS Challenge
--]]
if challengeType == 'js' then
if not cookie then
jsChl.sendChallengeHtmlPage(
jsChl.getAntiTamperingHash(clientIp, ua),
uniqueId
)
end
local field, err = cookie:get(cookieName)
if not field or type(field) ~= "string" then
jsChl.sendChallengeHtmlPage(
jsChl.getAntiTamperingHash(clientIp, ua),
uniqueId
)
end
local expectedCookie = jsChl.getBypassCookieValue(clientIp, ua, domain)
if field ~= expectedCookie then
--o2debug.debug('Not bypassed, not the expected cookie. Received = "' .. field .. '" and expected was "'.. expectedCookie ..'"')
jsChl.sendChallengeHtmlPage(
jsChl.getAntiTamperingHash(clientIp, ua),
uniqueId
)
end
-- The cookie is valid but we ignore it because we have some mitigation in place
if ngx.var['autoMitigationOverride'] == 1 then
jsChl.sendChallengeHtmlPage(
jsChl.getAntiTamperingHash(clientIp, ua),
uniqueId
)
end
-- TODO : Also implement the credit system in here
-- TODO : Should we delete persisted challenge in redis or just dont give a fuck because of the expiration on the key ?
ngx.exit(418)
end
--[[
Captcha challenge
--]]
if challengeType == 'captcha' then
if not cookie then
captchaChl.sendChallengeHtmlPage(captchaChl.getAntiTamperingHash(clientIp, ua), uniqueId)
end
local field, err = cookie:get(cookieName)
if not field or type(field) ~= "string" then
captchaChl.sendChallengeHtmlPage(captchaChl.getAntiTamperingHash(clientIp, ua), uniqueId)
end
local expectedCookie = captchaChl.getBypassCookieValue(clientIp, ua, domain)
if field ~= expectedCookie then
--o2debug.debug('Not bypassed, not the expected cookie. Received = "' .. field .. '" and expected was "'.. expectedCookie ..'"')
captchaChl.sendChallengeHtmlPage(captchaChl.getAntiTamperingHash(clientIp, ua), uniqueId)
end
-- The cookie is valid but we ignore it because we have some mitigation in place
if ngx.var['autoMitigationOverride'] == 1 then
captchaChl.sendChallengeHtmlPage(captchaChl.getAntiTamperingHash(clientIp, ua), uniqueId)
end
return ngx.exit(418)
end
--[[
Cookie challenge
--]]
if challengeType == 'cookie' then
-- No cookie at all ? Send the challenge
if not cookie then
--o2debug.debug("Cookie CHL : No cookie " .. clientIp .. ' on ' .. domain)
--o2debug.debug("Cookie CHL : Send 307 + cookie challenge for " .. clientIp .. ' on ' .. domain)
cookieChl.send307WithCookie(domain, cookieName, cookieChl.getChallengeCookieValue(clientIp, ua, domain))
end
-- Not cookie name o2s-chl : Send the challenge
local field, err = cookie:get(cookieName)
if not field then
--o2debug.debug("Cookie CHL : No cookie named " .. cookieName .. ' for ' .. clientIp .. ' on ' .. domain)
--o2debug.debug("Cookie CHL : Send 307 + cookie challenge for " .. clientIp .. ' on ' .. domain)
cookieChl.send307WithCookie(domain, cookieName, cookieChl.getChallengeCookieValue(clientIp, ua, domain))
end
-- A cookie is provided ? Is it valid and does it contains the right value ?
local expectedValue = cookieChl.getChallengeCookieValue(clientIp, ua, domain)
if field ~= expectedValue then
--o2debug.debug("Cookie CHL : Failed for " .. clientIp .. ' on ' .. domain)
--o2debug.debug("Cookie CHL : RE-Send 307 + cookie challenge for " .. clientIp .. ' on ' .. domain)
cookieChl.send307WithCookie(domain, cookieName, expectedValue)
end
if ngx.var['autoMitigationOverride'] == 1 then
cookieChl.send307WithCookie(domain, cookieName, expectedValue)
end
ngx.exit(418)
end
o2debug.debugErr('Weird, we shouldn\'t be here')
ngx.exit(418) -- Should not happen
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists