{"id":110669,"date":"2024-12-20T07:00:00","date_gmt":"2024-12-20T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=110669"},"modified":"2024-12-20T17:52:19","modified_gmt":"2024-12-21T01:52:19","slug":"20241220-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20241220-00\/?p=110669","title":{"rendered":"How do I register a file type for a scripting language so that users get a warning when they run an untrusted script?"},"content":{"rendered":"<p>Occasionally we get security reports that go something like this:<\/p>\n<blockquote class=\"q\">\n<p>Install the ContosoScript scripting language interpreter. it uses the file extension <tt>.contososcript<\/tt>. Write a script that does \u27e6 something malicious \u27e7 and put it on a Web site so it can be downloaded. Download the script to your Downloads folder, and then run it by double-clicking it from Explorer.<\/p>\n<p>Notice that no warning appears. The ContosoScript interpreter runs the malicious script which \u27e6 something malicious \u27e7.<\/p>\n<\/blockquote>\n<p>There are other variations of this report, like putting the malicious script on a malicious file share, but they all boil down to &#8220;Nobody stopped me from running this malicious script!&#8221;<\/p>\n<p>Windows takes several things into consideration when deciding whether a file with a non-local source requires an extra warning before opening. The relevant one here is whether the file extension is considered &#8220;dangerous to use with untrusted files.&#8221;<\/p>\n<p>Identifying these dangerous extensions is done by the function <a href=\"https:\/\/learn.microsoft.com\/en-us\/windows\/win32\/api\/shlwapi\/nf-shlwapi-associsdangerous\"> <tt>AssocIsDangerous()<\/tt><\/a>, and it consults a hard-coded list of known dangerous extensions (like <tt>.bat<\/tt> and <tt>.reg<\/tt>) as well as checking whether the file type reports itself as dangerous.<\/p>\n<p>The <a title=\"Programmatic Identifiers: Programmatic Identifier Elements Used by File Associations\" href=\"https:\/\/learn.microsoft.com\/en-us\/windows\/win32\/shell\/fa-progids#programmatic-identifier-elements-used-by-file-associations\"> documentation for registering file types<\/a> calls out that &#8220;a ProgID subkey should include the following elements&#8221;, and one of them is the <tt>EditFlags<\/tt> registry value which allows the file type to report various attributes about itself. One of them is <a title=\"FILETYPEATTRIBUTES enumeration\" href=\"https:\/\/learn.microsoft.com\/en-us\/windows\/win32\/api\/shlwapi\/ne-shlwapi-filetypeattributeflags\"> <tt>FTA_Always\u00adUnsafe<\/tt><\/a>, which is documented as<\/p>\n<blockquote class=\"q\">\n<p>Prevents the <b>Never ask me<\/b> check box from being enabled. Use of this flag means <b>FTA_OpenIsSafe<\/b> is not respected and <span style=\"border: solid 1px currentcolor;\"> <a href=\"https:\/\/learn.microsoft.com\/en-us\/windows\/win32\/api\/shlwapi\/nf-shlwapi-associsdangerous\"> AssocIsDangerous<\/a> always returns <b>TRUE<\/b><\/span>.<\/p>\n<p style=\"border: solid 1px currentcolor;\">If your file type can execute code, you should always use this flag or ensure that the file type handlers mitigate risks, for example, by producing warning prompts before running the code.<\/p>\n<\/blockquote>\n<p>If your file type has the ability to execute code when opened (for example, if it is a scripting language interpreter), then set the <tt>FTA_Always\u00adUnsafe<\/tt> flag in your type registration to indicate that it is &#8220;unsafe at any speed.&#8221;<\/p>\n<p>If your file type is registered via a manifest, you can set this flag by <a href=\"https:\/\/learn.microsoft.com\/en-us\/uwp\/schemas\/appxpackage\/uapmanifestschema\/element-uap-editflags\"> specifying the <tt>AlwaysUnsafe<\/tt> attribute in your <tt>uap:EditFlags<\/tt> element<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Use the FTA_AlwaysUnsafe edit flag.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-110669","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Use the FTA_AlwaysUnsafe edit flag.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110669","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=110669"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110669\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=110669"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=110669"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=110669"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}