HomeAbout

How Canvas Apps Use Clipboard to Copy Controls

By Denis Molodtsov
Published in Canvas Apps
April 29, 2023
5 min read
How Canvas Apps Use Clipboard to Copy Controls

Table Of Contents

01
Azure Storage BLOB and Clipboard Integration
02
What's in the BLOB?
03
Hacking the Clipboard
04
Every time you press CTRL+C, you essentially copy your data to the Internet
05
Conclusion

Have you ever wondered how Canvas Apps use the clipboard when you copy and paste controls across the app? You might be surprised to learn that Canvas Apps use Azure Storage BLOB to store the copied controls. Each time you press CTRL+C, you create a new BLOB in Azure storage.

Azure Storage BLOB and Clipboard Integration

When copying Canvas Apps controls, two main things happen:

  1. The controls are serialized into JSON and stored in Azure Storage BLOB.
  2. The URL to the BLOB is copied to your clipboard.

Using https://evercoder.github.io/clipboard-inspector/, we can peek inside the clipboard. Here’s an example of the clipboard content:

evercoder

Let’s explore what this contains. Turns out, the clipboard content is an HTML document. In clipboard, HTML is represented as a string with the following format:

<html>
<body>
<!--StartFragment-->
...HTML content...
<!--EndFragment-->
</body>
</html>

The text inside HTML is a JSON object with two properties:

  • a unique session ID
  • a URL to the Azure storage BLOB.
{
"sessionId":"2c9ca29f-706d-4d32-98b5-75bc515b15ff",
"blobUri":"https://docserverpwaprodcca.blob.core.windows.net/f39c3853-3888-471a-8d70-bf34a6ed861c-1/copyResult/copyResult?sv=2018-03-28&sr=b&sig=SZizVY02EFXWxj1whS3i74tphUnVVA57QazdbWaib2M%3D&spr=https&se=2023-04-30T21%3A44%3A39Z&sp=r"
}

Let’s break down the format of this blobUri URL to understand its structure better:

  1. https://docserverpwaprodcca.blob.core.windows.net: This is the base URL for accessing the Azure BLOB storage service. It consists of Microsoft’s storage account name (docserverpwaprodcca), and the domain name for Azure BLOB storage (blob.core.windows.net).

  2. /f39c3853-3888-471a-8d70-bf34a6ed861c-1/copyResult/copyResult: the path to the specific BLOB containing the copied control data. It consists of a unique identifier (f39c3853-3888-471a-8d70-bf34a6ed861c-1) and the nested path within the storage container (copyResult/copyResult).

  3. sv=2018-03-28: version of the Azure BLOB storage service being used (2018-03-28).

  4. sr=b: type of Azure storage resource being accessed. In this case, b stands for “BLOB”.

  5. sig=SZizVY02EFXWxj1whS3i74tphUnVVA57QazdbWaib2M%3D: authentication signature for the request, which is generated using the storage account access key. It is URL-encoded, with %3D representing the = character.

  6. se=2023-04-30T21%3A44%3A39Z: expiry time of the URL, which is set to 2023-04-30T21:44:39Z (in ISO 8601 format). It means that the URL will expire after 24 hours.

  7. sp=r: permissions granted for the request. Here, r stands for “read”, which means the URL allows read access to the BLOB.

What’s in the BLOB?

To view the BLOB, we can open its URL in a web browser and see what it returns. Here’s a shortened example of the BLOB content:

{
"LastCopyTime": "2023-04-29T21:29:55.7013443+00:00",
"CopiedDataKind": 0,
"Data": "{\"SourceDocumentVersion\":\"1.330\",\"ClientSessionId\":\"2c9ca29f-706d-4d32-98b5-75bc515b15ff\",\"CorrelationId\":\"7a915036-60eb-4feb-a32f-fa1ec24b1d87\",\"Entities\":[{\"Type\":\"ControlInfo\",\"Name\":\"TemplateDropdown\",\"HasDynamicProperties\":false}],\"ControlNames\":[\"TemplateDropdown\"]}"
}

This blob is a text document containing JSON data related to the Canvas Apps controls. It includes various properties, settings, and metadata about the controls, such as types, names, layouts, styles, rules, and more. Here’s an overview of the main elements in the JSON data:

  1. LastCopyTime: The timestamp of when the control was last copied. In this case, it is 2023-04-29T21:29:55.7013443+00:00.

  2. CopiedDataKind: An integer value representing the type of data copied. Here, it is set to 0.

  3. Data: The main object containing all the control-related data. It has several key-value pairs:

    • SourceDocumentVersion: The version of the source document, which is 1.330.

    • ClientSessionId: A unique identifier for the client session, which is 2c9ca29f-706d-4d32-98b5-75bc515b15ff.

    • CorrelationId: A unique identifier for the correlation, which is 7a915036-60eb-4feb-a32f-fa1ec24b1d87.

    • Entities: An array containing various information about the Canvas Apps control, including its type, name, metadata, properties, and rules. This array contains one object for the “TemplateDropdown” control, which has numerous properties and rules related to its design, layout, and functionality.

    • ControlNames: An array containing the names of the controls. In this case, it has only one item: “TemplateDropdown”.

