Perl 中的 HTML 表单篡改
Web 应用程序使用 HTML 表单来接收来自用户的输入。 HTML 表单有一个主要缺点,即用户可以将表单保存在文件中,对其进行编辑并将编辑后的表单文件提交回服务器。这个问题会导致更糟,因为网络应用程序本质上是“无状态的”。 HTTP 中的事务是无连接的,并且是一次性传输的。在通过表单收集用户的数据时,他们必须通过一系列的输入表单将他们的信息存储到服务器。 “状态”信息存储在用户的浏览器中,并在交易中共同发送回服务器。此状态信息可以通过 3 种方式存储:
- 浏览器中的“ Cookies ”
- URL 中的特殊标签
- HTML 表单中的“隐藏”字段
HTML 表单中最常用的方法是“隐藏”字段。这有助于隐藏表单中的输入,并且使用起来最简单,并且可以保存大量数据。然而,在填写表单时,数据存储在用户的网络浏览器中,它们很容易被隐藏的字段篡改。
示例:一个简单的 Web 应用程序,它允许用户使用 Perl 中的 CGI 库“登录”和更新他们的“邮件地址”。
Perl
#!/usr/bin/perl
use CGI qw/:standard/;
# Printing the MIME header:
print "Content−type: text/html\n\n";
print '';
print 'Tampering Input Form Example
';
# Assign some unchanged example values:
$userid = 'GeeksforGeeks';
$credit_ok = 1;
$form_expires = '40002002:10:53:50';
# Displaying a blank HTML form:
if (! param('chaddr'))
{
print_form();
}
else {
print "You made this easy ", param('userid'), "
";
print "Your address information has been successfully updated.";
}
print "";
## SUBROUTINES:
sub print_form {
# Prints an example HTML form
# with signature in the hidden field:
print<
END_TEXT
}
HTML
HTML
Perl
#!/usr/bin/perl −T
# Tamper-proof-form.pl
use Digest::MD5 qw(md5_base64);
use CGI qw/:standard/;
# Secret password to sign the form variables:
$secretkey = 'Geeks_for_Geeks_123';
# Printing the MIME header:
print "Content−type: text/html\n\n";
print '';
print 'Tamper proof form example
';
# Assigning some unchanged example values:
$userid = 'GeeksforGeeks';
$credit_ok = 1;
$form_expires = '30004004:11:52:40';
# Displaying a blank HTML form:
if ( ! param('chaddr') ) {
# Creating an MD5 signature:
$signature = sigMD5( 'create', $secretkey, '$userid', '$credit_ok',
'$form_expires');
print_form();
}
else {
# Validating the signature:
if ( sigMD5( 'check', $secretkey, 'userid', 'credit_ok',
'form_expires' ) eq param('signature') ) {
print "You made this easy ", param('userid'), "
";
print "You've successfully updated your address information.";
}
else {
print "ERROR: 'Hidden' fields were tampered with!";
}
}
print "";
sub print_form {
# Printing an example HTML form with signature:
print<
END_TEXT
}
sub sigMD5 {
my $mode = shift;
my $key = shift;
my @names = @_;
my $values = '';
my $fieldname;
# Joining each variable name with it's value:
foreach $fieldname (@names) {
if ($mode eq 'create') {
$values .= $fieldname . eval $fieldname;
} else {
$values .= '$' . $fieldname . param($fieldname);
}
}
$values = $key . $values;
return md5_base64($values);
}
HTML
HTML
HTML
在上面的登录页面上,我们跳过了 Web 应用程序的登录页面,脚本也不会对表单数据执行任何操作。当我们在 Web 浏览器中运行表单并考虑 HTML 源代码时。此表单使用“隐藏”字段来保存登录过程中的信息:
在表单中填写一些信息并按下提交按钮时,确认屏幕会直接使用 HTML 表单中的隐藏字段 userID 值。
篡改表格:
要篡改 HTML 表单,请按“ Ctrl+S ”将 HTML 表单的网页保存到您的计算机。 HTML 表单包含“隐藏”字段,可以使用文本编辑器进行编辑。更改“用户 ID ”字段,然后保存编辑的文件。然后在 Web 浏览器中打开相同的文件并提交表单。它将接受编辑的文件,因为 Web 应用程序信任“隐藏”字段。
示例:通过更改隐藏字段来篡改 HTML 表单。
- HTML 表单:
- 通过'Ctrl+S'保存上述表格
- 表单中最初隐藏的字段:
HTML
- 'userid'的值为“ GeeksforGeeks ”,并且类型是隐藏的。
- 关于篡改表单中的隐藏字段:
HTML
- 在“用户ID”值从“GeeksforGeeks”到“Geeks123“改变,使用文本编辑器。然后保存文件并在 Web 浏览器中打开此文件,填写表单,然后按提交按钮。
- 在按下提交按钮时:
防止 HTML 表单篡改:
有许多解决 HTML 表单篡改的方法。下面给出了一些:
- 密钥:HTML 表单篡改的一种解决方案是使用密钥。它可以检测字段中所做的更改,但并非完全万无一失。此方法依赖于存储在 Web 服务器上的密钥。但是,如果您有足够的安全措施防止闯入并定期修改 Web 服务器上的密钥,那么它就足够安全了。
- HTTP_REFERER :高级开发人员可能认为可以通过 HTTP_REFERER 变量检查来阻止篡改。许多 Web 浏览器会发送一个标头 HTTP_REFERER,其中包含用户之前看到的页面 URL。对于一些简单的 Web 应用程序,HTTP_REFERER 仅包含应用程序的 URL。当用户试图通过保存表单然后提交来篡改表单时,HTTP_REFERER 变为空白或将包含不同的 URL。
- 粉碎/删除 cookie : Java和PHP等语言将 cookie 保存在网络服务器上——这是我们会话在网络上花费的数据。在这种情况下,数据不会存储在用户的网络浏览器中,用户很难篡改任何数据字段。来自服务器端的数据由客户端-服务器标识符引用,以会话 ID 的形式存储为 cookie。 Cookie 有两种类型:
- 瞬态(会话)cookie -没有任何到期日期。
- 持久性 cookie -它有一个过期日期,设置在未来。
- 使用摘要算法:摘要算法为任何输入字段生成唯一的“签名”字符串。这使得用户不可能篡改表单的输入字段,因为这些算法产生相同的签名。这些算法用于 VPN、SSL 浏览器连接等,用于“签署”数据。它还可以在 Web 应用程序中用于对隐藏字段进行签名。最常用的摘要算法是Message Digest 5,也称为MD5 。更好的摘要算法是SHA1 HMAC 。
- Message Digest 5 :它是一种广泛使用的摘要算法,几乎在所有 Web 应用程序中用于对隐藏字段进行签名,但也遭受篡改攻击。使用 MD5 时,用户可以创建隐藏字段的指纹。他可以在一个字符串拼接的隐藏字段值,并使其通过摘要算法,并发送至另一隐藏字段来获得一个指纹。然而,这可以通过向指纹添加一个用户可能永远不知道的秘密组件来阻止篡改。
- HMAC 标准:使用摘要算法的标准方法是 HMAC。该算法通过 MD5 或 SHA1 使用两个密钥和三个迭代来隐藏输入字段。
示例:一个 Web 应用程序,使用 Perl 中的 CGI 库使用表单中的“MD5”摘要算法更改用户的“地址”以使其防篡改。
珀尔
#!/usr/bin/perl −T
# Tamper-proof-form.pl
use Digest::MD5 qw(md5_base64);
use CGI qw/:standard/;
# Secret password to sign the form variables:
$secretkey = 'Geeks_for_Geeks_123';
# Printing the MIME header:
print "Content−type: text/html\n\n";
print '';
print 'Tamper proof form example
';
# Assigning some unchanged example values:
$userid = 'GeeksforGeeks';
$credit_ok = 1;
$form_expires = '30004004:11:52:40';
# Displaying a blank HTML form:
if ( ! param('chaddr') ) {
# Creating an MD5 signature:
$signature = sigMD5( 'create', $secretkey, '$userid', '$credit_ok',
'$form_expires');
print_form();
}
else {
# Validating the signature:
if ( sigMD5( 'check', $secretkey, 'userid', 'credit_ok',
'form_expires' ) eq param('signature') ) {
print "You made this easy ", param('userid'), "
";
print "You've successfully updated your address information.";
}
else {
print "ERROR: 'Hidden' fields were tampered with!";
}
}
print "";
sub print_form {
# Printing an example HTML form with signature:
print<
END_TEXT
}
sub sigMD5 {
my $mode = shift;
my $key = shift;
my @names = @_;
my $values = '';
my $fieldname;
# Joining each variable name with it's value:
foreach $fieldname (@names) {
if ($mode eq 'create') {
$values .= $fieldname . eval $fieldname;
} else {
$values .= '$' . $fieldname . param($fieldname);
}
}
$values = $key . $values;
return md5_base64($values);
}
- 在上面的登录页面上,当我们在 Web 浏览器中运行表单时,并考虑 HTML 源代码。该表单包含一个新的隐藏字段“签名”,其中存储了一个 MD5 '指纹'。
- 上述指纹/签名值是使用隐藏字段中的“名称”和“值”以及存储在服务器上的“密钥”生成的。
- 在用户提交表单时,隐藏字段中的内容与密钥结合,生成 MD5 指纹。检查字段未被篡改的一种方法是将 MD5 生成的“签名”与原始表单中的签名相匹配。
上述方法可以在很大程度上防止HTML表单被篡改,但并非完全万无一失。
示例:通过更改表单中的隐藏字段来篡改 HTML 表单,使用 MD5 摘要算法。
- HTML 表单:
- 通过“ Ctrl+S ”保存上述表格
- 表单中最初隐藏的字段:
HTML
' userid ' 的值为“ GeeksforGeeks ”,并且类型是隐藏的。
- 关于篡改表单中的隐藏字段:
HTML
- 在“用户ID”值从“GeeksforGeeks”到“Geeks123“改变,使用文本编辑器。然后保存文件并在 Web 浏览器中打开此文件,填写表单,然后按提交按钮。
- 在按下提交按钮时:
- 现在检查提交表单的 HTML 源代码。
HTML
Web 应用程序使用MD5摘要算法,可防止篡改 HTML 表单。将原始签名 - 'OZ+1iYhIPiDw5hJdtjywQA' 与提交表单后获得的签名 - 'KJ+1oUbLiDqf9kWcymuvAL' 进行比较,可以清楚地看出区别。