question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Library doesn't work from sandboxed low-integrity process

See original GitHub issue

I’m experiencing problems using the Google Client libraries for .Net from a sandboxed low-integrity process. I’m suspecting that the problem is caused by the library attempting to write to C:\Users\<username>\AppData\Roaming\Google.Apis.Auth, which is read-only for low-integrity processes.

Suggested fixes:

  • Either, do not write to AppData\Roaming if running in low-integrity process (only store in-memory),
  • or, write configuration files to AppData\LocalLow if running in low-integrity process.

Steps to reproduce

  • Build https://github.com/youtube/api-samples/blob/master/dotnet/UploadVideo.cs into UploadVideo.exe
  • From a command prompt with admin permissions, run “icacls UploadVideo.exe /setintegritylevel Low” so that the executable will run in low integrity.
  • From a regular command prompt, run “UploadVideo.exe”.
  • Observe: “Error: Operation is not supported on this platform.

Environment:

  • Windows 10 1909 (x64).
  • Google.Apis version=“1.45.0” targetFramework=“net472”
  • Google.Apis.YouTube.v3 version=“1.45.0.1929” targetFramework=“net472”

Process explorer can be used to check if a process is running under low, medium or high integrity.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6

github_iconTop GitHub Comments

1reaction
jskeetcommented, Apr 29, 2020

TL;DR: The library works fine, but you need to avoid the process having to:

  • Write credentials to a file store
  • Launch a local web server to listen for codes
  • Launch a browser process

I’ve just tested to explicitly use NullDataStore in the sample. Unfortunately, it doesn’t seem to help.

I’ve just tested that, and it does help, or rather it at least makes a difference: it changes the nature of the error. It no longer tries to write to a file, but instead fails when it can’t construct an HttpListener - which is pretty reasonable in a low-integrity process. To avoid it having to create a web server to listen for the code being passed back from the browser, you can pass a PromptCodeReceiver to AuthorizeAsync too. At that point, it doesn’t crash - but it doesn’t launch the browser either, presumably for exactly the same reason. (Process.Start doesn’t throw an exception, which is a little odd.)

You can get round that problem by building your own ICodeReceiver based on PromptCodeReceiver, like this:

using Google.Apis.Auth.OAuth2;
using Google.Apis.Auth.OAuth2.Requests;
using Google.Apis.Auth.OAuth2.Responses;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Issue1551
{
    public class ConsoleOnlyCodeReceiver : ICodeReceiver
    {
        public string RedirectUri => GoogleAuthConsts.InstalledAppRedirectUri;
    
        public Task<AuthorizationCodeResponseUrl> ReceiveCodeAsync(AuthorizationCodeRequestUrl url,
            CancellationToken taskCancellationToken)
        {
            var authorizationUrl = url.Build().AbsoluteUri;
            Console.WriteLine("Please visit the following URL in a web browser, then enter the code shown after authorization:");
            Console.WriteLine(authorizationUrl);
            Console.WriteLine();

            string code = string.Empty;
            while (string.IsNullOrEmpty(code))
            {
                Console.WriteLine("Please enter code: ");
                code = Console.ReadLine();
            }
            return Task.FromResult(new AuthorizationCodeResponseUrl { Code = code });
        }
    }
}

That is able to authorize the user. I haven’t tried using the YouTube API, but I was able to use the credentials to list the storage buckets for my Cloud Project, so clearly the library is able to make requests and get responses.

The user experience is pretty awful at that point (copying and pasting URLs into a browser) but that’s just a fact of life when we don’t have the normal facilities available. If you’re able to authorize in a separate application first and store the access/refresh tokens somewhere that your application can get at them, that will avoid the problems you’re facing.

1reaction
jskeetcommented, Apr 28, 2020

I’ll have a look in the morning, but I suspect this is due to the sample using a file-based credential cache.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Sandbox
Most desktop applications run at medium integrity (MI), while less trusted processes like Internet Explorer's protected mode and our GPU sandbox run at...
Read more >
How can I check the integrity level of my process?
You can inspect a process's integrity level by calling GetTokenInformation and asking for TokenIntegrityLevel . For this trick, I'm going to ...
Read more >
Sandbox FAQ - Chromium Docs
The sandbox is a C++ library that allows the creation of sandboxed processes — processes that execute within a very restrictive environment. The...
Read more >
Thinking outside the sandbox
As a result of running as low integrity processes, sandboxed processes have limited ability to save files to the file system. Specifically, these...
Read more >
How to run Firefox in Protected Mode? (i.e. at low integrity ...
Unfortunately there is currently no way of running Firefox in Protected Mode. If you're not running 64-bit Windows, you can get something ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found