Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. How to isolate a QML item (<ifame> in QML?)
QtWS25 Last Chance

How to isolate a QML item (<ifame> in QML?)

Scheduled Pinned Locked Moved Solved QML and Qt Quick
isolationqqmlenginesandboxiframe
5 Posts 2 Posters 780 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    haiku
    wrote on 4 Oct 2020, 02:36 last edited by haiku 10 Apr 2020, 12:07
    #1

    Question:
    Is it possible to create a QML item which can not modify or access it's parent item?

    Context:
    I am developing a QML based application which has the ability to load user written qml files into the host application over the internet (think web browser). I do not want these user written qml components to reach outside themselves and interact with the host or other user written components for obvious security reasons. That means when these 3rd party qml items are displayed they must not be able to traverse up their own parent hierarchy.

    I have played around with creating components from C++ with their own separate QQmlEngine instances which works to a point. But as soon as I add these new objects into my application their parent sgets set and they can reach out.

    What I am basically looking for is a analogue to the <iframe> in HTML. Any pointers would be appreciated.

    Similar Questions:
    https://forum.qt.io/topic/73188/qml-sandboxing
    https://forum.qt.io/topic/78904/application-in-a-child-process
    https://forum.qt.io/topic/45356/solved-qml-sandboxing-of-components
    https://forum.qt.io/topic/42348/embedding-a-qwindow-inside-a-qml-scene

    1 Reply Last reply
    0
    • H Offline
      H Offline
      haiku
      wrote on 11 Oct 2020, 20:55 last edited by
      #5

      I've just tested out the QQuickWidget class and it's working as I hoped. I can give each QQuickWidget it's own separate QMLEngine instance and the qml items inside each widget are not able to reach out into Qt widget land.

      There are still a few issues I'm looking into though regarding displaying one QQuickWidget over another. I've worked out how to make the top widget transparent but I'm still looking into event handling and how to stop the top QQuickWidget from eating events that should really be processed by the bottom QQuickWidget. I'm sure it's possible though.

      It's a shame that this isn't possible from QML itself. It'd be lovely to have a option you just pass to a Loader to say to sandbox the loaded item or something along those lines but this will work for now.

      1 Reply Last reply
      0
      • H Offline
        H Offline
        haiku
        wrote on 4 Oct 2020, 13:18 last edited by
        #2

        Here is an example of what I am trying to stop for those who want to see some code:

        It shows a component loaded by a loader reaching outside itself and reading the secret property on the root item.

        import QtQuick 2.15
        
        Rectangle {
            id: root
            anchors.fill: parent
            
            // The untrustedComponent should not be able to access this
            property string secret: "super secret string"
            
            // Imagine that this source component was actually loaded from a third party http server
            Component {
                id: untrustedComponent
                
                Rectangle {
                    anchors {
                        margins: 20
                        fill: parent
                    }
                    color: '#dddddd'
                    
                    Text {
                        anchors.centerIn: parent
                        text: {
                            // Iterate up the heierarchy to find the parent with the secret
                            var elements = 'Parent Items'
                            var i = 0
                            var currentItem = parent
                            while(currentItem !== null && currentItem !== undefined)
                            {
                                elements = elements + '\n' + i + ': ' + currentItem
                                    
                                if(currentItem.secret)
                                {
                                    elements = elements + '   FOUND SECRET: ' + currentItem.secret
                                }
                                
                                i = i + 1
                                currentItem = currentItem.parent
                            }
            
                            return elements
                        }
                    }
                }
            }
            
            Loader {
               
                id: untrustedComponentLoader
                anchors.fill: parent
                sourceComponent: untrustedComponent
            }
        }
        

        2822cc7f-6b43-460e-88d6-cd4ceedc9719-image.png

        1 Reply Last reply
        0
        • F Offline
          F Offline
          fcarney
          wrote on 5 Oct 2020, 21:43 last edited by
          #3

          QML is not sandboxable, nor is its javascript. Add a 3rd party scripting language that you can sandbox yourself. I don't know of any declarative languages like QML. So you may end up with just code or code plus XML or something similar.

          You can use LUA or add a version of V8 for this. I am sure there are others.

          C++ is a perfectly valid school of magic.

          1 Reply Last reply
          0
          • H Offline
            H Offline
            haiku
            wrote on 7 Oct 2020, 08:08 last edited by
            #4

            @fcarney from what I see you can assign different QMLEngines (which inherit from QJSEngine) to sandbox the JavaScript execution environments of two qml components. The problem I have is how to display one of these components inside the other. As soon as one is parented to the other then it can access the other through it's parent attribute (which I'm guessing reaches out into c++ land).

            One potential solution I have come across is to base the top level interface on QtWidgets and embed my qml views via the QQuickWidget class. I've yet to test this out though as I was hoping for a QML / C++ only solution.

            1 Reply Last reply
            0
            • H Offline
              H Offline
              haiku
              wrote on 11 Oct 2020, 20:55 last edited by
              #5

              I've just tested out the QQuickWidget class and it's working as I hoped. I can give each QQuickWidget it's own separate QMLEngine instance and the qml items inside each widget are not able to reach out into Qt widget land.

              There are still a few issues I'm looking into though regarding displaying one QQuickWidget over another. I've worked out how to make the top widget transparent but I'm still looking into event handling and how to stop the top QQuickWidget from eating events that should really be processed by the bottom QQuickWidget. I'm sure it's possible though.

              It's a shame that this isn't possible from QML itself. It'd be lovely to have a option you just pass to a Loader to say to sandbox the loaded item or something along those lines but this will work for now.

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved