Html 如何检测访问者更改了查询字符串中的值?

Html 如何检测访问者更改了查询字符串中的值?,html,perl,validation,digital-signature,Html,Perl,Validation,Digital Signature,在下周学校期末考试的最后一周,老师决定给我们上一堂Perl速成班。我们讨论了如果使用Perl会遇到的所有差异,然后我们开始讨论欺骗 我们得到了一个HTML示例,其中用户可以输入他们的名字和姓氏。当然,我们的例子已经有米奇作为名字,鼠标作为姓氏 <form action="action_page.php"> First name:<br> <input type="text" value="Mickey"> <br> Last name:<br

在下周学校期末考试的最后一周,老师决定给我们上一堂Perl速成班。我们讨论了如果使用Perl会遇到的所有差异,然后我们开始讨论欺骗

我们得到了一个HTML示例,其中用户可以输入他们的名字和姓氏。当然,我们的例子已经有米奇作为名字,鼠标作为姓氏

<form action="action_page.php">
First name:<br>
<input type="text" value="Mickey">
<br>
Last name:<br>
<input type="text" name="lastname" value="Mouse">
<br><br>
<input type="submit" value="Submit">
</form>
您将输入以下内容

firstname=baseball&lastname=bat
这会立即改变预期的命令,最终你会得到棒球的名字和蝙蝠的姓氏

这一切听起来很直截了当,直到他说他希望我们编写一个程序来防止欺骗,而不使用post方法

相反,当用户试图欺骗系统时,我们应该打印一些反欺骗评论

不幸的是,除了示例之外,我们从未真正讨论过欺骗。我试图通过谷歌欺骗来查看一些示例代码,或者至少理解这个概念,但是我运气不好,或者我没有找到正确的地方


所以我想在这里问一下。能不能请一位精通Perl的人给我介绍一下基本的反欺骗程序和内容,或者至少解释并展示一下欺骗应该如何工作。

GET和POST之间的一个区别是前者的信息是通过URL本身传递的。这意味着您可以在浏览器的地址栏中键入您喜欢的内容—它不必来自HTML表单。我想这就是所谓的欺骗

最明显的保护是计算所有受保护字段的CRC(在本例中为米老鼠),并将该值放入服务器发送的HTML表单的隐藏字段中。然后,当请求返回时,计算相同字段的CRC,并检查它是否与返回的隐藏字段的值匹配


当然,如果用户计算出保护的功能,并添加自己对伪造数据的CRC的计算,就可以避免这种情况。但是这应该足以证明概念。

GET和POST之间的一个区别是前者的信息在URL本身中传递。这意味着您可以在浏览器的地址栏中键入您喜欢的内容—它不必来自HTML表单。我想这就是所谓的欺骗

最明显的保护是计算所有受保护字段的CRC(在本例中为米老鼠),并将该值放入服务器发送的HTML表单的隐藏字段中。然后,当请求返回时,计算相同字段的CRC,并检查它是否与返回的隐藏字段的值匹配


当然,如果用户计算出保护的功能,并添加自己对伪造数据的CRC的计算,就可以避免这种情况。但这对于概念验证来说应该足够了。

如果要在表单执行GET操作后检测用户是否更改了url查询字符串中的参数,请在提交表单之前生成客户端哈希。散列将基于表单字段的值,然后与基于响应页面上的当前参数值重新计算的散列进行比较。如果哈希不匹配,则查询字符串已被篡改

这里有一个客户端加密库来计算散列


注意:这仅用于教育用途,在现实世界中无法提供足够的安全性,因为用户还可以通过检查页面源来发现哈希键,并使用该哈希键生成自己的哈希。

如果要检测用户在表单执行GET操作后是否更改了url查询字符串中的参数,然后在提交表单之前生成客户端哈希。散列将基于表单字段的值,然后与基于响应页面上的当前参数值重新计算的散列进行比较。如果哈希不匹配,则查询字符串已被篡改

这里有一个客户端加密库来计算散列

请注意,这仅用于教育用途,在现实世界中无法提供足够的安全性,因为人们还可以通过检查页面源来发现散列密钥,并使用该密钥生成自己的散列。

POST方法无论如何都不会阻止欺骗。POST和GET的作用几乎完全相同——它们向web服务器发送纯文本编码的变量

他们非常容易欺骗——关键不是欺骗,而是你永远不应该相信用户的输入

我建议在名字的情况下,没关系。那么,如果我伪造你的网页,假装我被称为棒球棒呢

如果这很重要,例如,确保我只能看到我的测试结果,那么您需要处理数据处理服务器端。一种方法是v ia会话跟踪-因此,我没有在web表单中包含字段,而是使用会话令牌

你可以“发送”给我一个用户名和密码——理想的情况是使用散列,这样就不可能“看到”你正在发送的用户名和密码,或者在你的浏览器历史记录中。然后我将对照我的服务器检查它,通过在服务器上执行相同的操作并比较两者来检查哈希是否“有效”

如此完美:

#!/usr/bin/perl
use strict;
use warnings;

use Digest::SHA qw ( sha1_base64 );

my ( $firstname, $lastname ) = qw ( Mickey Mouse ); 
my $timewindow = int ( time / 300 ); 
my $token = sha1_base64 ( $timewindow.$firstname.$lastname );

print $token;
这会产生一个不会持续很长时间的令牌-它每5分钟更改一次-但篡改非常困难

包含时间的原因是为了避免重播攻击,如果查看浏览器历史记录,我可以找到您的令牌并重用它。这可能是继欺骗之后的下一个问题:

如果您将参数与令牌一起发送,请记住,恶意参与者实际上很容易自己执行相同的计算,并发送一些完全伪造的凭据和令牌

不过,这是一个过于简单的例子——因为实际上,伪造的参数并不重要,因为您首先不应该信任它们。如果“米老鼠”有效,而“棒球棒”无效,那么服务器应该在处理表单时检测到,并丢弃后者,这使得整个“表单欺骗”事件变得无关紧要

POST方法无论如何也不能阻止欺骗。POST和GET的作用几乎完全相同——它们向web服务器发送纯文本编码的变量

他们非常容易欺骗——关键不是欺骗,而是你永远不应该相信用户的输入

我建议在名字的情况下,没关系。那么,如果我伪造你的网页,假装我被称为棒球棒呢

如果这很重要,例如,确保我只能看到我的测试结果,那么您需要处理数据处理服务器端。实现这一点的一种方法是通过会话跟踪——因此,我使用会话令牌,而不是在web表单中包含字段

你可以“发送”给我一个用户名和密码——理想的情况是使用散列,这样就不可能“看到”你正在发送的用户名和密码,或者在你的浏览器历史记录中。然后我将对照我的服务器检查它,通过在服务器上执行相同的操作并比较两者来检查哈希是否“有效”

如此完美:

#!/usr/bin/perl
use strict;
use warnings;

use Digest::SHA qw ( sha1_base64 );

my ( $firstname, $lastname ) = qw ( Mickey Mouse ); 
my $timewindow = int ( time / 300 ); 
my $token = sha1_base64 ( $timewindow.$firstname.$lastname );

print $token;
这会产生一个不会持续很长时间的令牌-它每5分钟更改一次-但篡改非常困难

包含时间的原因是为了避免重播攻击,如果查看浏览器历史记录,我可以找到您的令牌并重用它。这可能是继欺骗之后的下一个问题:

如果您将参数与令牌一起发送,请记住,恶意参与者实际上很容易自己执行相同的计算,并发送一些完全伪造的凭据和令牌


不过,这是一个过于简单的例子——因为实际上,伪造的参数并不重要,因为您首先不应该信任它们。如果“米老鼠”有效,而“棒球棒”无效,那么服务器应该在处理表单时检测到,并丢弃后者,这使得整个“表单欺骗”事件变得无关紧要

这个问题的措辞相当狭隘,因此这个答案可能无法完全回答您的问题。但作为一项政策,如果你不想让你的用户篡改你的数据,你不应该让他们保管它。如果服务器已经知道用户名,为什么还要依赖查询字符串?依靠客户机进行身份验证和获取新信息,并依靠您的记录获取用户无法控制的任何信息