The JSON data stored in the BLOB provides a detailed snapshot of the Canvas Apps control, which can be used to recreate the control when pasted across screens or even browsers.

In theory, I can share this BLOB with you via a URL, and you can use it to paste the control into your Canvas Apps. However, it won’t work forever because the BLOB URL is only valid for 24 hours. After that, it will expire, and you won’t be able to access it.

When pasting the controls, the URL is read from the clipboard, and the controls are deserialized from the BLOB.

Hacking the Clipboard

Serialized Canvas App controls BLOB only lasts for 24 hours. So you are good to go if you copy a control and paste it into another Canvas app within 24 hours. However, I can’t imagine a case where you would want to copy a control, wait for that long and then click CTRL+V to paste it. So 24 is plenty of time.

However, I hoped to find a way to extract the BLOB from the clipboard and store it elsewhere to be used for longer than 24 hours. Imagine a web page that contains all sorts of reusable Canvas Apps controls that you can copy and paste into your apps without installing any custom components.

As part of an experiment, I tried hosting copied serialized JSON data in my Azure BLOB and even on GitHub. For example:

https://gist.githubusercontent.com/Zerg00s/5f336dfb07ebe34cd80138d89b86e255/raw/9ad76c0cb7ce45711b8104a563013b6f9da85f2e/Contro.txt

I also wrote a PowerShell script to mimic the CTRL+C behavior of the Canvas app. This script can inject a custom URL into the clipboard, the same as Canvas Apps do. This URL points to the JSON data stored in my Azure BLOB storage or GitHub. Here is an example:

Add-Type -AssemblyName System.Windows.Forms
function Write-HtmlToClipboard {
param (
[Parameter(Mandatory = $true)]
[string]$Html
)
$htmlHeader = @"
Version:1.0
StartHTML:<<<<<<<1
EndHTML:<<<<<<<2
StartFragment:<<<<<<<3
EndFragment:<<<<<<<4
"@
$startHtml = $htmlHeader.Length - 28
$preHtml = @"
<html>
<body>
<!--StartFragment-->
"@
$postHtml = @"
<!--EndFragment-->
</body>
</html>
"@
$startFragment = $startHtml + $preHtml.Length
$endFragment = $startFragment + $Html.Length
$endHtml = $endFragment + $postHtml.Length
$htmlHeader = $htmlHeader.Replace("<<<<<<<1", $startHtml.ToString("D10"))
$htmlHeader = $htmlHeader.Replace("<<<<<<<2", $endHtml.ToString("D10"))
$htmlHeader = $htmlHeader.Replace("<<<<<<<3", $startFragment.ToString("D10"))
$htmlHeader = $htmlHeader.Replace("<<<<<<<4", $endFragment.ToString("D10"))
$clipboardHtml = $htmlHeader + $preHtml + $Html + $postHtml
[System.Windows.Forms.Clipboard]::SetText($clipboardHtml, [System.Windows.Forms.TextDataFormat]::Html)
}
$htmlContent = '{"sessionId":"a0c7c6e9-5f02-435f-b39e-99b798283ea","blobUri":"https://gist.githubusercontent.com/Zerg00s/5f336dfb07ebe34cd80138d89b86e255/raw/962acb21c3e8224abf03f2c71ce760893a0aa2aa/Contro.txt"}'
Write-HtmlToClipboard -Html $htmlContent

I must ensure that sessionID in the HTML document and ClientSessionId in the serialized JSON is the same.

When I tried pressing CTRL+V in another Canvas App, it didn’t work. Perhaps, it might be something to do with the nonexistent session ID? Or, perhaps Canvas Apps validates the URL and doesn’t allow pasting from external sources? If you have any ideas, please let me know

Every time you press CTRL+C, you essentially copy your data to the Internet

I know it sounds crazy, but every time you press CTRL+C, you copy your data to the Internet. The data is stored in Azure Storage BLOB, a cloud-based storage solution. The good news is that the BLOB’s URL is literary impossible to guess. There are just too many parameters to the URL. So, it’s not like anyone can guess the URL and access your data. However, you might want to be careful when copying sensitive data, like passwords, credit card numbers, or other personal information. Of course, it’s hard to imagine a scenario where you would copy such data in a Canvas App, but you never know.

Conclusion

So, we took a deep dive into how Canvas Apps uses the clipboard when you copy and paste controls within the app. The controls get turned into JSON and stored in Azure Storage BLOB, and the clipboard gets the link to the BLOB. The BLOB holds all the juicy info about the control, like its design, layout, and all that good stuff. And when you paste, the app uses the info from the BLOB to bring the control back to life. Cool, huh? We also attempted to extend the lifetime of the serialized Canvas App controls by hosting the JSON data in an external location and injecting a custom URL into the clipboard. However, our attempt was unsuccessful, and the pasted control did not work. Perhaps, the issue is due to a nonexistent session ID or Canvas Apps not allowing pasting from external sources.

Overall, this little adventure gives us a better understanding of how Canvas Apps magic works when copying and pasting controls and why we can’t keep them forever (even though we wish we could).


Tags

canvasapps

Share

Previous Article
How Canvas Apps Use Clipboard to Copy Controls
Denis Molodtsov

Denis Molodtsov

Microsoft 365 Architect

Quick Links

About

Social Media