From b9e7f061788c3b86a0c67d2d4158f067ec5eb625 Mon Sep 17 00:00:00 2001 From: Ondrej Mular Date: Fri, 29 Jan 2016 14:31:37 +0100 Subject: [PATCH] fix CSRF vulnerability * requests /remote/* (GET and POST) and /run_pcs are accessible only with token authentication * all web UI requests are accessible only with session authentication * all web UI requests (except for /manage, /managec//main, /permissions ) must include header: X-Requested-With: XMLHttpRequest --- pcsd/pcsd.rb | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/pcsd/pcsd.rb b/pcsd/pcsd.rb index 349e236f0..847eb1190 100644 --- a/pcsd/pcsd.rb +++ b/pcsd/pcsd.rb @@ -121,26 +121,31 @@ def generate_cookie_secret helpers do def protected! - if not PCSAuth.loginByToken(session, cookies) and not PCSAuth.isLoggedIn(session) - # If we're on /managec//main we redirect - match_expr = "/managec/(.*)/(.*)" - mymatch = request.path.match(match_expr) - on_managec_main = false - if mymatch and mymatch.length >= 3 and mymatch[2] == "main" - on_managec_main = true + gui_request = ( # these are URLs for web pages + request.path == '/' or + request.path == '/manage' or + request.path == '/permissions' or + request.path.match('/managec/.+/main') + ) + if request.path.start_with?('/remote/') or request.path == '/run_pcs' + unless PCSAuth.loginByToken(session, cookies) + halt [401, '{"notauthorized":"true"}'] end - - if request.path.start_with?('/remote') or - (request.path.match(match_expr) and not on_managec_main) or - '/run_pcs' == request.path or - '/clusters_overview' == request.path or - request.path.start_with?('/permissions_') + else #/managec/* /manage/* /permissions + if !gui_request and + request.env['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest' then - $logger.info "ERROR: Request without authentication" + # Accept non GUI requests only with header + # "X_REQUESTED_WITH: XMLHttpRequest". (check if they are send via AJAX). + # This prevents CSRF attack. halt [401, '{"notauthorized":"true"}'] - else - session[:pre_login_path] = request.path - redirect '/login' + elsif not PCSAuth.isLoggedIn(session) + if gui_request + session[:pre_login_path] = request.path + redirect '/login' + else + halt [401, '{"notauthorized":"true"}'] + end end end end