Skip to content

Commit c508d97

Browse files
jschmidt-icingajulianbrost
authored andcommitted
Remove TicketSalt in VariableQueryHandler as early as possible
This is to avoid another kind of exploit found by where TicketSalt can be accessed when the object filter is evaluated by checking its name via the local `variable` reference and then `throw`ing it to print it in the error message. Reported-by: julian.brost@icinga.com
1 parent 3900402 commit c508d97

File tree

1 file changed

+16
-8
lines changed

1 file changed

+16
-8
lines changed

lib/remote/variablequeryhandler.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,28 @@ class VariableTargetProvider final : public TargetProvider
2222
void FindTargets(const String& type,
2323
const std::function<void (const Value&)>& addTarget) const override
2424
{
25-
{
26-
Namespace::Ptr globals = ScriptGlobal::GetGlobals();
27-
ObjectLock olock(globals);
28-
for (const Namespace::Pair& kv : globals) {
29-
addTarget(FilterUtility::GetTargetForVar(kv.first, kv.second.Val));
25+
Namespace::Ptr globals = ScriptGlobal::GetGlobals();
26+
ObjectLock olock(globals);
27+
for (auto& [key, value] : globals) {
28+
/* We want wo avoid leaking the TicketSalt over the API, so we remove it here,
29+
* as early as possible, so it isn't possible to abuse the fact that all of the
30+
* global variables we return here later get checked against a user-provided
31+
* filter expression that can cause its content to be printed in an error message
32+
* or potentially access them otherwise.
33+
*/
34+
if (key == "TicketSalt") {
35+
continue;
3036
}
37+
38+
addTarget(FilterUtility::GetTargetForVar(key, value.Val));
3139
}
3240
}
3341

3442
Value GetTargetByName(const String& type, const String& name) const override
3543
{
44+
if (name == "TicketSalt") {
45+
BOOST_THROW_EXCEPTION(std::invalid_argument{"Access to TicketSalt via /v1/variables is not permitted."});
46+
}
3647
return FilterUtility::GetTargetForVar(name, ScriptGlobal::Get(name));
3748
}
3849

@@ -90,9 +101,6 @@ bool VariableQueryHandler::HandleRequest(
90101
ArrayData results;
91102

92103
for (const Dictionary::Ptr& var : objs) {
93-
if (var->Get("name") == "TicketSalt")
94-
continue;
95-
96104
results.emplace_back(new Dictionary({
97105
{ "name", var->Get("name") },
98106
{ "type", var->Get("type") },

0 commit comments

Comments
 (0)