]> granicus.if.org Git - icinga2/commitdiff
Don't allow scripts to access FANoUserView attributes in sandbox mode
authorGunnar Beutner <gunnar@beutner.name>
Mon, 26 Oct 2015 09:41:00 +0000 (10:41 +0100)
committerGunnar Beutner <gunnar@beutner.name>
Mon, 26 Oct 2015 09:41:00 +0000 (10:41 +0100)
fixes #10457

lib/config/expression.cpp
lib/config/vmops.hpp

index 1c4dcea293d2859f285516ab345c032028e28b77..5290a9897e41f0cd00ca75f06f2eba02ec8e718b 100644 (file)
@@ -99,7 +99,7 @@ ExpressionResult VariableExpression::DoEvaluate(ScriptFrame& frame, DebugHint *d
        if (frame.Locals && frame.Locals->Get(m_Variable, &value))
                return value;
        else if (frame.Self.IsObject() && frame.Locals != static_cast<Object::Ptr>(frame.Self) && VMOps::HasField(frame.Self, m_Variable))
-               return VMOps::GetField(frame.Self, m_Variable, m_DebugInfo);
+               return VMOps::GetField(frame.Self, m_Variable, frame.Sandboxed, m_DebugInfo);
        else
                return ScriptGlobal::Get(m_Variable);
 }
@@ -391,7 +391,7 @@ ExpressionResult FunctionCallExpression::DoEvaluate(ScriptFrame& frame, DebugHin
        String index;
 
        if (m_FName->GetReference(frame, false, &self, &index))
-               vfunc = VMOps::GetField(self, index, m_DebugInfo);
+               vfunc = VMOps::GetField(self, index, frame.Sandboxed, m_DebugInfo);
        else {
                ExpressionResult vfuncres = m_FName->Evaluate(frame);
                CHECK_RESULT(vfuncres);
@@ -504,7 +504,7 @@ ExpressionResult SetExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint)
        CHECK_RESULT(operand2);
 
        if (m_Op != OpSetLiteral) {
-               Value object = VMOps::GetField(parent, index, m_DebugInfo);
+               Value object = VMOps::GetField(parent, index, frame.Sandboxed, m_DebugInfo);
 
                switch (m_Op) {
                        case OpSetAdd:
@@ -606,7 +606,7 @@ ExpressionResult IndexerExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dh
        ExpressionResult operand2 = m_Operand2->Evaluate(frame, dhint);
        CHECK_RESULT(operand2);
 
-       return VMOps::GetField(operand1.GetValue(), operand2.GetValue(), m_DebugInfo);
+       return VMOps::GetField(operand1.GetValue(), operand2.GetValue(), frame.Sandboxed, m_DebugInfo);
 }
 
 bool IndexerExpression::GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint) const
@@ -624,13 +624,13 @@ bool IndexerExpression::GetReference(ScriptFrame& frame, bool init_dict, Value *
 
        if (m_Operand1->GetReference(frame, init_dict, &vparent, &vindex, &psdhint)) {
                if (init_dict) {
-                       Value old_value =  VMOps::GetField(vparent, vindex, m_Operand1->GetDebugInfo());
+                       Value old_value =  VMOps::GetField(vparent, vindex, frame.Sandboxed, m_Operand1->GetDebugInfo());
 
                        if (old_value.IsEmpty() && !old_value.IsString())
                                VMOps::SetField(vparent, vindex, new Dictionary(), m_Operand1->GetDebugInfo());
                }
 
-               *parent = VMOps::GetField(vparent, vindex, m_DebugInfo);
+               *parent = VMOps::GetField(vparent, vindex, frame.Sandboxed, m_DebugInfo);
                free_psd = true;
        } else {
                ExpressionResult operand1 = m_Operand1->Evaluate(frame);
@@ -706,7 +706,7 @@ ExpressionResult ImportExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhi
        if (frame.Sandboxed)
                BOOST_THROW_EXCEPTION(ScriptError("Imports are not allowed in sandbox mode.", m_DebugInfo));
 
-       String type = VMOps::GetField(frame.Self, "type", m_DebugInfo);
+       String type = VMOps::GetField(frame.Self, "type", frame.Sandboxed, m_DebugInfo);
        ExpressionResult nameres = m_Name->Evaluate(frame);
        CHECK_RESULT(nameres);
        Value name = nameres.GetValue();
index 0027a12d290dae726e79b2c959b192fbe81f07ae..760c5708a6cdd9b97623a842b6640d79e8f3320e 100644 (file)
@@ -50,7 +50,7 @@ public:
                if (frame.Locals && frame.Locals->Get(name, &value))
                        return value;
                else if (frame.Self.IsObject() && frame.Locals != static_cast<Object::Ptr>(frame.Self) && HasField(frame.Self, name))
-                       return GetField(frame.Self, name, debugInfo);
+                       return GetField(frame.Self, name, frame.Sandboxed, debugInfo);
                else
                        return ScriptGlobal::Get(name);
        }
@@ -219,7 +219,7 @@ public:
                        Object::Ptr object = type->GetPrototype();
 
                        if (object && HasField(object, field))
-                               return GetField(object, field, debugInfo);
+                               return GetField(object, field, false, debugInfo);
 
                        type = type->GetBaseType();
                } while (type);
@@ -230,7 +230,7 @@ public:
                        return Empty;
        }
 
-       static inline Value GetField(const Value& context, const String& field, const DebugInfo& debugInfo = DebugInfo())
+       static inline Value GetField(const Value& context, const String& field, bool sandboxed = false, const DebugInfo& debugInfo = DebugInfo())
        {
                if (context.IsEmpty() && !context.IsString())
                        return Empty;
@@ -277,6 +277,13 @@ public:
                if (fid == -1)
                        return GetPrototypeField(context, field, true, debugInfo);
 
+               if (sandboxed) {
+                       Field fieldInfo = type->GetFieldInfo(fid);
+
+                       if (fieldInfo.Attributes & FANoUserView)
+                               BOOST_THROW_EXCEPTION(ScriptError("Accessing the field '" + field + "' for type '" + type->GetName() + "' is not allowed in sandbox mode."));
+               }
+
                return object->GetField(fid);
        }