QubesOS / qubes-issues

The Qubes OS Project issue tracker
https://www.qubes-os.org/doc/issue-tracking/
534 stars 46 forks source link

DispVMs based on DVM template with default value of `default_dispvm` always have the DVM template itself as `default_dispvm` #8680

Open emanruse opened 10 months ago

emanruse commented 10 months ago

Qubes OS release

4.1.2

Brief summary

Setting default_dispvm to the default value (the one set through Qubes Global Settings, section "qube defaults") for DVM templates results in DispVMs always having the DVM template itself as their default_dispvm.

Steps to reproduce

  1. In Qubes Global Settings, set disposable template = minimal-offline-dvm.

  2. Create an AppVM, making it a DVM template (e.g. TEST-dvm), setting its default_dispvm = (default) minimal-offline-dvm.

  3. Start a disposable based on TEST-dvm (e.g. disp123).

Expected behavior

disp123's default_dispvm should be minimal-offline-dvm (as set).

Actual behavior

disp123's default_dispvm is TEST-dvm.

Additional notes:

To have TEST-dvm based disposables have the desired default_dispvm, it must be set explicitly to "minimal-offline-dvm", not to the "(default) minimal-offline-dvm". Only then it works as expected.

Discussion

Edit: typo

rustybird commented 10 months ago

It's intentional: https://github.com/QubesOS/qubes-core-admin/commit/89624525029bcc7382a7f1ea1c2af5d6d99bb29c

But maybe the UI should show a hint in this situation.

emanruse commented 10 months ago

On the link you provide, the explanation says:

"This prevent various isolation bypass cases, like using a chain of DispVMs to access network."

While this may be valid in some cases, in others it would actually assist network leaks.

Example scenario:

  1. Receive a malicious email attachment in AppVM "my-mail"
  2. Save the file in some folder and run "View in VM" for it

Result:

The file is opened in a DispVM which has the same network connectivity as "my-mail", i.e. it is able to connect (at least) to the mail server. If the received file is a mail server exploit, it will be able to do its job and reach the mail server, potentially causing harm. So, the expected protection this intentional feature is supposed to provide would not work at all.

If the actual reasoning is really to protect from unwanted network connections, then it would be much safer if one uses a globally default offline default_dispvm and that setting is respected, rather than overridden. That is what I actually tried until I found that it doesn't work.

While it is still possible to set this individually and explicitly for each DVM template, that practically makes the global setting of default_dispvm partially useless because:

  1. From security viewpoint: It is misleading and confusing. In Qubes Global Settings one reads "Set your system's default qubes", so if any qube uses the default_dispvm, then it is expected to be that. But it is not, so various insecure scenarios are possible.

  2. From usability viewpoint: one has to do extra work to do what the UI promised but did not provide.

What do you think?

rustybird commented 10 months ago
  1. Receive a malicious email attachment in AppVM "my-mail"
  2. Save the file in some folder and run "View in VM" for it

"View in DisposableVM", right?

Result: The file is opened in a DispVM which has the same network connectivity as "my-mail"

No, this would result in a DisposableVM whose template is my-mail's default_dispvm if explicitly set or the system-wide default_dispvm otherwise, because the DisposableVM is spawed by an AppVM. The quirk only matters if a DisposableVM is spawned by a DisposableVM.

It would be possible apply this quirk even more narrowly, to only DisposableVMs spawned by a DisposableVM with auto_cleanup==True edit: or rather a disp-created-by- tag (e.g. by a disp1234 but not by a disposable sys-usb)

emanruse commented 10 months ago

"View in DisposableVM", right?

Yes, sorry.

The quirk only applies if a DisposableVM is spawned by a DisposableVM.

You are right. That can still be a security problem though. Example:

  1. Run a browser in a DispVM with DVM having default_dispvm = global default, i.e. not explicitly set
  2. Download an infected/malicious file
  3. "View in DisposableVM" that file

Result:

