什么是软件
就...前一段时间据称某个电子商务平台被发现利用系统漏洞在用户不知情的情况下——我们不知道用户是否同意因为那个没有人会读的《最终用户许可协议》是可能具有法律效力的,或者说:谁让你没读呢——但至少它发生的时候用户是不知情的——利用用户设备的数据进行了一些有利于该平台的行为。
本文可以视为对这次事件的评论。
cc-by-sa 4.0
cc-by-nc-sa 4.0
从一般用户的角度而言,软件直观上是存储在在用户设备中可供运行的程序文件,如果它不运行在用户设备中而是运行在别处的话,它可能并不会存储在用户设备上,但它总之还是某个程序文件。
不过这种视角只看到了软件的某一种状态,并且那一个特定的程序文件只是软件的一个“副本”。但话说回来,指着一本《红楼梦》说“这不是《红楼梦》而是《红楼梦》的副本”好像并没有什么意义,因为就其承载的内容而言每个特定版本的《红楼梦》都是“完全相同”的,有意义的不是它的承载形式而是它的内容。
所以在这个意义上说,软件是软件的二进制表示。因而,更进一步的,我们可以说,软件是软件的代码,因为无论是二进制的“编译产物”还是文本形式的“源代码”,都只不过是这个软件的不同“承载形式”,就其“用于指导处理器和计算机执行特定任务”的内容而言,它们是相同的。
所以,就其本质而言,软件是一种知识。
如果和书籍类比的话,它像是字典或手册。你不会记下手册中的全部内容,但当你需要完成某项任务时,你会打开手册,按照其中的说明进行操作。当你需要使用计算机完成任务时,你会打开软件,执行它的功能。
开发者开发了某个软件,就像编写了一本字典,手册或教材。开发者通过软件教育或指导用户应当/可以如何去完成某项任务,而用户可以执行其中的说明。
但用户不会亲自去阅读某个软件的二进制表示,因为计算机会代劳。但我们应当注意到,当你在使用一台计算机时,它的设备和处理器构成了你的身体,感官和思维的延伸。从而“使用CPU”查阅软件的二进制代码,和“使用电子显微镜”观察微观事物并没有实质上的区别:你并没有真的看到代码,实际上你也没有真的看到微观结构,是电子看到了它,电子显微镜将电子束的观察“重新解释并呈现”为你能够理解的形式。而“运行软件”就是一个“重新解释并呈现”的过程。
不过这只是软件的一个侧面。因为当我们在谈论软件时,我们谈论的通常并不是它“死”的,在存储设备中的状态。我们谈论的是它“活”的状态,是当软件在设备中运行时,它的“运行实例”。某个软件的“某一个运行实例”和这个软件的“软件程序”本身并不相同。运行实例是具体于某个设备,某个任务,某次运行的,是抽象知识的具象化。“一次运行实例”就好比是“一次查字典”,它是存储在字典当中的死知识的具象化。
但这种具象化是特定于设备,特定于任务,并且最终来说,也总是特定于用户的。
在某个瞬间,用户的灵魂与软件重叠。于是,长眠于代码中的知识死而复生,作为运行实例短暂地存活,并成为了用户生命历程的一部分。
也就是说,作为“运行实例”存在的软件,它是且只能是作为用户的一部分才得以存在的。正如前文的类比,“用户运行软件就像读者参照手册”,读者可以脱离手册自由发挥,用户也可以任意操作软件的运行实例。用户可以暂停,随意修改数据,然后继续执行,或者存储*或销毁它。用户是“运行实例”的主导者,就像读者是“查手册”的主导者。虽然说,因为现代电子计算机和软件系统的极端复杂性,用户想要真正掌握主导需要大量的知识,虽然用户正在失去对它的主导能力,但我们必须要强调,这个过程无论如何都只能是脱胎于用户的,因而它无论如何都是用户的一部分。
*: https://criu.org/Main_Page
*: https://podman.io/getting-started/checkpoint
那么,我想有些事的“价值判断”应当是不言自明的。但是有一点需要强调,这起事件的重点并不是“利用漏洞”,而是“不知情不同意”。“利用漏洞”可以是同意的,“不利用漏洞”也可以是不知情不同意的。而进一步的,“不允许利用漏洞”同样可以是不被同意的。
软件是知识,记载关于如何“利用漏洞”的书籍本身并不是必然是错的。然而,故意在手册中写下不利于读者的条目,利用读者的无知伤害读者,故意在软件中包含不利于用户的代码,利用用户的无知伤害用户,这是错的。
因此,
我认为“利用漏洞”的“不知情不同意”相比“不利用漏洞”的“不知情不同意”并不更加恶劣。因为就其对用户的伤害而言两者是相当的。
我认为任何“不允许利用漏洞”的措施,如果这实际上会进一步剥夺用户的主导能力,那么无论是为了将“利用漏洞”的“不知情不同意”变为“不利用漏洞”的“不知情不同意”,或者出于任何其他目的,比如所谓的“安全”,这种措施都不存在任何正当性可言。
没错我说的是iOS app store以及某些android软件的root检测。当然我不会说root检测完全是不好的因为如果真的有用户在不知情的情况下被安装后门,这至少能让用户知道。但root检测应当提供绕过选项,也就是“我机器是我自己root我自己知道你不用管”的选项。
那么......
我们还没有讨论“服务器软件运行实例”。既然“运行实例”是用户自身的一部分,那么“服务器软件运行实例”自然也是服务提供者的一部分,所以我们看似在讨论软件,实际上我们应当讨论的是参与方,也就是“提供者”和“客户”。所以说,“虽然我不小心写了个漏洞但你不能利用这个漏洞伤害我”,这是成立的。就比如在无人的摊贩前盗窃依然是盗窃,虽然它就好像是在欢迎你来偷一样,但这依然是盗窃。
注意这里使用“客户”(clients)而不是“用户”(users),因为“提供者”同样是用户。在下文中“客户”可以视为与“最终用户”含义相近。
但是这里有一些问题,比如说,“什么叫伤害”。会非常微妙。
比如首先客户端软件是一种知识,它指导客户如何与服务器软件通信。那么显然仅仅是使用第三方客户端在任何意义上都不可能构成对服务提供者的伤害。反过来说,“你必须用这个和我玩,不然我就不和你玩了”,如果提供者具有垄断地位,那么这显然是对客户的伤害。比如某个处于垄断地位的IM服务提供者,如果强制所有客户必须使用某个软件,甚至封禁使用第三方客户端的客户账号,这当然......我们所有人都知道这在客户看来是怎么样的。
但反过来说,能构成对服务提供者的伤害的,是没有按照服务器所预期的,或者双方所约定的方式与服务器通信。当然这里有很多例子,针对服务器的攻击基本上都是通过构造“非预期的”请求,或令服务器软件进入“非预期的”状态来造成服务器软件的“非预期的”行为。而“非预期”行为的发生便为“攻击者所期望的行为”制造了机会。那么如果某个第三方客户端与服务器通信的方式是“非预期”的,而尤其如果这种方式是“故意”的,这就是故意的伤害行为了。
但在此基础上服务提供者是应当承担更多义务的,因为是服务提供者在主动提供服务,服务本身也是完全由提供者定义,因此提供者天然处于优势。提供者应当明确说明预期的通信方式,从而客户可以自行判断出自己正在意图进行的通信是否是提供者所预期的。只有在事先做好约定的前提下,当意外或攻击发生时,提供者才有资格指责对方没有遵守协议。
然而如果协议本身就是在伤害客户,那么按照习惯其中的不公平条款应被认为是自始无效才对。
如果是在多方的情况下,从提供者-客户协议中我们可以自然引申出一个“多方协议”或“社区规则”,比如多人游戏中对作弊的定义和态度。多方协议应当是在所有参与方之间共同达成的,比如多人游戏的多方协议可以是具体于对局的。比如所有参与方都赞同不限制在其他对局中可能被认为是作弊的行为的的电子游戏对局中,这些行为就是合理的。同样的,所有参与方都赞同以极端手段检测作弊的对局中,极端手段就是合理的:因为参与者不仅对别人采取了手段,这种手段也会施加于自身。
社区规则也包括coc和合规性问题。但是我认为这里有一个前提是这个协议依然是“多方”的。服务器软件代表提供者一方,但是社区不是提供者一方的社区,那么合规性以及合规性风险当然不应该是提供者一方的事情。社区的每一个参与方都应当为自己的合规性负责。毕竟由提供者代行合规性是一种僭越......嘛,这是另一个问题。
社区和服务器软件当然是两回事,服务提供者通过服务器软件向社区提供承载服务,社区是通过这个承载服务所建立的用户(提供者也可以是社区成员)关系,结构和内容。
提供者-客户关系是关于如何使用服务器软件的,而社区规则是关于社区成员之间的。如果我们的讨论仅限于服务器软件,那么社区是和服务器软件完全没有关系的,因为服务器软件仅在于提供者-客户双方,客户将这个关系用来做什么事是和服务器软件本身无关的。