CGI-Lingua
view release on metacpan or search on metacpan
t/cgi_security.t view on Meta::CPAN
# ââ 1. Shell metacharacter injection via HTTP_ACCEPT_LANGUAGE âââââââââââââââââ
# The regex /^([A-Za-z0-9\-,;=.*\s]{1,256})$/a must reject every shell meta.
# If any payload leaked, it could reach I18N::AcceptLanguage's regex engine or
# be stored in the object and later reflected.
subtest 'Accept-Language: shell metacharacters are rejected by untaint regex' => sub {
for my $payload (@SHELL_PAYLOADS) {
local %ENV = (HTTP_ACCEPT_LANGUAGE => $payload, REMOTE_ADDR => '127.0.0.1');
my $l = _obj();
# language() must fall through to 'Unknown'; it must NOT return or store
# any fragment of the hostile payload.
my $lang = $l->language();
is($lang, 'Unknown', "shell payload rejected: " . _abbrev($payload));
unlike($lang // '', qr/[|;&\x60\$]/, 'no shell meta in returned language');
}
};
# ââ 2. CRLF injection via HTTP_ACCEPT_LANGUAGE ââââââââââââââââââââââââââââââââ
# A browser forging a CRLF-bearing Accept-Language header could attempt to
# inject extra HTTP response headers when the application reflects the header.
t/cgi_security.t view on Meta::CPAN
};
# ââ 9. LANG env-var injection âââââââââââââââââââââââââââââââââââââââââââââââââ
# LANG is only consulted when HTTP_ACCEPT_LANGUAGE and the CGI::Info lang param
# are both absent (local/debug mode). It is untainted by a similar regex.
subtest 'LANG: shell metacharacters are ignored' => sub {
for my $payload ('en_US; rm -rf /', "en_US\r\nX-Header: evil", "en_US\x00") {
local %ENV = (LANG => $payload, REMOTE_ADDR => '127.0.0.1');
my $l = _obj();
# language() must not expose any fragment of the payload
my $lang = $l->language();
unlike($lang // '', qr/[|;&\x60\$\r\n\x00]/, "LANG payload not reflected: " . _abbrev($payload));
}
};
# ââ 10. HTTP_USER_AGENT CRLF injection (locale() path) âââââââââââââââââââââââ
# locale() parses the User-Agent parenthetical for a language tag. A crafted
# UA with CRLF could attempt to split the match and inject data.
subtest 'HTTP_USER_AGENT: CRLF in parenthetical does not leak into locale()' => sub {
( run in 1.895 second using v1.01-cache-2.11-cpan-b16cb0d3907 )