It will open in another DispVM, having the same network connectivity as the first one. Hence, it will still be able to do network mischief, e.g. "call home", possibly also sending some info, thus notifying that someone downloaded and opened it (which may be the first step to something bigger the attacker is planning).

IOW, the supposed protection justifying how this is made to work, simply doesn't protect. It just ensures that every next "inherited" DispVM along the chain has the same network connectivity.

Additionally, we have these 2 default values, one global and one implicitly taking precedence. Normally, security implies simplicity. Here we have a confusing extra complexity facilitating possible mistakes by the user.

rustybird commented 10 months ago

Basically a tradeoff between two possible misconfigurations. The current behavior does seem like the lesser evil to me, but it's unintuitive and undocumented.

Besides improving the docs/UI, I wonder if (in the implicit case) we should also set the child DisposableVM's netvm to None? That doesn't look completely trivial to implement though.

emanruse commented 10 months ago

Besides improving the docs/UI, I wonder if (in the implicit case) we should also set the child DisposableVM's netvm to None?

That would improve security (confidentiality), but then opening links in the default DisposableVM will stop working, which may cause additional confusion, especially to an unexperienced user. Then he may start looking for ways to "fix" it, thus possibly creating even worse misconfigurations.

Perhaps, the most cleanest thing is to split the current menu in two:

Both will use the global default_dispvm (unless another has been explicitly set in the AppVM), just in the second case the action will force the DisposableVM to have netvm=none.

adrelanos commented 10 months ago

default_disvm -> default_dispvm? Please edit.

andrewdavidwong commented 10 months ago

It looks like this was part of the resolution for QSB-47:

[...]

To mitigate this problem, we are implementing two changes:

  1. When a DisposableVM is started, automatically set its default_dispvm to the DVM Template on which it is based. This means that, when a DisposableVM is started from another DisposableVM, they will both be based on the same DVM Template. Hence, they will have all the same settings, including the same network settings. This change will not affect DVM Templates for which user has manually modified the default_dispvm property.

[...]

emanruse commented 10 months ago

Also related:

https://forum.qubes-os.org/t/are-qubes-really-isolated-security-questions/18497/18

@andrewdavidwong

Considering the significance of this, wouldn't it be more appropriate to have an actual fix, rather than a mitigation?

The listed resolution is not quite efficient because:

  1. [...] Hence, they will have all the same settings, including the same network settings.

This may not match one's intention of opening a file in a DispVM (e.g. for the purpose of not allowing a potentially dangerous file to connect to the Internet)

  1. Add a warning message in the Qube Settings GUI when the NetVM of a qube in the "Basic" tab is set to a different value than the NetVM of the default DVM Template set in the "Advanced" tab.

As also discussed in the forum thread, that's too unnoticeable. In fact, it is noticeable only if the directly specified default_dispvm has different netvm. If the VM is part of a chain (as demonstrated in the forum post), there is no visual cue whatsoever, although the VM is just as vulnerable to the issue as a non-chained one.

What makes this even more confusing (from UI/UX perspective) is that this also conflicts the red message (in section Firewall) which says "This qube has no net qube. It will not be have any access anyway." (obviously based only on the netvm setting).

andrewdavidwong commented 10 months ago

@emanruse: The second part is off-topic for this issue. Every issue must be about a single, actionable thing. Please feel free to open a separate issue for that, if one doesn't exist already.

andrewdavidwong commented 10 months ago

@emanruse: The second part is off-topic for this issue. Every issue must be about a single, actionable thing. Please feel free to open a separate issue for that, if one doesn't exist already.

Opened #8688 for this.

ben-grande commented 10 months ago

I disagree with this thread continuing further for the following reasons:

If this thread continues further, it would make more sense to fix the problem by being explitcit on the qube manager and on the qvm-prefs setting that the correct default_dispvm for each diposable template is the disposable template itself.

emanruse commented 10 months ago
  • It has already been explained to the user that that it is intentional

