Perl:如何使用“login”参数测试接受GET请求的URL(https)

时间:2013-06-21 20:58:36

标签: perl security http

我有一个CGI服务器端脚本,它接受GET和POST,带有登录参数。 我想测试它以确保它不易受攻击。所以计划是使用Perl LWP,并在GET和POST中发送登录参数,并比较结果。界面已经改变,所以只有在POST时我们才能在会话cookie中发送用户名和密码(不确定这是不是一个好主意),那我该怎么测试呢?以下是我到目前为止的情况:

#!/usr/bin/perl
use LWP;
print "This is libwww-perl-$LWP::VERSION\n";
# Create a user agent object
  use LWP::UserAgent;
  my $ua = LWP::UserAgent->new;
  $ua->agent("MyApp/0.1 ");

  # Create a request
  #my $req = HTTP::Request->new(POST => 'http://search.cpan.org/search');
  #my $req = HTTP::Request->new(GET => 'https://qa.co.net:443/cgi-bin/n-cu.cgi');
  my $req = HTTP::Request->new(GET => 'https://qa.co.net:443/cgi-bin/n-cu.cgi?mode=frameset&JScript=1&remote_user&login=foo&password=foo HTTP/1.1');
  $req->content_type('application/x-www-form-urlencoded');
  $req->content('query=libwww-perl&mode=dist');
  # Pass request to the user agent and get a response back
  my $res = $ua->request($req);

  # Check the outcome of the response
  if ($res->is_success) {
      print $res->content;
      #print $res->code;
      #print $res->message;
  }
  else {
      print $res->status_line, "\n";
  }

这不会这样做,因为它没有会话cookie的东西。但是可能是一个好的开始。这是测试GET和POST的正确方法吗?

以下是cgi中实现的内容:

#cr_login for POST && login for GET -- leave GET param as it used to be.
     if ($m eq 'GET' && defined($req->param('login'))) {
         $msg = 'parameter "login" is invalid for this request type.';
+        my $seclog = $event_logging_directory . '/invalid_request.log';
+        open(S, ">>$seclog") or die $!;
+        my $logmsg = sprintf("%4d-%02d-%02d %02d:%02d:%02d",Today_and_Now())
+            . "|mode:" . $req->param('mode')
+            . "|login:" . $req->param('login')
+            . "|remote_addr:" . $ENV{REMOTE_ADDR}
+            . "|$msg\n";
+        print S $logmsg;

和:

POST request to n-cu.cgi should use parameter "cr_login". If the parameter "login" is passed in a post request, it should throw error and return to login screen.

GET request to n-cu.cgi should use the parameter "login". If the parameter "cr_login" is passed in a post request, it should throw error and return to login screen.

所以这就是我们如何做到的:

  • 保持会话cookie和上下文的活动:

    my $ browser = LWP :: UserAgent-> new(keep_alive => 10);    $ browser-> cookie_jar({});    浏览器的$>代理( '的Mozilla / 8.0');    #$ browser-> ssl_opts({verify_hostname => 0});    浏览器的$> show_progress(1);

及以后:打印回复

print "Cookies:\n", Dumper($browser->cookie_jar()), "\n\n";

  my $content =  $response->as_string;
  print "$content\n";

1 个答案:

答案 0 :(得分:1)

在Cookie中发送密码?不。

禁止GET for / login。

POST用户名和密码到/ login,通过SSL。


CGI中,通过REQUEST_METHOD环境变量指示GET / POST。

您无法阻止确定的人向您的服务器发出GET请求,但您可以拒绝处理它(未经测试的代码 - 您必须填写详细信息):

 if ($ENV{REQUEST_METHOD} ne 'POST') {
    # issue a redirect to a suitable error page, then return.        
 }

 my $q = CGI->new();
 my $user = $q->params('username');
 my $password = $q->params('password');

 my $encrypted_password = my_password_encryptor($password);
 unless ( can_log_in($user, $encrypted_password) ) {
   # issue an error message - redirect&return or fall-through...
 }
 else {
   $session->set_user_logged_in();
 }

大多数人不会推送自己的身份验证或会话处理。他们大多使用CPAN中的一个,或者更大的应用程序框架中包含的一个。如果您正在进行CGI,则可以使用CGI :: Session。

你可以给CGI::Application和/或它的后代看看。那些作者已经解决了你遇到的一系列问题。