@@ -3023,6 +3023,23 @@ PHP_FUNCTION(imap_fetch_overview)
3023
3023
}
3024
3024
/* }}} */
3025
3025
3026
+ static zend_bool header_injection (zend_string * str , zend_bool adrlist )
3027
+ {
3028
+ char * p = ZSTR_VAL (str );
3029
+
3030
+ while ((p = strpbrk (p , "\r\n" )) != NULL ) {
3031
+ if (!(p [0 ] == '\r' && p [1 ] == '\n' )
3032
+ /* adrlists do not support folding, but swallow trailing line breaks */
3033
+ && !((adrlist && p [1 ] == '\0' )
3034
+ /* other headers support folding */
3035
+ || !adrlist && (p [1 ] == ' ' || p [1 ] == '\t' ))) {
3036
+ return 1 ;
3037
+ }
3038
+ p ++ ;
3039
+ }
3040
+ return 0 ;
3041
+ }
3042
+
3026
3043
/* {{{ Create a MIME message based on given envelope and body sections */
3027
3044
PHP_FUNCTION (imap_mail_compose )
3028
3045
{
@@ -3046,6 +3063,13 @@ PHP_FUNCTION(imap_mail_compose)
3046
3063
zend_argument_value_error (2 , "cannot be empty" );
3047
3064
}
3048
3065
3066
+ #define CHECK_HEADER_INJECTION (zstr , adrlist , header ) \
3067
+ if (header_injection(zstr, adrlist)) { \
3068
+ php_error_docref(NULL, E_WARNING, "header injection attempt in " header); \
3069
+ RETVAL_FALSE; \
3070
+ goto done; \
3071
+ }
3072
+
3049
3073
#define PHP_RFC822_PARSE_ADRLIST (target , value ) \
3050
3074
str_copy = estrndup(Z_STRVAL_P(value), Z_STRLEN_P(value)); \
3051
3075
rfc822_parse_adrlist(target, str_copy, "NO HOST"); \
@@ -3054,46 +3078,57 @@ PHP_FUNCTION(imap_mail_compose)
3054
3078
env = mail_newenvelope ();
3055
3079
if ((pvalue = zend_hash_str_find (envelope , "remail" , sizeof ("remail" ) - 1 )) != NULL ) {
3056
3080
convert_to_string (pvalue );
3081
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "remail" );
3057
3082
env -> remail = cpystr (Z_STRVAL_P (pvalue ));
3058
3083
}
3059
3084
if ((pvalue = zend_hash_str_find (envelope , "return_path" , sizeof ("return_path" ) - 1 )) != NULL ) {
3060
3085
convert_to_string (pvalue );
3086
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "return_path" );
3061
3087
PHP_RFC822_PARSE_ADRLIST (& env -> return_path , pvalue );
3062
3088
}
3063
3089
if ((pvalue = zend_hash_str_find (envelope , "date" , sizeof ("date" ) - 1 )) != NULL ) {
3064
3090
convert_to_string (pvalue );
3091
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "date" );
3065
3092
env -> date = (unsigned char * )cpystr (Z_STRVAL_P (pvalue ));
3066
3093
}
3067
3094
if ((pvalue = zend_hash_str_find (envelope , "from" , sizeof ("from" ) - 1 )) != NULL ) {
3068
3095
convert_to_string (pvalue );
3096
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "from" );
3069
3097
PHP_RFC822_PARSE_ADRLIST (& env -> from , pvalue );
3070
3098
}
3071
3099
if ((pvalue = zend_hash_str_find (envelope , "reply_to" , sizeof ("reply_to" ) - 1 )) != NULL ) {
3072
3100
convert_to_string (pvalue );
3101
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "reply_to" );
3073
3102
PHP_RFC822_PARSE_ADRLIST (& env -> reply_to , pvalue );
3074
3103
}
3075
3104
if ((pvalue = zend_hash_str_find (envelope , "in_reply_to" , sizeof ("in_reply_to" ) - 1 )) != NULL ) {
3076
3105
convert_to_string (pvalue );
3106
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "in_reply_to" );
3077
3107
env -> in_reply_to = cpystr (Z_STRVAL_P (pvalue ));
3078
3108
}
3079
3109
if ((pvalue = zend_hash_str_find (envelope , "subject" , sizeof ("subject" ) - 1 )) != NULL ) {
3080
3110
convert_to_string (pvalue );
3111
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "subject" );
3081
3112
env -> subject = cpystr (Z_STRVAL_P (pvalue ));
3082
3113
}
3083
3114
if ((pvalue = zend_hash_str_find (envelope , "to" , sizeof ("to" ) - 1 )) != NULL ) {
3084
3115
convert_to_string (pvalue );
3116
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "to" );
3085
3117
PHP_RFC822_PARSE_ADRLIST (& env -> to , pvalue );
3086
3118
}
3087
3119
if ((pvalue = zend_hash_str_find (envelope , "cc" , sizeof ("cc" ) - 1 )) != NULL ) {
3088
3120
convert_to_string (pvalue );
3121
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "cc" );
3089
3122
PHP_RFC822_PARSE_ADRLIST (& env -> cc , pvalue );
3090
3123
}
3091
3124
if ((pvalue = zend_hash_str_find (envelope , "bcc" , sizeof ("bcc" ) - 1 )) != NULL ) {
3092
3125
convert_to_string (pvalue );
3126
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 1 , "bcc" );
3093
3127
PHP_RFC822_PARSE_ADRLIST (& env -> bcc , pvalue );
3094
3128
}
3095
3129
if ((pvalue = zend_hash_str_find (envelope , "message_id" , sizeof ("message_id" ) - 1 )) != NULL ) {
3096
3130
convert_to_string (pvalue );
3131
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "message_id" );
3097
3132
env -> message_id = cpystr (Z_STRVAL_P (pvalue ));
3098
3133
}
3099
3134
@@ -3104,6 +3139,7 @@ PHP_FUNCTION(imap_mail_compose)
3104
3139
ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (pvalue ), env_data ) {
3105
3140
custom_headers_param = mail_newbody_parameter ();
3106
3141
convert_to_string (env_data );
3142
+ CHECK_HEADER_INJECTION (Z_STR_P (env_data ), 0 , "custom_headers" );
3107
3143
custom_headers_param -> value = (char * ) fs_get (Z_STRLEN_P (env_data ) + 1 );
3108
3144
custom_headers_param -> attribute = NULL ;
3109
3145
memcpy (custom_headers_param -> value , Z_STRVAL_P (env_data ), Z_STRLEN_P (env_data ) + 1 );
@@ -3146,6 +3182,7 @@ PHP_FUNCTION(imap_mail_compose)
3146
3182
}
3147
3183
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "charset" , sizeof ("charset" ) - 1 )) != NULL ) {
3148
3184
convert_to_string (pvalue );
3185
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body charset" );
3149
3186
tmp_param = mail_newbody_parameter ();
3150
3187
tmp_param -> value = cpystr (Z_STRVAL_P (pvalue ));
3151
3188
tmp_param -> attribute = cpystr ("CHARSET" );
@@ -3158,9 +3195,11 @@ PHP_FUNCTION(imap_mail_compose)
3158
3195
SEPARATE_ARRAY (pvalue );
3159
3196
ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (pvalue ), key , disp_data ) {
3160
3197
if (key == NULL ) continue ;
3198
+ CHECK_HEADER_INJECTION (key , 0 , "body disposition key" );
3161
3199
disp_param = mail_newbody_parameter ();
3162
3200
disp_param -> attribute = cpystr (ZSTR_VAL (key ));
3163
3201
convert_to_string (disp_data );
3202
+ CHECK_HEADER_INJECTION (Z_STR_P (disp_data ), 0 , "body disposition value" );
3164
3203
disp_param -> value = (char * ) fs_get (Z_STRLEN_P (disp_data ) + 1 );
3165
3204
memcpy (disp_param -> value , Z_STRVAL_P (disp_data ), Z_STRLEN_P (disp_data ) + 1 );
3166
3205
disp_param -> next = tmp_param ;
@@ -3170,19 +3209,23 @@ PHP_FUNCTION(imap_mail_compose)
3170
3209
}
3171
3210
}
3172
3211
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "subtype" , sizeof ("subtype" ) - 1 )) != NULL ) {
3173
- convert_to_string (pvalue );
3212
+ convert_to_string_ex (pvalue );
3213
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body subtype" );
3174
3214
bod -> subtype = cpystr (Z_STRVAL_P (pvalue ));
3175
3215
}
3176
3216
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "id" , sizeof ("id" ) - 1 )) != NULL ) {
3177
3217
convert_to_string (pvalue );
3218
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body id" );
3178
3219
bod -> id = cpystr (Z_STRVAL_P (pvalue ));
3179
3220
}
3180
3221
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "description" , sizeof ("description" ) - 1 )) != NULL ) {
3181
3222
convert_to_string (pvalue );
3223
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body description" );
3182
3224
bod -> description = cpystr (Z_STRVAL_P (pvalue ));
3183
3225
}
3184
3226
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "disposition.type" , sizeof ("disposition.type" ) - 1 )) != NULL ) {
3185
3227
convert_to_string (pvalue );
3228
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body disposition.type" );
3186
3229
bod -> disposition .type = (char * ) fs_get (Z_STRLEN_P (pvalue ) + 1 );
3187
3230
memcpy (bod -> disposition .type , Z_STRVAL_P (pvalue ), Z_STRLEN_P (pvalue )+ 1 );
3188
3231
}
@@ -3192,9 +3235,11 @@ PHP_FUNCTION(imap_mail_compose)
3192
3235
SEPARATE_ARRAY (pvalue );
3193
3236
ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (pvalue ), key , disp_data ) {
3194
3237
if (key == NULL ) continue ;
3238
+ CHECK_HEADER_INJECTION (key , 0 , "body type.parameters key" );
3195
3239
disp_param = mail_newbody_parameter ();
3196
3240
disp_param -> attribute = cpystr (ZSTR_VAL (key ));
3197
3241
convert_to_string (disp_data );
3242
+ CHECK_HEADER_INJECTION (Z_STR_P (disp_data ), 0 , "body type.parameters value" );
3198
3243
disp_param -> value = (char * ) fs_get (Z_STRLEN_P (disp_data ) + 1 );
3199
3244
memcpy (disp_param -> value , Z_STRVAL_P (disp_data ), Z_STRLEN_P (disp_data ) + 1 );
3200
3245
disp_param -> next = tmp_param ;
@@ -3225,6 +3270,7 @@ PHP_FUNCTION(imap_mail_compose)
3225
3270
}
3226
3271
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "md5" , sizeof ("md5" ) - 1 )) != NULL ) {
3227
3272
convert_to_string (pvalue );
3273
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body md5" );
3228
3274
bod -> md5 = cpystr (Z_STRVAL_P (pvalue ));
3229
3275
}
3230
3276
} else if (Z_TYPE_P (data ) == IS_ARRAY && topbod -> type == TYPEMULTIPART ) {
@@ -3256,7 +3302,8 @@ PHP_FUNCTION(imap_mail_compose)
3256
3302
}
3257
3303
}
3258
3304
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "charset" , sizeof ("charset" ) - 1 )) != NULL ) {
3259
- convert_to_string (pvalue );
3305
+ convert_to_string_ex (pvalue );
3306
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body charset" );
3260
3307
tmp_param = mail_newbody_parameter ();
3261
3308
tmp_param -> value = (char * ) fs_get (Z_STRLEN_P (pvalue ) + 1 );
3262
3309
memcpy (tmp_param -> value , Z_STRVAL_P (pvalue ), Z_STRLEN_P (pvalue ) + 1 );
@@ -3270,9 +3317,11 @@ PHP_FUNCTION(imap_mail_compose)
3270
3317
SEPARATE_ARRAY (pvalue );
3271
3318
ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (pvalue ), key , disp_data ) {
3272
3319
if (key == NULL ) continue ;
3320
+ CHECK_HEADER_INJECTION (key , 0 , "body type.parameters key" );
3273
3321
disp_param = mail_newbody_parameter ();
3274
3322
disp_param -> attribute = cpystr (ZSTR_VAL (key ));
3275
- convert_to_string (disp_data );
3323
+ convert_to_string_ex (disp_data );
3324
+ CHECK_HEADER_INJECTION (Z_STR_P (disp_data ), 0 , "body type.parameters value" );
3276
3325
disp_param -> value = (char * )fs_get (Z_STRLEN_P (disp_data ) + 1 );
3277
3326
memcpy (disp_param -> value , Z_STRVAL_P (disp_data ), Z_STRLEN_P (disp_data ) + 1 );
3278
3327
disp_param -> next = tmp_param ;
@@ -3282,19 +3331,23 @@ PHP_FUNCTION(imap_mail_compose)
3282
3331
}
3283
3332
}
3284
3333
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "subtype" , sizeof ("subtype" ) - 1 )) != NULL ) {
3285
- convert_to_string (pvalue );
3334
+ convert_to_string_ex (pvalue );
3335
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body subtype" );
3286
3336
bod -> subtype = cpystr (Z_STRVAL_P (pvalue ));
3287
3337
}
3288
3338
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "id" , sizeof ("id" ) - 1 )) != NULL ) {
3289
- convert_to_string (pvalue );
3339
+ convert_to_string_ex (pvalue );
3340
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body id" );
3290
3341
bod -> id = cpystr (Z_STRVAL_P (pvalue ));
3291
3342
}
3292
3343
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "description" , sizeof ("description" ) - 1 )) != NULL ) {
3293
- convert_to_string (pvalue );
3344
+ convert_to_string_ex (pvalue );
3345
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body description" );
3294
3346
bod -> description = cpystr (Z_STRVAL_P (pvalue ));
3295
3347
}
3296
3348
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "disposition.type" , sizeof ("disposition.type" ) - 1 )) != NULL ) {
3297
- convert_to_string (pvalue );
3349
+ convert_to_string_ex (pvalue );
3350
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body disposition.type" );
3298
3351
bod -> disposition .type = (char * ) fs_get (Z_STRLEN_P (pvalue ) + 1 );
3299
3352
memcpy (bod -> disposition .type , Z_STRVAL_P (pvalue ), Z_STRLEN_P (pvalue )+ 1 );
3300
3353
}
@@ -3304,9 +3357,11 @@ PHP_FUNCTION(imap_mail_compose)
3304
3357
SEPARATE_ARRAY (pvalue );
3305
3358
ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (pvalue ), key , disp_data ) {
3306
3359
if (key == NULL ) continue ;
3360
+ CHECK_HEADER_INJECTION (key , 0 , "body disposition key" );
3307
3361
disp_param = mail_newbody_parameter ();
3308
3362
disp_param -> attribute = cpystr (ZSTR_VAL (key ));
3309
- convert_to_string (disp_data );
3363
+ convert_to_string_ex (disp_data );
3364
+ CHECK_HEADER_INJECTION (Z_STR_P (disp_data ), 0 , "body disposition value" );
3310
3365
disp_param -> value = (char * ) fs_get (Z_STRLEN_P (disp_data ) + 1 );
3311
3366
memcpy (disp_param -> value , Z_STRVAL_P (disp_data ), Z_STRLEN_P (disp_data ) + 1 );
3312
3367
disp_param -> next = tmp_param ;
@@ -3336,7 +3391,8 @@ PHP_FUNCTION(imap_mail_compose)
3336
3391
bod -> size .bytes = zval_get_long (pvalue );
3337
3392
}
3338
3393
if ((pvalue = zend_hash_str_find (Z_ARRVAL_P (data ), "md5" , sizeof ("md5" ) - 1 )) != NULL ) {
3339
- convert_to_string (pvalue );
3394
+ convert_to_string_ex (pvalue );
3395
+ CHECK_HEADER_INJECTION (Z_STR_P (pvalue ), 0 , "body md5" );
3340
3396
bod -> md5 = cpystr (Z_STRVAL_P (pvalue ));
3341
3397
}
3342
3398
}
0 commit comments