Please kindly note that the user has understood and has also shown that this intention may not match the overall OS's intent of security. Additionally, it was shown that this intentional design is confusing and misleading, unless one is specifically educated about it (which is not the general case).

  • In case the qube is still pristine and not infected, having the disposable template be the the DVM itself is more intuitive and keep the same chain of qubes than basing on the parent setting of default_dispvm.

When you say "it is more intuitive", is this a fact or an opinion?

I am asking because it is a major UI design principle to have the interface reflect actuality (facts), not designer's gut feeling. If the UI says global default_dispv=X, then it must be X by default and nothing else. If special UI hints, documentation etc. are necessary to explain that "even if set to X, this doesn't mean it is always X, only in cases when... and in other cases ..." this is not adding clarity, it is just reaffirming the poor design. A good and secure design is simple, straightforward, and needs no clarifications - "Walk/Don't walk".

So, if what you say about intuitive is a fact, it should come with proper verifiable evidence. Personally, I could not speak for other's intuition without actual statistical data from test cases.

If it is an opinion, and if community's voice matters, here is another opinion too: when one installs a security focused OS, one expects security by default, not complicated paths to it, allowing insecurities in-between.

If this thread continues further, it would make more sense to fix the problem by being explitcit on the qube manager and on the qvm-prefs setting that the correct default_dispvm for each diposable template is the disposable template itself.

I understand you are willing to stop this discussion by enforcing this viewpoint, however please note that this would contradict everything explained above.

Forgive me for the long reply. The user will keep quiet from now on.

ben-grande commented 10 months ago

Please kindly note that the user has understood and has also shown that this intention may not match the overall OS's intent of security. Additionally, it was shown that this intentional design is confusing and misleading, unless one is specifically educated about it (which is not the general case).

I agreed with you it is misleading the way it is treated in the preferences list and the qube manager. The fix is not however a regression, but showing the disposable template it is actually going to use.

When you say "it is more intuitive", is this a fact or an opinion?

Opinion.

I am asking because it is a major UI design principle to have the interface reflect actuality (facts), not designer's gut feeling. If the UI says global default_dispv=X, then it must be X by default and nothing else. If special UI hints, documentation etc. are necessary to explain that "even if set to X, this doesn't mean it is always X, only in cases when... and in other cases ..." this is not adding clarity, it is just reaffirming the poor design. A good and secure design is simple, straightforward, and needs no clarifications - "Walk/Don't walk".

I agree the UI should reflect the facts, currently they don't. The fix however is to show the facts, not to revert to use the global disposable template.

Where itself is the actual disposable template name.

In both cases, it needs explanation to why it is happening, why templates are non networked, it is documented. What is not documented is the disposable template of a disposable template default setting and its preference and manager counterpart.

So, if what you say about intuitive is a fact, it should come with proper verifiable evidence. Personally, I could not speak for other's intuition without actual statistical data from test cases.

If it is an opinion, and if community's voice matters, here is another opinion too: when one installs a security focused OS, one expects security by default, not complicated paths to it, allowing insecurities in-between.

I agree the paths should be easy. You are however biased on using a disposable based on a disposable template of the setting of the disposable template of itself. This is advanced usage and no normal user does this. This is a complicated path. Non-advanced users don't open disposables from disposables.

I understand you are willing to stop this discussion by enforcing this viewpoint, however please note that this would contradict everything explained above.

We agree the current UI doesn't reflect the reality. We disagree on the outcome.

emanruse commented 10 months ago

I was willing to stay quiet but OK.

You are however biased on using a disposable based on a disposable template of the setting of the disposable template of itself.

I outlined actual observable facts. I don't understand how facts can be biased. Or what do you mean?

This is advanced usage and no normal user does this. This is a complicated path. Non-advanced users don't open disposables from disposables.

This could add weight to your opinion, if you add:

We disagree on the outcome.

The outcome you suggest means:

My suggestion is simpler:

Global default_dispvm=none (by default, after clean OS installation) and every qube should respect that value unless explicitly changed for individual qubes.

Then everything about newly created qubes will be clear, simple (no "complicated path") and safe by default. The documentation will also be simpler and clearer.