Apache-AuthCookie

 view release on metacpan or  search on metacpan

t/real.t  view on Meta::CPAN

    ]);

    is($r->header('Location'), '/docs/protected/get_me.html',
       'HttpOnly location header');

    is($r->header('Set-Cookie'),
       'Sample::AuthCookieHandler_WhatEver=programmer:Heroo; path=/; HttpOnly',
       'cookie contains HttpOnly attribute');

    is($r->code, 302, 'check redirect response code');
};

# Should succeed and cookie should have SameSite attribute
subtest 'SameSite cookie attribute' => sub {
    plan tests => 3;

    my $r = POST('/LOGIN-SAMESITE', [
        destination  => '/docs/protected/get_me.html',
        credential_0 => 'programmer',
        credential_1 => 'Heroo'
    ]);

    is($r->header('Location'), '/docs/protected/get_me.html',
       'SameSite location header');

    is($r->header('Set-Cookie'),
       'Sample::AuthCookieHandler_WhatEver=programmer:Heroo; path=/; SameSite=strict',
       'cookie contains SameSite attribute');

    is($r->code, 302, 'check redirect response code');
};

# test SessionTimeout
subtest 'session timeout' => sub {
    plan tests => 1;

    my $r = GET(
        '/docs/stimeout/get_me.html',
        Cookie => 'Sample::AuthCookieHandler_WhatEver=programmer:Hero'
    );

    like($r->header('Set-Cookie'),
         qr/^Sample::AuthCookieHandler_WhatEver=.*expires=.+/,
         'Set-Cookie contains expires property');
};

# should return bad credentials page, and credentials should be in a comment.
# We are checking here that $r->prev->pnotes('WhatEverCreds') works.
subtest 'creds are in pnotes' => sub {
    plan tests => 1;

    my $r = POST('/LOGIN', [
        destination  => '/docs/protected/get_me.html',
        credential_0 => 'fail',
        credential_1 => 'Hero'
    ]);

    like($r->content, qr/creds: fail Hero/s, 'WhatEverCreds pnotes works');
};

# regression - Apache2::URI::unescape_url() does not handle '+' to ' '
# conversion.
subtest 'unescape URL with spaces' => sub {
    plan tests => 1;

    my $r = POST('/LOGIN', [
        destination  => '/docs/protected/get_me.html',
        credential_0 => 'fail',
        credential_1 => 'one two'
    ]);

    like($r->content, qr/creds: fail one two/,
         'read form data handles "+" conversion');
};

# variation of '+' to ' ' regression.  Make sure we do not remove encoded
# '+'
subtest 'do not remove encoded +' => sub {
    plan tests => 1;

    my $r = POST('/LOGIN', [
        destination  => '/docs/protected/get_me.html',
        credential_0 => 'fail',
        credential_1 => 'one+two'
    ]);

    like($r->content, qr/creds: fail one\+two/,
         'read form data handles "+" conversion with encoded +');
};

# XSS attack prevention.  make sure embedded \r, \n, \t is escaped in the destination.
subtest 'XSS: no newlines in destination' => sub {
    plan tests => 4;

    my $r = POST('/LOGIN', [
        destination  => "/docs/protected/get_me.html\r\nX-Test-Bar: True\r\nX-Test-Foo: True\r\n",
        credential_0 => 'programmer',
        credential_1 => 'Hero'
    ]);

    ok(!defined $r->header('X-Test-Foo'), 'anti XSS injection');
    ok(!defined $r->header('X-Test-Bar'), 'anti XSS injection');

    # try with escaped CRLF also.
    $r = POST('/LOGIN', [
        destination  => "/docs/protected/get_me.html%0d%0aX-Test-Foo: True%0d%0aX-Test-Bar: True\r\n",
        credential_0 => 'programmer',
        credential_1 => 'Hero'
    ]);

    ok(!defined $r->header('X-Test-Foo'), 'anti XSS injection with escaped CRLF');
    ok(!defined $r->header('X-Test-Bar'), 'anti XSS injection with escaped CRLF');
};

# embedded html tags in destination
subtest 'XSS: no embedded HTML in destination' => sub {
    plan tests => 1;

    my $r = POST('/LOGIN', [
        destination  => '/"><form method="post">Embedded Form</form>'
    ]);

    like $r->content, qr{"/%22%3E%3Cform method=%22post%22%3EEmbedded Form%3C/form%3E"};
};

# embedded script tags
subtest 'XSS: no embedded script' => sub {
    plan tests => 1;

    my $r = POST('/LOGIN', [
        destination => q{"><script>alert('123')</script>}
    ]);

    ok index($r->content, q{<script>alert('123')</script>}) == -1;
};

subtest 'preserve / in password' => sub {
    plan tests => 1;

    my $r = POST('/LOGIN', [
        destination  => '/docs/protected/get_me.html',
        credential_0 => 'fail',
        credential_1 => 'one/two'
    ]);

    like($r->content, qr/creds: fail one\/two/,
         'read form data handles "/" conversion with encoded +');
};

# make sure multi-valued form data is preserved.
subtest 'multi-valued form data is preserved' => sub {
    plan tests => 2;

    my $r = POST('/docs/protected/xyz', [
        one => 'abc',
        one => 'def'
    ]);

    # check and make sure we are at the login form now.
    like($r->content, qr/Failure reason: 'no_cookie'/,
         'login form was returned');

    # check for multi-valued form data.
    like($r->content, qr/one=abc&one=def/,
         'post conversion perserves multi-valued fields');
};

# make sure $ENV{REMOTE_USER} gets set up
subtest 'setup $ENV{REMOTE_USER}' => sub {
    plan tests => 1;

    my $r = GET('/docs/protected/echo_user.pl',



( run in 0.778 second using v1.01-cache-2.11-cpan-5a3173703d6 )