Windows API – Information disclosure / covert channel

by Prapattimynk, Sunday, 17 September 2023 (5 months ago)
Windows API – Information disclosure / covert channel

I use open-source software every day. And I try to contribute as much
as I can.

However, sometimes weird things happen when writing OSS code. Like finding a security bug in a closed source software.

Note: there is a TL;DR at the end of the post.

I’m using restic for backup at home. It’s a lovely, lightweight, and well-designed backup utility. It also runs on my NAS, which is a delightful surprise for me.

Restic supports many backends (some natively, some others leveraging on rclone, another fantastic utility). It also supports a simple REST backend, named rest-server. The advantage of rest-server is that it’s “restic-aware”, so it can force things like “append-only mode” or “per-user repositories” server-side.

No doubt that rest-server is a good choice when running daemons on storage nodes.


If you deploy a project in Kubernetes, Docker, or some other orchestration tool, you might leverage on health checks (readiness/liveness). Long story short, these APIs can report to the orchestrator the current “health” of the application so that the orchestrator can decide what to do (e.g., re-schedule the instance, temporarily put that instance out of the load balancer, etc.).

This is also true when using “plain-old” load balancers in non-orchestrated environments.

@anguslees opened an issue a few months ago saying that he is deploying rest-server on Kubernetes. He made a “feature request”: a health check endpoint so he can instruct Kubernetes to monitor rest-server. I immediately picked that request, as I enjoy helping OSS projects.

What to check?

There are a lot of good articles on the internet on how to do good health checks. In this case, as rest-server doesn’t have external dependencies except for the local storage, my goal was to write Go subroutines to check whether the process has all necessary permissions and there is enough space.

I was looking for a cross-platform solution. Luckily, writing multi-platform code in Go is straightforward: you can create different files: they will be included in the build process only if the platform matches the file suffix (e.g., _windows.go). Also, calling UNIX syscalls and Windows APIs is straightforward.

Check directory permissions on Windows

To have rest-server behave correctly in Windows, I had to implement a permission check subroutine. However, while in UNIX/Linux I can check permission bits, on Windows we need to deal with NTFS ACLs.

That’s not entirely true: Linux supports filesystem ACLs, also the whole filesystem might be read-only, and the process might be confined using SELinux or AppArmor. However, a simple permissions bit check on the directory is a good start.

Dealing with ACLs is hard when you need to decode and analyze them. And I’m lazy. Damn lazy. So I opened the Windows API documentation, and I tried some API calls.


I did some tests using C. Why? Because I went from “boring-search-of-an-API” mode to “lets-play-with-APIs-and-break-something” mode.


I was testing the CreateFile API to open a file for reading its attributes. It was one of the checks that I planned to do. The call parameters are:

  • Opening a file at the path C:\Users\Alice\Desktop\cv.doc
  • I was asking to read the file attributes: FILE_READ_ATTRIBUTES
  • I was willing to share the file access for reading, writing, or deleting (meaning no locks): FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE
  • No security attributes
  • I asked CreateFile to open the file only if the file already existed: OPEN_EXISTING
  • No flags and no attributes were specified, and
  • No template (this parameter is ignored when opening an existing file)

Let assume that I’m Alice from now on. I tried the call above (the file was there), and it works. So far, so good.

What if the file exists but it’s in a directory where the current user doesn’t have access?


GetLastError() is returning “Access denied”. Good. I mean, I should not have access to Bob’s desktop.

What if the file doesn’t exist?


GetLastError() is returning “Not found”. OOOPS!

So yes, if you use this Windows API, you can tell if the file exists even if you don’t have access to the underlying path.

In security terms, this vulnerability is named Information disclosure: Alice was not supposed to get any information about Bob. Also, this bug can be exploited for “covert channels” or “side channels”: unintended communication channels between two users who should not be allowed to exchange data.

Microsoft Researcher Portal

I quickly opened a case in Microsoft Researcher Portal: case number #66958. After few days, Microsoft acknowledged the issue (VULN-053244). However, they told me that this doesn’t qualify for a security update so that the fix will be released as usual. Also, they said that I could share these details in public based on their responsible disclosure policy.

  • During my work on Restic rest-server and Windows API, I discovered an Information disclosure security issue with CreateFile API. I can tell if a specific file exists or not, even if I don’t have access to the directory where the file is in.
  • I’ve opened case #66958 on Microsoft Researcher Portal immediately (Mon, 23 Aug 2021 17:33:55 +0000)
  • Microsoft acknowledged on Tue, 31 Aug 2021 14:41:44 +0000. The vulnerability was rated as a “moderate information disclosure”. According to their policy, this issue will not be addressed using “security updates” but using regular updates.


Your email address will not be published. Required fields are marked *

Ads Blocker Image Powered by Code Help Pro

AdBlocker Detected!!!

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.