POST请求几乎可以像GET请求一样轻松地编制,而加密保护,即使是安全的,也只在客户端无法访问的情况下才有用
加密数据;那么为什么要来回传输呢?

这个问题的措辞相当狭隘,因此这个答案可能无法完全回答您的问题。但作为一项政策,如果你不想让你的用户篡改你的数据,你不应该让他们保管它。如果服务器已经知道用户名,为什么还要依赖查询字符串?依靠客户机进行身份验证和获取新信息,并依靠您的记录获取用户无法控制的任何信息

POST请求几乎可以像GET请求一样轻松地编制,而加密保护,即使是安全的,也只在客户端无法访问的情况下才有用
加密数据;那么为什么要来回传输它呢?

您需要做的是验证查询字符串中的数据,并在收到数据时验证它。这有一个标准的工具集:加密工具

基本上,MAC是一个函数,它接收消息中的任意字符串和密钥,并输出随机密钥- 以一种复杂的方式查看同时依赖于消息和密钥的令牌。重要的是,实际上不可能在不知道密钥的情况下为修改后的消息计算有效的MAC令牌

要使用MAC验证查询字符串或其他一些数据,您基本上要遵循以下步骤:

将数据编码为字符串的规范形式。对于HTTP URL,您可以直接使用查询字符串和/或整个URL,尽管您可能希望对其进行规范化,例如,对不需要编码的任何字符进行%解码,并规范任何%编码值的大小写,例如%3f→ %3F

或者,您可以将查询字符串解码为(比如)关联数组,并以您选择的格式序列化该数组。这样可以更容易地组合来自多个源(例如隐藏表单字段)的参数,添加额外的数据字段(见下文),并选择要验证的字段

(可选)将数据与您希望与之关联的任何其他信息(如用户ID和/或时间戳)组合。您可以显式地传输时间戳,也可以将其四舍五入到(比如)最后一个小时,并在验证时检查当前时间戳和上一个时间戳。更改这些值中的任何一个都会更改MAC输出,从而防止攻击者尝试在另一个用户的帐户下提交一个用户的数据

优选地,在服务器上存储安全生成的随机值(例如128位)的密钥。显然,必须存储此密钥,以便用户无法访问它(例如,通过猜测配置文件的路径)

将规范编码的数据和密钥输入MAC算法。获取结果,如果您的MAC library没有为您执行此操作,请在方便的情况下对其进行编码,例如使用

将编码的MAC令牌作为额外参数附加到URL中

当您接收回数据时,移除MAC令牌,将其余数据按上述方式反馈回MAC生成代码,并检查生成的MAC是否与您接收到的MAC匹配

MAC算法可以由MD5或SHA-1/2/3等构造而成。事实上,只需将机密和消息连接起来,对它们进行散列,并将结果用作令牌,即可获得基本MAC

对于一些散列函数,如SHA-3,上面描述的简单MAC构造实际上被认为是安全的;但是,对于旧的散列函数(没有明确考虑到这种用法),使用稍微复杂的结构更安全,它将输入散列两次


或者,也有MAC算法,例如,基于分组密码(如AES)而不是散列函数的MAC算法。在某些情况下,例如在嵌入式平台上,快速哈希函数可能不可用,这些可能比HMAC更有效;但是,对于web应用程序,选择基本上是一个品味问题。

您需要做的是验证查询字符串中的数据,并在收到数据时对其进行验证。这有一个标准的工具集:加密工具

基本上,MAC是一个函数,它接收消息中的任意字符串和密钥,并输出一个看起来随机的令牌,该令牌以复杂的方式依赖于消息和密钥。重要的是,实际上不可能在不知道密钥的情况下为修改后的消息计算有效的MAC令牌

要使用MAC验证查询字符串或其他一些数据,您基本上要遵循以下步骤:

将数据编码为字符串的规范形式。对于HTTP URL,您可以直接使用查询字符串和/或整个URL,尽管您可能希望对其进行规范化,例如,对不需要编码的任何字符进行%解码,并规范任何%编码值的大小写,例如%3f→ %3F

