@@ -3551,6 +3551,23 @@ PHP_FUNCTION(imap_fetch_overview)
3551
3551
}
3552
3552
/* }}} */
3553
3553
3554
+ static zend_bool header_injection (zend_string * str , zend_bool adrlist )
3555
+ {
3556
+ char * p = ZSTR_VAL (str );
3557
+
3558
+ while ((p = strpbrk (p , "\r\n" )) != NULL ) {
3559
+ if (!(p [0 ] == '\r' && p [1 ] == '\n' )
3560
+ /* adrlists do not support folding, but swallow trailing line breaks */
3561
+ && !((adrlist && p [1 ] == '\0' )
3562
+ /* other headers support folding */
3563
+ || !adrlist && (p [1 ] == ' ' || p [1 ] == '\t' ))) {
3564
+ return 1 ;
3565
+ }
3566
+ p ++ ;
3567
+ }
3568
+ return 0 ;
3569
+ }
3570
+
3554
3571
/* {{{ proto string imap_mail_compose(array envelope, array body)
3555
3572
Create a MIME message based on given envelope and body sections */
3556
3573
PHP_FUNCTION (imap_mail_compose )
@@ -3571,6 +3588,13 @@ PHP_FUNCTION(imap_mail_compose)
3571
3588
return ;
3572
3589
}
3573
3590
3591
+ #define CHECK_HEADER_INJECTION (zstr , adrlist , header ) \
3592
+ if (header_injection(zstr, adrlist)) { \
3593
+ php_error_docref(NULL, E_WARNING, "header injection attempt in " header); \
3594
+ RETVAL_FALSE; \
3595
+ goto done; \
3596
+ }
3597
+
3574
3598
#define PHP_RFC822_PARSE_ADRLIST (target , value ) \
3575
3599
str_copy = estrndup(Z_STRVAL_P(value), Z_STRLEN_P(value)); \
3576
3600
rfc822_parse_adrlist(target, str_copy, "NO HOST"); \
@@ -3579,46 +3603,57 @@ PHP_FUNCTION(imap_mail_compose)
3579
3603
env = mail_newenvelope ();
3580
3604
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "remail" , sizeof ("remail" ) - 1 )) != NULL ) {
3581
3605
convert_to_string_ex (pvalue );
3606
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "remail" );
3582
3607
env -> remail = cpystr (Z_STRVAL_P (pvalue ));
3583
3608
}
3584
3609
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "return_path" , sizeof ("return_path" ) - 1 )) != NULL ) {
3585
3610
convert_to_string_ex (pvalue );
3611
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "return_path" );
3586
3612
PHP_RFC822_PARSE_ADRLIST (& env -> return_path , pvalue );
3587
3613
}
3588
3614
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "date" , sizeof ("date" ) - 1 )) != NULL ) {
3589
3615
convert_to_string_ex (pvalue );
3616
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "date" );
3590
3617
env -> date = (unsigned char * )cpystr (Z_STRVAL_P (pvalue ));
3591
3618
}
3592
3619
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "from" , sizeof ("from" ) - 1 )) != NULL ) {
3593
3620
convert_to_string_ex (pvalue );
3621
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "from" );
3594
3622
PHP_RFC822_PARSE_ADRLIST (& env -> from , pvalue );
3595
3623
}
3596
3624
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "reply_to" , sizeof ("reply_to" ) - 1 )) != NULL ) {
3597
3625
convert_to_string_ex (pvalue );
3626
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "reply_to" );
3598
3627
PHP_RFC822_PARSE_ADRLIST (& env -> reply_to , pvalue );
3599
3628
}
3600
3629
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "in_reply_to" , sizeof ("in_reply_to" ) - 1 )) != NULL ) {
3601
3630
convert_to_string_ex (pvalue );
3631
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "in_reply_to" );
3602
3632
env -> in_reply_to = cpystr (Z_STRVAL_P (pvalue ));
3603
3633
}
3604
3634
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "subject" , sizeof ("subject" ) - 1 )) != NULL ) {
3605
3635
convert_to_string_ex (pvalue );
3636
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "subject" );
3606
3637
env -> subject = cpystr (Z_STRVAL_P (pvalue ));
3607
3638
}
3608
3639
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "to" , sizeof ("to" ) - 1 )) != NULL ) {
3609
3640
convert_to_string_ex (pvalue );
3641
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "to" );
3610
3642
PHP_RFC822_PARSE_ADRLIST (& env -> to , pvalue );
3611
3643
}
3612
3644
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "cc" , sizeof ("cc" ) - 1 )) != NULL ) {
3613
3645
convert_to_string_ex (pvalue );
3646
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "cc" );
3614
3647
PHP_RFC822_PARSE_ADRLIST (& env -> cc , pvalue );
3615
3648
}
3616
3649
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "bcc" , sizeof ("bcc" ) - 1 )) != NULL ) {
3617
3650
convert_to_string_ex (pvalue );
3651
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "bcc" );
3618
3652
PHP_RFC822_PARSE_ADRLIST (& env -> bcc , pvalue );
3619
3653
}
3620
3654
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "message_id" , sizeof ("message_id" ) - 1 )) != NULL ) {
3621
3655
convert_to_string_ex (pvalue );
3656
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "message_id" );
3622
3657
env -> message_id = cpystr (Z_STRVAL_P (pvalue ));
3623
3658
}
3624
3659
@@ -3629,6 +3664,7 @@ PHP_FUNCTION(imap_mail_compose)
3629
3664
ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (pvalue ), env_data ) {
3630
3665
custom_headers_param = mail_newbody_parameter ();
3631
3666
convert_to_string_ex (env_data );
3667
+ CHECK_HEADER_INJECTION (Z_STR_P (env_data ), 0 , "custom_headers" );
3632
3668
custom_headers_param -> value = (char * ) fs_get (Z_STRLEN_P (env_data ) + 1 );
3633
3669
custom_headers_param -> attribute = NULL ;
3634
3670
memcpy (custom_headers_param -> value , Z_STRVAL_P (env_data ), Z_STRLEN_P (env_data ) + 1 );
@@ -3667,6 +3703,7 @@ PHP_FUNCTION(imap_mail_compose)
3667
3703
}
3668
3704
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "charset" , sizeof ("charset" ) - 1 )) != NULL ) {
3669
3705
convert_to_string_ex (pvalue );
3706
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body charset" );
3670
3707
tmp_param = mail_newbody_parameter ();
3671
3708
tmp_param -> value = cpystr (Z_STRVAL_P (pvalue ));
3672
3709
tmp_param -> attribute = cpystr ("CHARSET" );
@@ -3679,9 +3716,11 @@ PHP_FUNCTION(imap_mail_compose)
3679
3716
SEPARATE_ARRAY (pvalue );
3680
3717
ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (pvalue ), key , disp_data ) {
3681
3718
if (key == NULL ) continue ;
3719
+ CHECK_HEADER_INJECTION (key , 0 , "body disposition key" );
3682
3720
disp_param = mail_newbody_parameter ();
3683
3721
disp_param -> attribute = cpystr (ZSTR_VAL (key ));
3684
3722
convert_to_string_ex (disp_data );
3723
+ CHECK_HEADER_INJECTION (Z_STR_P (disp_data ), 0 , "body disposition value" );
3685
3724
disp_param -> value = (char * ) fs_get (Z_STRLEN_P (disp_data ) + 1 );
3686
3725
memcpy (disp_param -> value , Z_STRVAL_P (disp_data ), Z_STRLEN_P (disp_data ) + 1 );
3687
3726
disp_param -> next = tmp_param ;
@@ -3692,18 +3731,22 @@ PHP_FUNCTION(imap_mail_compose)
3692
3731
}
3693
3732
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "subtype" , sizeof ("subtype" ) - 1 )) != NULL ) {
3694
3733
convert_to_string_ex (pvalue );
3734
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body subtype" );
3695
3735
bod -> subtype = cpystr (Z_STRVAL_P (pvalue ));
3696
3736
}
3697
3737
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "id" , sizeof ("id" ) - 1 )) != NULL ) {
3698
3738
convert_to_string_ex (pvalue );
3739
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body id" );
3699
3740
bod -> id = cpystr (Z_STRVAL_P (pvalue ));
3700
3741
}
3701
3742
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "description" , sizeof ("description" ) - 1 )) != NULL ) {
3702
3743
convert_to_string_ex (pvalue );
3744
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body description" );
3703
3745
bod -> description = cpystr (Z_STRVAL_P (pvalue ));
3704
3746
}
3705
3747
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "disposition.type" , sizeof ("disposition.type" ) - 1 )) != NULL ) {
3706
3748
convert_to_string_ex (pvalue );
3749
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body disposition.type" );
3707
3750
bod -> disposition .type = (char * ) fs_get (Z_STRLEN_P (pvalue ) + 1 );
3708
3751
memcpy (bod -> disposition .type , Z_STRVAL_P (pvalue ), Z_STRLEN_P (pvalue )+ 1 );
3709
3752
}
@@ -3713,9 +3756,11 @@ PHP_FUNCTION(imap_mail_compose)
3713
3756
SEPARATE_ARRAY (pvalue );
3714
3757
ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (pvalue ), key , disp_data ) {
3715
3758
if (key == NULL ) continue ;
3759
+ CHECK_HEADER_INJECTION (key , 0 , "body type.parameters key" );
3716
3760
disp_param = mail_newbody_parameter ();
3717
3761
disp_param -> attribute = cpystr (ZSTR_VAL (key ));
3718
3762
convert_to_string_ex (disp_data );
3763
+ CHECK_HEADER_INJECTION (Z_STR_P (disp_data ), 0 , "body type.parameters value" );
3719
3764
disp_param -> value = (char * ) fs_get (Z_STRLEN_P (disp_data ) + 1 );
3720
3765
memcpy (disp_param -> value , Z_STRVAL_P (disp_data ), Z_STRLEN_P (disp_data ) + 1 );
3721
3766
disp_param -> next = tmp_param ;
@@ -3746,6 +3791,7 @@ PHP_FUNCTION(imap_mail_compose)
3746
3791
}
3747
3792
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "md5" , sizeof ("md5" ) - 1 )) != NULL ) {
3748
3793
convert_to_string_ex (pvalue );
3794
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body md5" );
3749
3795
bod -> md5 = cpystr (Z_STRVAL_P (pvalue ));
3750
3796
}
3751
3797
} else if (Z_TYPE_P (data ) == IS_ARRAY && topbod -> type == TYPEMULTIPART ) {
@@ -3778,6 +3824,7 @@ PHP_FUNCTION(imap_mail_compose)
3778
3824
}
3779
3825
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "charset" , sizeof ("charset" ) - 1 )) != NULL ) {
3780
3826
convert_to_string_ex (pvalue );
3827
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body charset" );
3781
3828
tmp_param = mail_newbody_parameter ();
3782
3829
tmp_param -> value = (char * ) fs_get (Z_STRLEN_P (pvalue ) + 1 );
3783
3830
memcpy (tmp_param -> value , Z_STRVAL_P (pvalue ), Z_STRLEN_P (pvalue ) + 1 );
@@ -3791,9 +3838,11 @@ PHP_FUNCTION(imap_mail_compose)
3791
3838
SEPARATE_ARRAY (pvalue );
3792
3839
ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (pvalue ), key , disp_data ) {
3793
3840
if (key == NULL ) continue ;
3841
+ CHECK_HEADER_INJECTION (key , 0 , "body type.parameters key" );
3794
3842
disp_param = mail_newbody_parameter ();
3795
3843
disp_param -> attribute = cpystr (ZSTR_VAL (key ));
3796
3844
convert_to_string_ex (disp_data );
3845
+ CHECK_HEADER_INJECTION (Z_STR_P (disp_data ), 0 , "body type.parameters value" );
3797
3846
disp_param -> value = (char * )fs_get (Z_STRLEN_P (disp_data ) + 1 );
3798
3847
memcpy (disp_param -> value , Z_STRVAL_P (disp_data ), Z_STRLEN_P (disp_data ) + 1 );
3799
3848
disp_param -> next = tmp_param ;
@@ -3804,18 +3853,22 @@ PHP_FUNCTION(imap_mail_compose)
3804
3853
}
3805
3854
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "subtype" , sizeof ("subtype" ) - 1 )) != NULL ) {
3806
3855
convert_to_string_ex (pvalue );
3856
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body subtype" );
3807
3857
bod -> subtype = cpystr (Z_STRVAL_P (pvalue ));
3808
3858
}
3809
3859
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "id" , sizeof ("id" ) - 1 )) != NULL ) {
3810
3860
convert_to_string_ex (pvalue );
3861
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body id" );
3811
3862
bod -> id = cpystr (Z_STRVAL_P (pvalue ));
3812
3863
}
3813
3864
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "description" , sizeof ("description" ) - 1 )) != NULL ) {
3814
3865
convert_to_string_ex (pvalue );
3866
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body description" );
3815
3867
bod -> description = cpystr (Z_STRVAL_P (pvalue ));
3816
3868
}
3817
3869
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "disposition.type" , sizeof ("disposition.type" ) - 1 )) != NULL ) {
3818
3870
convert_to_string_ex (pvalue );
3871
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body disposition.type" );
3819
3872
bod -> disposition .type = (char * ) fs_get (Z_STRLEN_P (pvalue ) + 1 );
3820
3873
memcpy (bod -> disposition .type , Z_STRVAL_P (pvalue ), Z_STRLEN_P (pvalue )+ 1 );
3821
3874
}
@@ -3825,9 +3878,11 @@ PHP_FUNCTION(imap_mail_compose)
3825
3878
SEPARATE_ARRAY (pvalue );
3826
3879
ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (pvalue ), key , disp_data ) {
3827
3880
if (key == NULL ) continue ;
3881
+ CHECK_HEADER_INJECTION (key , 0 , "body disposition key" );
3828
3882
disp_param = mail_newbody_parameter ();
3829
3883
disp_param -> attribute = cpystr (ZSTR_VAL (key ));
3830
3884
convert_to_string_ex (disp_data );
3885
+ CHECK_HEADER_INJECTION (Z_STR_P (disp_data ), 0 , "body disposition value" );
3831
3886
disp_param -> value = (char * ) fs_get (Z_STRLEN_P (disp_data ) + 1 );
3832
3887
memcpy (disp_param -> value , Z_STRVAL_P (disp_data ), Z_STRLEN_P (disp_data ) + 1 );
3833
3888
disp_param -> next = tmp_param ;
@@ -3858,6 +3913,7 @@ PHP_FUNCTION(imap_mail_compose)
3858
3913
}
3859
3914
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "md5" , sizeof ("md5" ) - 1 )) != NULL ) {
3860
3915
convert_to_string_ex (pvalue );
3916
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body md5" );
3861
3917
bod -> md5 = cpystr (Z_STRVAL_P (pvalue ));
3862
3918
}
3863
3919
}
0 commit comments