What happens
GET /storagenode/{id} returns empty images and snapinfiles arrays for
every online node when the caller authenticates with an API token instead of a
browser session. The response is a normal 200. Nothing is logged.
The same thing happens inside the server: FOGMulticastManager and anything
else reaching Route::getItem('storagenode', $id) from a CLI daemon gets the
same empty lists.
The browser UI is unaffected, which is why this has not been obvious.
Why
Those two fields are not columns. StorageNode::_getData() builds each one by
making an HTTP request to status/getfiles.php on the node itself, and that
endpoint calls FOGCore::checkAuthAndCSRF().
The only credential FOGURLRequests had to offer was the caller's own PHP
session cookie. session_id() is '' in every CLI daemon and in any API
request authenticated by token, so there was nothing to forward, the inner
request was unauthenticated, and getfiles.php answered 401.
_getData() then does:
return preg_grep(
'#dev|postdownloadscripts|ssl#',
json_decode($response[0], true) ?? [],
PREG_GREP_INVERT
);
json_decode() of the 401 body is not an array, ?? [] turns it into an empty
one, and an authentication failure is served to the caller as "this node has no
images". Wrong data rather than an error.
Two problems, not one
- There is no credential a session-less FOG component can present. Fixing
that is an authentication decision, not a patch to _getData().
- Serializing a storage node fans out to that storage node. Every caller
pays two outbound HTTP requests to a machine that may be down, including the
many that never read the answer — FOGMulticastManager re-reads its master
nodes every MULTICASTSLEEPTIME (10s by default), and the storage group grid
serializes a master node per row. logfiles was already commented out in
Route::getter() for exactly this cost, which is the tell that the other two
should be opt-in rather than deleted a third time.
Found while fixing #1308/#1309 (an empty PHPSESSID= cookie minting a
throwaway session on the far side). Stopping that leak did not fix
authentication — it made the 401 honest.
What happens
GET /storagenode/{id}returns emptyimagesandsnapinfilesarrays forevery online node when the caller authenticates with an API token instead of a
browser session. The response is a normal 200. Nothing is logged.
The same thing happens inside the server:
FOGMulticastManagerand anythingelse reaching
Route::getItem('storagenode', $id)from a CLI daemon gets thesame empty lists.
The browser UI is unaffected, which is why this has not been obvious.
Why
Those two fields are not columns.
StorageNode::_getData()builds each one bymaking an HTTP request to
status/getfiles.phpon the node itself, and thatendpoint calls
FOGCore::checkAuthAndCSRF().The only credential
FOGURLRequestshad to offer was the caller's own PHPsession cookie.
session_id()is''in every CLI daemon and in any APIrequest authenticated by token, so there was nothing to forward, the inner
request was unauthenticated, and
getfiles.phpanswered 401._getData()then does:json_decode()of the 401 body is not an array,?? []turns it into an emptyone, and an authentication failure is served to the caller as "this node has no
images". Wrong data rather than an error.
Two problems, not one
that is an authentication decision, not a patch to
_getData().pays two outbound HTTP requests to a machine that may be down, including the
many that never read the answer —
FOGMulticastManagerre-reads its masternodes every
MULTICASTSLEEPTIME(10s by default), and the storage group gridserializes a master node per row.
logfileswas already commented out inRoute::getter()for exactly this cost, which is the tell that the other twoshould be opt-in rather than deleted a third time.
Found while fixing #1308/#1309 (an empty
PHPSESSID=cookie minting athrowaway session on the far side). Stopping that leak did not fix
authentication — it made the 401 honest.