或者,您可以将查询字符串解码为(比如)关联数组,并以您选择的格式序列化该数组。这样可以更容易地组合来自多个源(例如隐藏表单字段)的参数,添加额外的数据字段(见下文),并选择要验证的字段

(可选)将数据与您希望与之关联的任何其他信息(如用户ID和/或时间戳)组合。您可以显式地传输时间戳,也可以将其四舍五入到(比如)最后一个小时,并在验证时检查当前时间戳和上一个时间戳。更改这些值中的任何一个都会更改MAC输出,从而防止攻击者尝试在另一个用户的帐户下提交一个用户的数据

优选地,在服务器上存储安全生成的随机值(例如128位)的密钥。显然,必须存储此密钥,以便用户无法访问它(例如,通过猜测配置文件的路径)

将规范编码的数据和密钥输入MAC算法。获取结果,如果您的MAC lib rary不会为您执行此操作。请在方便的情况下对其进行编码,例如使用

将编码的MAC令牌作为额外参数附加到URL中

当您接收回数据时,移除MAC令牌,将其余数据按上述方式反馈回MAC生成代码,并检查生成的MAC是否与您接收到的MAC匹配

MAC算法可以由MD5或SHA-1/2/3等构造而成。事实上,只需将机密和消息连接起来,对它们进行散列,并将结果用作令牌,即可获得基本MAC

对于一些散列函数,如SHA-3,上面描述的简单MAC构造实际上被认为是安全的;但是,对于旧的散列函数(没有明确考虑到这种用法),使用稍微复杂的结构更安全,它将输入散列两次


或者,也有MAC算法,例如,基于分组密码(如AES)而不是散列函数的MAC算法。在某些情况下,例如在嵌入式平台上,快速哈希函数可能不可用,这些可能比HMAC更有效;但是,对于web应用程序来说,选择基本上是一个品味问题。

欢迎使用堆栈溢出。请尽快阅读这一页。我很困惑-这看起来更像HTML和表单管理,而不是Perl。谢谢,我会的。-我们的老师把他的课叫做perl和web,这对我来说是一个全新的、完全令人困惑的课程。欢迎来到Stack Overflow。请尽快阅读这一页。我很困惑-这看起来更像HTML和表单管理,而不是Perl。谢谢,我会的。-我们的老师把他的课叫做perl和web,这对我来说是一个全新的、完全令人困惑的课程。你上一段提到的问题可以通过使用盐哈希而不是不盐哈希来避免。攻击者必须知道欺骗的秘密。我不知道你为什么建议使用CRC作为哈希算法;使用更好的方法也同样容易。@ikegami:OP说“他想让我们编写一个程序来防止欺骗,而不使用post方法”没有做到这一点!删除了评论。@ikegami它不只是那么糟糕。MD5是一个正确的加密散列。虽然它有已知的弱点,但它比简单的CRC要好得多,而且对于这种操作场景来说可能已经足够好了。我同意出于教育目的,更强的散列可能是一个更好的例子,但是你在这里反应过度了。你上一段提到的问题可以通过使用盐散列而不是不盐散列来避免。攻击者必须知道欺骗的秘密。我不知道你为什么建议使用CRC作为哈希算法;使用更好的方法也同样容易。@ikegami:OP说“他想让我们编写一个程序来防止欺骗,而不使用post方法”没有做到这一点!删除了评论。@ikegami它不只是那么糟糕。MD5是一个正确的加密散列。虽然它有已知的弱点,但它比简单的CRC要好得多,而且对于这种操作场景来说可能已经足够好了。我同意出于教育目的,一个更强大的散列可能是一个更好的例子,但你在这里几乎是反应过度了。客户端库没有帮助。他也可以通过更改字段轻松地更改值。您可能希望在服务器上散列用秘密标记的值,并将该标记包含在表单中的隐藏字段中。服务器将通过检查提交值的哈希值和提交的哈希值来检查篡改。客户端库没有帮助。他也可以通过更改字段轻松地更改值。您可能希望在服务器上散列用秘密标记的值,并将该标记包含在表单中的隐藏字段中。服务器将通过检查提交值的散列和提交的散列来检查篡改。