Perl-Critic-Policy-Security-RandBytesFromHash
view release on metacpan or search on metacpan
lib/Perl/Critic/Policy/Security/RandBytesFromHash.pm view on Meta::CPAN
package Perl::Critic::Policy::Security::RandBytesFromHash;
# ABSTRACT: flag common anti-patterns for generating random bytes
use v5.24;
use warnings;
use parent 'Perl::Critic::Policy';
use List::Util qw( any );
use Perl::Critic::Utils qw( :severities :classification :ppi );
use PPI 1.281; # signatures support
use Readonly 2.01;
use Ref::Util qw( is_plain_arrayref );
# RECOMMEND PREREQ: Ref::Util::XS
our $VERSION = 'v0.1.3';
Readonly my $DESC => 'random bytes generated using a hash';
Readonly my $EXPL => 'A hash seeded with poor sources of entropy is still a poor source of entropy, use system entropy instead.';
use experimental qw( signatures );
sub supported_parameters { () }
sub default_severity { $SEVERITY_HIGH }
sub default_themes { return qw( security cpansec ) }
sub applies_to { 'PPI::Token::Word' }
Readonly my $DIGEST_REGEX => qr/\A (
( \w+:: )*
( md[2456] | sha( 1 | 224 | 256 ) | digest_data | (hex|b64)?digest(_hash)? | join )
( _ ( hex | b64u? | base64 | sum | bytes ) )?
) \z/anx;
sub violates ( $self, $elem, $ ) {
if ( $elem =~ $DIGEST_REGEX && ( is_function_call($elem) || is_method_call($elem) ) )
{
my @args = parse_arg_list($elem);
if ( $self->_is_bad_seed_source( \@args ) ) {
return $self->violation( $DESC, $EXPL, $elem );
}
}
return ();
}
sub _is_bad_seed_source( $self, $elem ) {
if ( is_plain_arrayref($elem) ) {
return any { $self->_is_bad_seed_source($_) } $elem->@*;
}
return 0 if $elem->isa("PPI::Token::Whitespace");
return 1
if $elem =~ /\A ( (CORE::)?rand | (Time::HiRes::)? (time|gettimeofday|localtime|gmtime|clock_gettime) | refaddr ) \z/anx
&& ( is_perl_builtin_with_optional_argument($elem)
|| is_function_call($elem) );
return 1 if $elem eq '$$' && is_perl_global($elem);
return 1 if $elem =~ /\A \$ (PID|PROCESS_ID) \z/anx && $elem->isa("PPI::Token::Symbol");
if ( $elem->isa("PPI::Structure") ) {
return any { $self->_is_bad_seed_source($_) } $elem->children
}
elsif ( $elem->isa("PPI::Statement") ) {
return any { $self->_is_bad_seed_source($_) } $elem->children
( run in 2.385 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )