自定义协议打开本地客户端程序遇上CSP内容安全策略

最近asp.net网站使用自定义协议打开本地客户端程序遇上Content-Security-Policy(内容安全策略)遇到一些问题,基于FastReport.net开发了一个web打印客户端,添加自定义协议支持,这样就实现了在各类浏览器中直接打开本地的客户端的功能

最近asp.net网站使用自定义协议打开本地客户端程序遇上Content-Security-Policy(内容安全策略)遇到一些问题,基于FastReport.net开发了一个web打印客户端,添加自定义协议支持,这样就实现了在各类浏览器中直接打开本地的客户端的功能,当然你可以实现在网页上点击一个链接打开任何程序,网页上打开QQ客户端就是这样实现的。

自定义协议打开本地客户端程序遇上CSP内容安全策略

Content-Security-Policy(内容安全策略)

作为网站安全策略的一部分,CSP在可以在服务器上实现,如果是asp.net开发的,或者asp.net mvc以及asp.net core等,可以在配置文件(web.config)里面添加相应的节点,如下:

<httpProtocol>
      <customHeaders>
           <add name="Content-Security-Policy" value="default-src 'self' jhrs:; style-src 'self' 'unsafe-inline';"/>
 </customHeaders>
</httpProtocol>

通过这样的配置就完成了内容安全策略设置。

自定义协议打开本地客户端程序

就像上面那个配置一样,我们配置了默认的default-src ‘self’,注意后面还跟随了【jhrs:】,这个jhrs就表示在我们的网页上应用了自定义协议,要打开jhrs桌面软件,应使用自定义协议单击链接,如下所示:

<a href="jhrs:https://jhrs/print?action=print&id=1234">直接打印</a>

就像你看到的上面那个链接一样,它的href是用jhrs开头的,这种写法就是通过自定义协议可以打开本地的客户端程序。

什么是自定义协议URI Scheme?

URI是统一资源标识符的简称(Uniform Resource Identifier),一个统一资源标识符(URI)是提供一个唯一的地址,其中一个资源可以被发现(无论是互联网或本地Intranet上)的字符串。它的外观与更常用的统一资源定位器(URL)相似,URL用于在这些站点中定位网站和页面。URL是一种URI。即,所有URL都是URI,但并非所有URI都是URL。URL通常标识要在浏览器中查看的网页。URI标识任何类型的资源,通常是指计算机要使用但不能在浏览器中查看的资源。URI通常标识资源,这些资源是使用Web本体语言(OWL)定义的本体的一部分。例如,代理中的类Agent或属性电子邮件朋友词汇表中的每个朋友都有一个单独的URI。的URI大多被替换为国际化资源标识符(IRI),其不同之处的IRI能处理字符集,如相同的URI汉字而不是被限制在ASCII作为URI是。

URI语法

每个URI以方案名称开头,该方案名称引用在该方案内分配标识符的规范。这样,URI语法是联合可扩展的命名系统,其中每个方案的规范可以进一步限制使用该方案的标识符的语法和语义。URI通用语法是所有URI方案的语法的超集。它首先在1998年8月发布的RFC  2396中定义在2005年1月发布的RFC  3986中最终确定

URI一般语法由五个的分层序列的组分

