mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-16 04:36:02 +00:00
01_FHEMWEB.pm: return 401 for empty/no CSRF (Forum #67848)
git-svn-id: https://svn.fhem.de/fhem/trunk@13516 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
f26213c2f0
commit
0669d97685
@ -94,6 +94,7 @@ my $FW_use_sha = 0;
|
||||
my $FW_activateInform = 0;
|
||||
my $FW_lastWebName = ""; # Name of last FHEMWEB instance, for caching
|
||||
my $FW_lastHashUpdate = 0;
|
||||
my $FW_httpRetCode = "";
|
||||
my %FW_csrfTokenCache;
|
||||
|
||||
#########################
|
||||
@ -530,6 +531,7 @@ FW_Read($$)
|
||||
}
|
||||
}
|
||||
|
||||
$FW_httpRetCode = "200 OK";
|
||||
my $cacheable = FW_answerCall($arg);
|
||||
if($cacheable == -1) {
|
||||
FW_closeConn($hash);
|
||||
@ -557,7 +559,7 @@ FW_Read($$)
|
||||
Log3 $FW_wname, 4,
|
||||
"name: $arg / RL:$length / $FW_RETTYPE / $compressed / $expires";
|
||||
if( ! FW_addToWritebuffer($hash,
|
||||
"HTTP/1.1 200 OK\r\n" .
|
||||
"HTTP/1.1 $FW_httpRetCode\r\n" .
|
||||
"Content-Length: $length\r\n" .
|
||||
$expires . $compressed . $FW_headerlines .
|
||||
"Content-Type: $FW_RETTYPE\r\n\r\n" .
|
||||
@ -810,6 +812,7 @@ FW_answerCall($)
|
||||
if($supplied ne $want) {
|
||||
Log3 $FW_wname, 3, "FHEMWEB $FW_wname CSRF error: $supplied ne $want. ".
|
||||
"For detals see the csrfToken FHEMWEB attribute";
|
||||
$FW_httpRetCode = "401 Unauthorized";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
var fd_loadedHash={}, fd_loadedList=[], fd_all={}, fd_allCnt, fd_progress=0,
|
||||
fd_lang, fd_offsets=[], fd_scrolled=0, fd_modLinks={}, csrfToken="";
|
||||
fd_lang, fd_offsets=[], fd_scrolled=0, fd_modLinks={}, csrfToken="X";
|
||||
|
||||
|
||||
function
|
||||
@ -19,13 +19,19 @@ fd_status(txt)
|
||||
function
|
||||
fd_fC(fn, callback)
|
||||
{
|
||||
console.log("fd_fC:"+fn);
|
||||
var p = location.pathname;
|
||||
var cmd = p.substr(0,p.indexOf('/doc'))+
|
||||
'?cmd='+fn+csrfToken+'&XHR=1';
|
||||
var ax = $.ajax({ cache:false, url:cmd });
|
||||
ax.done(callback);
|
||||
ax.fail(function(req, stat, err) {
|
||||
console.log("FAIL ERR:"+err+" STAT:"+stat);
|
||||
var cmd = p.substr(0,p.indexOf('/doc'))+'?cmd='+fn+csrfToken+'&XHR=1';
|
||||
$.ajax({
|
||||
url:cmd, method:'POST', cache:false, success:callback,
|
||||
error:function(xhr, status, err) {
|
||||
if(xhr.status == 401 && csrfToken) {
|
||||
csrfToken = "";
|
||||
fd_csrfRefresh(function(){fd_fC(fn, callback)});
|
||||
} else {
|
||||
console.log("FAIL ERR:"+xhr.status+" STAT:"+status);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -151,6 +157,21 @@ loadOtherLang()
|
||||
loadOneDoc(mname, fd_loadedHash[mname]=="EN" ? "DE" : "EN");
|
||||
}
|
||||
|
||||
function
|
||||
fd_csrfRefresh(callback)
|
||||
{
|
||||
console.log("fd_csrfRefresh");
|
||||
$.ajax({
|
||||
url:location.pathname.replace(/docs.*/,'')+"?XHR=1",
|
||||
success: function(data, textStatus, request){
|
||||
csrfToken = request.getResponseHeader('x-fhem-csrftoken');
|
||||
csrfToken = csrfToken ? ("&fwcsrf="+csrfToken) : "";
|
||||
if(callback)
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
var p = location.pathname;
|
||||
fd_lang = p.substring(p.indexOf("commandref")+11,p.indexOf(".html"));
|
||||
@ -203,10 +224,5 @@ $(document).ready(function(){
|
||||
setTimeout(checkScroll, 500);
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
url:(location.pathname+"").replace(/\/docs.commandref.html.*/,"?XHR=1"),
|
||||
success: function(data, textStatus, request){
|
||||
csrfToken = request.getResponseHeader('x-fhem-csrftoken');
|
||||
csrfToken = csrfToken ? ("&fwcsrf="+csrfToken) : "";
|
||||
}});
|
||||
fd_csrfRefresh();
|
||||
});
|
||||
|
@ -8,7 +8,7 @@ var FW_serverLastMsg = FW_serverFirstMsg;
|
||||
var FW_isIE = (navigator.appVersion.indexOf("MSIE") > 0);
|
||||
var FW_isiOS = navigator.userAgent.match(/(iPad|iPhone|iPod)/);
|
||||
var FW_scripts = {}, FW_links = {};
|
||||
var FW_docReady = false, FW_longpollType;
|
||||
var FW_docReady = false, FW_longpollType, FW_csrfToken;
|
||||
var FW_root = "/fhem"; // root
|
||||
var embedLoadRetry = 100;
|
||||
|
||||
@ -70,6 +70,7 @@ FW_jqueryReadyFn()
|
||||
FW_longpollType = $("body").attr("longpoll");
|
||||
if(FW_longpollType != "0")
|
||||
setTimeout("FW_longpoll()", 100);
|
||||
FW_csrfToken = $("body").attr('fwcsrf');
|
||||
|
||||
$("a").each(function() { FW_replaceLink(this); })
|
||||
$("head script").each(function() {
|
||||
@ -366,29 +367,47 @@ log(txt)
|
||||
function
|
||||
addcsrf(arg)
|
||||
{
|
||||
var csrf = $("body").attr('fwcsrf');
|
||||
if(csrf && arg.indexOf('fwcsrf') < 0)
|
||||
arg += '&fwcsrf='+csrf;
|
||||
if(FW_csrfToken) {
|
||||
arg = arg.replace(/&fwcsrf=[^&]*/,'');
|
||||
arg += '&fwcsrf='+FW_csrfToken;
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
function
|
||||
FW_csrfRefresh(callback)
|
||||
{
|
||||
log("FW_csrfRefresh");
|
||||
$.ajax({
|
||||
url:location.pathname+"?XHR=1",
|
||||
success: function(data, textStatus, request){
|
||||
FW_csrfToken = request.getResponseHeader('x-fhem-csrftoken');
|
||||
if(callback)
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function
|
||||
FW_cmd(arg, callback)
|
||||
{
|
||||
log("FW_cmd:"+arg);
|
||||
arg = addcsrf(arg);
|
||||
arg += '&fw_id='+$("body").attr('fw_id');
|
||||
var req = new XMLHttpRequest();
|
||||
req.open("POST", arg, true);
|
||||
req.send(null);
|
||||
req.onreadystatechange = function(){
|
||||
if(req.readyState == 4) {
|
||||
$.ajax({
|
||||
url:addcsrf(arg)+'&fw_id='+$("body").attr('fw_id'),
|
||||
method:'POST',
|
||||
success: function(data, textStatus, req){
|
||||
if(callback)
|
||||
callback(req.responseText);
|
||||
else if(req.responseText)
|
||||
FW_errmsg(req.responseText, 5000);
|
||||
},
|
||||
error:function(xhr, status, err) {
|
||||
if(xhr.status == 401 && FW_csrfToken) {
|
||||
FW_csrfToken = "";
|
||||
FW_csrfRefresh(function(){FW_cmd(arg, callback)});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function
|
||||
@ -1470,8 +1489,6 @@ loadScript(sname, callback, force)
|
||||
}
|
||||
script.onload = function(){
|
||||
scriptLoaded();
|
||||
// if(FW_isiOS) // Fixed in the maintime/not needed with 10.2
|
||||
// FW_longpoll();
|
||||
}
|
||||
}
|
||||
h.appendChild(script);
|
||||
|
Loading…
x
Reference in New Issue
Block a user