@@ -3533,6 +3533,23 @@ PHP_FUNCTION(imap_fetch_overview)
3533
3533
}
3534
3534
/* }}} */
3535
3535
3536
+ static zend_bool header_injection (zend_string * str , zend_bool adrlist )
3537
+ {
3538
+ char * p = ZSTR_VAL (str );
3539
+
3540
+ while ((p = strpbrk (p , "\r\n" )) != NULL ) {
3541
+ if (!(p [0 ] == '\r' && p [1 ] == '\n' )
3542
+ /* adrlists do not support folding, but swallow trailing line breaks */
3543
+ && !((adrlist && p [1 ] == '\0' )
3544
+ /* other headers support folding */
3545
+ || !adrlist && (p [1 ] == ' ' || p [1 ] == '\t' ))) {
3546
+ return 1 ;
3547
+ }
3548
+ p ++ ;
3549
+ }
3550
+ return 0 ;
3551
+ }
3552
+
3536
3553
/* {{{ proto string imap_mail_compose(array envelope, array body)
3537
3554
Create a MIME message based on given envelope and body sections */
3538
3555
PHP_FUNCTION (imap_mail_compose )
@@ -3553,6 +3570,13 @@ PHP_FUNCTION(imap_mail_compose)
3553
3570
return ;
3554
3571
}
3555
3572
3573
+ #define CHECK_HEADER_INJECTION (zstr , adrlist , header ) \
3574
+ if (header_injection(zstr, adrlist)) { \
3575
+ php_error_docref(NULL, E_WARNING, "header injection attempt in " header); \
3576
+ RETVAL_FALSE; \
3577
+ goto done; \
3578
+ }
3579
+
3556
3580
#define PHP_RFC822_PARSE_ADRLIST (target , value ) \
3557
3581
str_copy = estrndup(Z_STRVAL_P(value), Z_STRLEN_P(value)); \
3558
3582
rfc822_parse_adrlist(target, str_copy, "NO HOST"); \
@@ -3561,46 +3585,57 @@ PHP_FUNCTION(imap_mail_compose)
3561
3585
env = mail_newenvelope ();
3562
3586
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "remail" , sizeof ("remail" ) - 1 )) != NULL ) {
3563
3587
convert_to_string_ex (pvalue );
3588
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "remail" );
3564
3589
env -> remail = cpystr (Z_STRVAL_P (pvalue ));
3565
3590
}
3566
3591
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "return_path" , sizeof ("return_path" ) - 1 )) != NULL ) {
3567
3592
convert_to_string_ex (pvalue );
3593
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "return_path" );
3568
3594
PHP_RFC822_PARSE_ADRLIST (& env -> return_path , pvalue );
3569
3595
}
3570
3596
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "date" , sizeof ("date" ) - 1 )) != NULL ) {
3571
3597
convert_to_string_ex (pvalue );
3598
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "date" );
3572
3599
env -> date = (unsigned char * )cpystr (Z_STRVAL_P (pvalue ));
3573
3600
}
3574
3601
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "from" , sizeof ("from" ) - 1 )) != NULL ) {
3575
3602
convert_to_string_ex (pvalue );
3603
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "from" );
3576
3604
PHP_RFC822_PARSE_ADRLIST (& env -> from , pvalue );
3577
3605
}
3578
3606
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "reply_to" , sizeof ("reply_to" ) - 1 )) != NULL ) {
3579
3607
convert_to_string_ex (pvalue );
3608
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "reply_to" );
3580
3609
PHP_RFC822_PARSE_ADRLIST (& env -> reply_to , pvalue );
3581
3610
}
3582
3611
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "in_reply_to" , sizeof ("in_reply_to" ) - 1 )) != NULL ) {
3583
3612
convert_to_string_ex (pvalue );
3613
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "in_reply_to" );
3584
3614
env -> in_reply_to = cpystr (Z_STRVAL_P (pvalue ));
3585
3615
}
3586
3616
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "subject" , sizeof ("subject" ) - 1 )) != NULL ) {
3587
3617
convert_to_string_ex (pvalue );
3618
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "subject" );
3588
3619
env -> subject = cpystr (Z_STRVAL_P (pvalue ));
3589
3620
}
3590
3621
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "to" , sizeof ("to" ) - 1 )) != NULL ) {
3591
3622
convert_to_string_ex (pvalue );
3623
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "to" );
3592
3624
PHP_RFC822_PARSE_ADRLIST (& env -> to , pvalue );
3593
3625
}
3594
3626
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "cc" , sizeof ("cc" ) - 1 )) != NULL ) {
3595
3627
convert_to_string_ex (pvalue );
3628
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "cc" );
3596
3629
PHP_RFC822_PARSE_ADRLIST (& env -> cc , pvalue );
3597
3630
}
3598
3631
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "bcc" , sizeof ("bcc" ) - 1 )) != NULL ) {
3599
3632
convert_to_string_ex (pvalue );
3633
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "bcc" );
3600
3634
PHP_RFC822_PARSE_ADRLIST (& env -> bcc , pvalue );
3601
3635
}
3602
3636
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (envelope ), "message_id" , sizeof ("message_id" ) - 1 )) != NULL ) {
3603
3637
convert_to_string_ex (pvalue );
3638
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "message_id" );
3604
3639
env -> message_id = cpystr (Z_STRVAL_P (pvalue ));
3605
3640
}
3606
3641
@@ -3611,6 +3646,7 @@ PHP_FUNCTION(imap_mail_compose)
3611
3646
ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (pvalue ), env_data ) {
3612
3647
custom_headers_param = mail_newbody_parameter ();
3613
3648
convert_to_string_ex (env_data );
3649
+ CHECK_HEADER_INJECTION (Z_STR_P (env_data ), 0 , "custom_headers" );
3614
3650
custom_headers_param -> value = (char * ) fs_get (Z_STRLEN_P (env_data ) + 1 );
3615
3651
custom_headers_param -> attribute = NULL ;
3616
3652
memcpy (custom_headers_param -> value , Z_STRVAL_P (env_data ), Z_STRLEN_P (env_data ) + 1 );
@@ -3649,6 +3685,7 @@ PHP_FUNCTION(imap_mail_compose)
3649
3685
}
3650
3686
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "charset" , sizeof ("charset" ) - 1 )) != NULL ) {
3651
3687
convert_to_string_ex (pvalue );
3688
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body charset" );
3652
3689
tmp_param = mail_newbody_parameter ();
3653
3690
tmp_param -> value = cpystr (Z_STRVAL_P (pvalue ));
3654
3691
tmp_param -> attribute = cpystr ("CHARSET" );
@@ -3661,9 +3698,11 @@ PHP_FUNCTION(imap_mail_compose)
3661
3698
SEPARATE_ARRAY (pvalue );
3662
3699
ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (pvalue ), key , disp_data ) {
3663
3700
if (key == NULL ) continue ;
3701
+ CHECK_HEADER_INJECTION (key , 0 , "body disposition key" );
3664
3702
disp_param = mail_newbody_parameter ();
3665
3703
disp_param -> attribute = cpystr (ZSTR_VAL (key ));
3666
3704
convert_to_string_ex (disp_data );
3705
+ CHECK_HEADER_INJECTION (Z_STR_P (disp_data ), 0 , "body disposition value" );
3667
3706
disp_param -> value = (char * ) fs_get (Z_STRLEN_P (disp_data ) + 1 );
3668
3707
memcpy (disp_param -> value , Z_STRVAL_P (disp_data ), Z_STRLEN_P (disp_data ) + 1 );
3669
3708
disp_param -> next = tmp_param ;
@@ -3674,18 +3713,22 @@ PHP_FUNCTION(imap_mail_compose)
3674
3713
}
3675
3714
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "subtype" , sizeof ("subtype" ) - 1 )) != NULL ) {
3676
3715
convert_to_string_ex (pvalue );
3716
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body subtype" );
3677
3717
bod -> subtype = cpystr (Z_STRVAL_P (pvalue ));
3678
3718
}
3679
3719
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "id" , sizeof ("id" ) - 1 )) != NULL ) {
3680
3720
convert_to_string_ex (pvalue );
3721
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body id" );
3681
3722
bod -> id = cpystr (Z_STRVAL_P (pvalue ));
3682
3723
}
3683
3724
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "description" , sizeof ("description" ) - 1 )) != NULL ) {
3684
3725
convert_to_string_ex (pvalue );
3726
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body description" );
3685
3727
bod -> description = cpystr (Z_STRVAL_P (pvalue ));
3686
3728
}
3687
3729
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "disposition.type" , sizeof ("disposition.type" ) - 1 )) != NULL ) {
3688
3730
convert_to_string_ex (pvalue );
3731
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body disposition.type" );
3689
3732
bod -> disposition .type = (char * ) fs_get (Z_STRLEN_P (pvalue ) + 1 );
3690
3733
memcpy (bod -> disposition .type , Z_STRVAL_P (pvalue ), Z_STRLEN_P (pvalue )+ 1 );
3691
3734
}
@@ -3695,9 +3738,11 @@ PHP_FUNCTION(imap_mail_compose)
3695
3738
SEPARATE_ARRAY (pvalue );
3696
3739
ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (pvalue ), key , disp_data ) {
3697
3740
if (key == NULL ) continue ;
3741
+ CHECK_HEADER_INJECTION (key , 0 , "body type.parameters key" );
3698
3742
disp_param = mail_newbody_parameter ();
3699
3743
disp_param -> attribute = cpystr (ZSTR_VAL (key ));
3700
3744
convert_to_string_ex (disp_data );
3745
+ CHECK_HEADER_INJECTION (Z_STR_P (disp_data ), 0 , "body type.parameters value" );
3701
3746
disp_param -> value = (char * ) fs_get (Z_STRLEN_P (disp_data ) + 1 );
3702
3747
memcpy (disp_param -> value , Z_STRVAL_P (disp_data ), Z_STRLEN_P (disp_data ) + 1 );
3703
3748
disp_param -> next = tmp_param ;
@@ -3728,6 +3773,7 @@ PHP_FUNCTION(imap_mail_compose)
3728
3773
}
3729
3774
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "md5" , sizeof ("md5" ) - 1 )) != NULL ) {
3730
3775
convert_to_string_ex (pvalue );
3776
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body md5" );
3731
3777
bod -> md5 = cpystr (Z_STRVAL_P (pvalue ));
3732
3778
}
3733
3779
} else if (Z_TYPE_P (data ) == IS_ARRAY && topbod -> type == TYPEMULTIPART ) {
@@ -3760,6 +3806,7 @@ PHP_FUNCTION(imap_mail_compose)
3760
3806
}
3761
3807
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "charset" , sizeof ("charset" ) - 1 )) != NULL ) {
3762
3808
convert_to_string_ex (pvalue );
3809
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body charset" );
3763
3810
tmp_param = mail_newbody_parameter ();
3764
3811
tmp_param -> value = (char * ) fs_get (Z_STRLEN_P (pvalue ) + 1 );
3765
3812
memcpy (tmp_param -> value , Z_STRVAL_P (pvalue ), Z_STRLEN_P (pvalue ) + 1 );
@@ -3773,9 +3820,11 @@ PHP_FUNCTION(imap_mail_compose)
3773
3820
SEPARATE_ARRAY (pvalue );
3774
3821
ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (pvalue ), key , disp_data ) {
3775
3822
if (key == NULL ) continue ;
3823
+ CHECK_HEADER_INJECTION (key , 0 , "body type.parameters key" );
3776
3824
disp_param = mail_newbody_parameter ();
3777
3825
disp_param -> attribute = cpystr (ZSTR_VAL (key ));
3778
3826
convert_to_string_ex (disp_data );
3827
+ CHECK_HEADER_INJECTION (Z_STR_P (disp_data ), 0 , "body type.parameters value" );
3779
3828
disp_param -> value = (char * )fs_get (Z_STRLEN_P (disp_data ) + 1 );
3780
3829
memcpy (disp_param -> value , Z_STRVAL_P (disp_data ), Z_STRLEN_P (disp_data ) + 1 );
3781
3830
disp_param -> next = tmp_param ;
@@ -3786,18 +3835,22 @@ PHP_FUNCTION(imap_mail_compose)
3786
3835
}
3787
3836
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "subtype" , sizeof ("subtype" ) - 1 )) != NULL ) {
3788
3837
convert_to_string_ex (pvalue );
3838
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body subtype" );
3789
3839
bod -> subtype = cpystr (Z_STRVAL_P (pvalue ));
3790
3840
}
3791
3841
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "id" , sizeof ("id" ) - 1 )) != NULL ) {
3792
3842
convert_to_string_ex (pvalue );
3843
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body id" );
3793
3844
bod -> id = cpystr (Z_STRVAL_P (pvalue ));
3794
3845
}
3795
3846
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "description" , sizeof ("description" ) - 1 )) != NULL ) {
3796
3847
convert_to_string_ex (pvalue );
3848
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body description" );
3797
3849
bod -> description = cpystr (Z_STRVAL_P (pvalue ));
3798
3850
}
3799
3851
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "disposition.type" , sizeof ("disposition.type" ) - 1 )) != NULL ) {
3800
3852
convert_to_string_ex (pvalue );
3853
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body disposition.type" );
3801
3854
bod -> disposition .type = (char * ) fs_get (Z_STRLEN_P (pvalue ) + 1 );
3802
3855
memcpy (bod -> disposition .type , Z_STRVAL_P (pvalue ), Z_STRLEN_P (pvalue )+ 1 );
3803
3856
}
@@ -3807,9 +3860,11 @@ PHP_FUNCTION(imap_mail_compose)
3807
3860
SEPARATE_ARRAY (pvalue );
3808
3861
ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (pvalue ), key , disp_data ) {
3809
3862
if (key == NULL ) continue ;
3863
+ CHECK_HEADER_INJECTION (key , 0 , "body disposition key" );
3810
3864
disp_param = mail_newbody_parameter ();
3811
3865
disp_param -> attribute = cpystr (ZSTR_VAL (key ));
3812
3866
convert_to_string_ex (disp_data );
3867
+ CHECK_HEADER_INJECTION (Z_STR_P (disp_data ), 0 , "body disposition value" );
3813
3868
disp_param -> value = (char * ) fs_get (Z_STRLEN_P (disp_data ) + 1 );
3814
3869
memcpy (disp_param -> value , Z_STRVAL_P (disp_data ), Z_STRLEN_P (disp_data ) + 1 );
3815
3870
disp_param -> next = tmp_param ;
@@ -3840,6 +3895,7 @@ PHP_FUNCTION(imap_mail_compose)
3840
3895
}
3841
3896
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "md5" , sizeof ("md5" ) - 1 )) != NULL ) {
3842
3897
convert_to_string_ex (pvalue );
3898
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body md5" );
3843
3899
bod -> md5 = cpystr (Z_STRVAL_P (pvalue ));
3844
3900
}
3845
3901
}
0 commit comments