URI = scheme:[//authority]path[?query][#fragment]

通常在网页上想要打开本地客户端程序,可以通过自定义URI方案来实现。为此,请将现有应用程序注册为URI可插拔协议处理程序,并将其与自定义URI方案相关联。成功启动应用程序后,它可以使用命令行参数来检索启动它的URI。

安全警告:处理URI方案的应用程序必须考虑如何响应恶意数据。因为处理程序应用程序可以从不受信任的来源接收数据,所以传递给应用程序的URI和其他参数值可能包含试图利用处理程序应用程序的恶意数据。

本主题包含以下部分:

  • 注册处理自定义URI方案的应用程序
  • 启动处理程序
  • 安全问题
  • 示例可插拔协议处理程序
  • 相关话题

注册处理自定义URI方案的应用程序

要注册用于处理特定URI方案的应用程序,请向HKEY_CLASSES_ROOT中添加一个新键以及相应的子键和值。根密钥必须与要添加的URI方案匹配。例如,要添加“警报:”方案,请向HKEY_CLASSES_ROOT添加警报键,如下所示:

HKEY_CLASSES_ROOT
   alert
      URL Protocol = ""

在此新密钥下,URL协议字符串值指示此密钥声明了自定义可插拔协议处理程序。没有此密钥,处理程序应用程序将无法启动。该值应为空字符串。

还应该为DefaultIconshell添加密钥。DefaultIcon键的Default字符串值必须是用作此新URI方案的图标的文件名。字符串的形式为“ path,iconindex”,最大长度为MAX_PATH。shell键下的第一个键的名称应为动作动词,例如open。在此键下,命令键或DDEEXEC键指示应如何调用处理程序。命令DDEEXEC键下的值描述了如何启动处理新协议的应用程序。

最后,默认字符串值应包含新URI方案的显示名称。以下示例显示了如何注册一个应用程序(在这种情况下,alert.exe)来处理警报方案。

HKEY_CLASSES_ROOT
   alert
      (Default) = "URL:Alert Protocol"
      URL Protocol = ""
      DefaultIcon
         (Default) = "alert.exe,1"
      shell
         open
            command
               (Default) = "C:\Program Files\Alert\alert.exe" "%1"

当用户单击包含您的自定义URI方案的链接时,Windows Internet Explorer会启动为该URI方案注册的可插拔协议处理程序。如果注册表中指定的指定打开命令包含%1参数,则Internet Explorer会将URI传递给已注册的可插拔协议处理程序应用程序。

启动处理程序

通过将以上设置添加到注册表中,导航至URI之类的内容alert:Hello%20World将导致尝试在命令行上使用完整URI启动alert.exe。Internet Explorer百分号解码了URI,但Windows  Run …命令没有。如果URI包含百分比编码的空格,则可以在命令行上将其拆分为多个参数。

例如,如果通过Internet Explorer跟随上面的链接,则命令行为:

"C:\Program Files\Alert\alert.exe" "alert:Hello World"

如果通过Windows资源管理器,Windows运行命令或某些其他应用程序访问此链接 ,则命令行为:

"C:\Program Files\Alert\alert.exe" "alert:Hello%20World"

由于Internet Explorer在将结果字符串传递给ShellExecute之前将对URI中所有百分比编码的八位字节进行解码,因此URIalert:%3F?将被提供给警报应用程序可插入协议处理程序alert:??。处理程序将不知道第一个问号是百分比编码的。为避免此问题,可插拔协议处理程序及其关联的URI方案不得依赖于编码。如果需要编码,则协议处理程序应使用与URI语法兼容的另一种编码类型,例如Base64编码。双重百分比编码也不是一个好的解决方案。如果Internet Explorer未处理应用程序协议URI,则不会对其进行解码。

ShellExecute在命令行上使用字符串执行可插拔协议处理程序时,URI中任何未编码的空格,引号和反斜杠将被解释为命令行的一部分。这意味着,如果您使用C / C ++的argc和argv来确定传递给应用程序的参数,则字符串可能会在多个参数之间被打乱。要缓解此问题:

  • 避免在URI中使用空格,引号或反斜杠
  • 引用注册中的%1(“ alert”示例注册中写为“%1”)

但是,避免不能完全解决URI中引号或URI末尾反斜杠的问题。

安全问题

如上所述,传递给可插拔协议处理程序的字符串可能会在多个参数之间中断。恶意方可能会使用其他引号或反斜杠字符来传递其他命令行参数。因此,可插拔协议处理程序应假定命令行上的任何参数都可能来自恶意方,并仔细进行验证。可能根据外部数据启动危险动作的应用程序必须首先与用户确认这些动作。此外,应使用过长的URI或包含意外(或不良)字符序列的URI测试处理应用程序。

自定义协议打开本地客户端程序

以下示例代码包含一个简单的C#控制台应用程序,演示了一种为警报URI方案实现可插拔协议处理程序的方法。

using System;
using System.Collections.Generic;
using System.Text;

namespace Alert
{
  class Program
  {
    static string ProcessInput(string s)
    {
       // TODO Verify and validate the input 
       // string as appropriate for your application.
       return s;
    }

    static void Main(string[] args)
    {
      Console.WriteLine("Alert.exe invoked with the following parameters.\r\n");
      Console.WriteLine("Raw command-line: \n\t" + Environment.CommandLine);

      Console.WriteLine("\n\nArguments:\n");
      foreach (string s in args)
      {
        Console.WriteLine("\t" + ProcessInput(s));
      }
      Console.WriteLine("\nPress any key to continue...");
      Console.ReadKey();
    }
  }
}

alert:"Hello%20World"从Internet Explorer用URI (请注意额外的引号)调用时,程序将响应:

Alert.exe invoked with the following parameters.

Raw command-line:
        "C:\Program Files\Alert\alert.exe" "alert:"Hello World""


Arguments:

        alert:Hello
        World

Press any key to continue...

加入电报群

【江湖人士】(jhrs.com)原创文章,作者:江小编,如若转载,请注明出处:https://jhrs.com/2020/39052.html

扫码加入电报群,让你获得国外网赚一手信息。

文章标题:自定义协议打开本地客户端程序遇上CSP内容安全策略

(0)
江小编的头像江小编
上一篇 2020-12-09 12:55
下一篇 2020-12-11 09:04

热门推荐

Leave a Reply

Sending

国外老牌便宜域名服务商Namecheap注册com域名大优惠,抢到就赚到,优惠码:NEWCOM698
$5.98/年
直达官网