This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Gets the email message from the user's mailbox to add as |
||
4 | * a WordPress post. Mailbox connection information must be |
||
5 | * configured under Settings > Writing |
||
6 | * |
||
7 | * @package WordPress |
||
8 | */ |
||
9 | |||
10 | /** Make sure that the WordPress bootstrap has run before continuing. */ |
||
11 | require(dirname(__FILE__) . '/wp-load.php'); |
||
12 | |||
13 | /** This filter is documented in wp-admin/options.php */ |
||
14 | if ( ! apply_filters( 'enable_post_by_email_configuration', true ) ) |
||
15 | wp_die( __( 'This action has been disabled by the administrator.' ), 403 ); |
||
16 | |||
17 | $mailserver_url = get_option( 'mailserver_url' ); |
||
18 | |||
19 | if ( 'mail.example.com' === $mailserver_url || empty( $mailserver_url ) ) { |
||
20 | wp_die( __( 'This action has been disabled by the administrator.' ), 403 ); |
||
21 | } |
||
22 | |||
23 | /** |
||
24 | * Fires to allow a plugin to do a complete takeover of Post by Email. |
||
25 | * |
||
26 | * @since 2.9.0 |
||
27 | */ |
||
28 | do_action( 'wp-mail.php' ); |
||
29 | |||
30 | /** Get the POP3 class with which to access the mailbox. */ |
||
31 | require_once( ABSPATH . WPINC . '/class-pop3.php' ); |
||
32 | |||
33 | /** Only check at this interval for new messages. */ |
||
34 | if ( !defined('WP_MAIL_INTERVAL') ) |
||
35 | define('WP_MAIL_INTERVAL', 300); // 5 minutes |
||
36 | |||
37 | $last_checked = get_transient('mailserver_last_checked'); |
||
38 | |||
39 | if ( $last_checked ) |
||
40 | wp_die(__('Slow down cowboy, no need to check for new mails so often!')); |
||
41 | |||
42 | set_transient('mailserver_last_checked', true, WP_MAIL_INTERVAL); |
||
43 | |||
44 | $time_difference = get_option('gmt_offset') * HOUR_IN_SECONDS; |
||
45 | |||
46 | $phone_delim = '::'; |
||
47 | |||
48 | $pop3 = new POP3(); |
||
49 | |||
50 | if ( !$pop3->connect( get_option('mailserver_url'), get_option('mailserver_port') ) || !$pop3->user( get_option('mailserver_login') ) ) |
||
51 | wp_die( esc_html( $pop3->ERROR ) ); |
||
52 | |||
53 | $count = $pop3->pass( get_option('mailserver_pass') ); |
||
54 | |||
55 | if( false === $count ) |
||
56 | wp_die( esc_html( $pop3->ERROR ) ); |
||
57 | |||
58 | if( 0 === $count ) { |
||
59 | $pop3->quit(); |
||
60 | wp_die( __('There doesn’t seem to be any new mail.') ); |
||
61 | } |
||
62 | |||
63 | for ( $i = 1; $i <= $count; $i++ ) { |
||
64 | |||
65 | $message = $pop3->get($i); |
||
66 | |||
67 | $bodysignal = false; |
||
68 | $boundary = ''; |
||
69 | $charset = ''; |
||
70 | $content = ''; |
||
71 | $content_type = ''; |
||
72 | $content_transfer_encoding = ''; |
||
73 | $post_author = 1; |
||
74 | $author_found = false; |
||
75 | foreach ($message as $line) { |
||
0 ignored issues
–
show
|
|||
76 | // Body signal. |
||
77 | if ( strlen($line) < 3 ) |
||
78 | $bodysignal = true; |
||
79 | if ( $bodysignal ) { |
||
80 | $content .= $line; |
||
81 | } else { |
||
82 | if ( preg_match('/Content-Type: /i', $line) ) { |
||
83 | $content_type = trim($line); |
||
84 | $content_type = substr($content_type, 14, strlen($content_type) - 14); |
||
85 | $content_type = explode(';', $content_type); |
||
86 | if ( ! empty( $content_type[1] ) ) { |
||
87 | $charset = explode('=', $content_type[1]); |
||
88 | $charset = ( ! empty( $charset[1] ) ) ? trim($charset[1]) : ''; |
||
89 | } |
||
90 | $content_type = $content_type[0]; |
||
91 | } |
||
92 | if ( preg_match('/Content-Transfer-Encoding: /i', $line) ) { |
||
93 | $content_transfer_encoding = trim($line); |
||
94 | $content_transfer_encoding = substr($content_transfer_encoding, 27, strlen($content_transfer_encoding) - 27); |
||
95 | $content_transfer_encoding = explode(';', $content_transfer_encoding); |
||
96 | $content_transfer_encoding = $content_transfer_encoding[0]; |
||
97 | } |
||
98 | if ( ( $content_type == 'multipart/alternative' ) && ( false !== strpos($line, 'boundary="') ) && ( '' == $boundary ) ) { |
||
99 | $boundary = trim($line); |
||
100 | $boundary = explode('"', $boundary); |
||
101 | $boundary = $boundary[1]; |
||
102 | } |
||
103 | if (preg_match('/Subject: /i', $line)) { |
||
104 | $subject = trim($line); |
||
105 | $subject = substr($subject, 9, strlen($subject) - 9); |
||
106 | // Captures any text in the subject before $phone_delim as the subject |
||
107 | if ( function_exists('iconv_mime_decode') ) { |
||
108 | $subject = iconv_mime_decode($subject, 2, get_option('blog_charset')); |
||
109 | } else { |
||
110 | $subject = wp_iso_descrambler($subject); |
||
111 | } |
||
112 | $subject = explode($phone_delim, $subject); |
||
113 | $subject = $subject[0]; |
||
114 | } |
||
115 | |||
116 | /* |
||
117 | * Set the author using the email address (From or Reply-To, the last used) |
||
118 | * otherwise use the site admin. |
||
119 | */ |
||
120 | if ( ! $author_found && preg_match( '/^(From|Reply-To): /', $line ) ) { |
||
121 | if ( preg_match('|[a-z0-9_.-]+@[a-z0-9_.-]+(?!.*<)|i', $line, $matches) ) |
||
122 | $author = $matches[0]; |
||
123 | else |
||
124 | $author = trim($line); |
||
125 | $author = sanitize_email($author); |
||
126 | if ( is_email($author) ) { |
||
127 | /* translators: Post author email address */ |
||
128 | echo '<p>' . sprintf(__('Author is %s'), $author) . '</p>'; |
||
129 | $userdata = get_user_by('email', $author); |
||
130 | if ( ! empty( $userdata ) ) { |
||
131 | $post_author = $userdata->ID; |
||
132 | $author_found = true; |
||
133 | } |
||
134 | } |
||
135 | } |
||
136 | |||
137 | if ( preg_match( '/Date: /i', $line ) ) { // of the form '20 Mar 2002 20:32:37 +0100' |
||
138 | $ddate = str_replace( 'Date: ', '', trim( $line ) ); |
||
139 | $ddate = preg_replace( '!\s*\(.+\)\s*$!', '', $ddate ); // remove parenthesised timezone string if it exists, as this confuses strtotime |
||
140 | $ddate_U = strtotime( $ddate ); |
||
141 | $post_date = gmdate( 'Y-m-d H:i:s', $ddate_U + $time_difference ); |
||
142 | $post_date_gmt = gmdate( 'Y-m-d H:i:s', $ddate_U ); |
||
143 | } |
||
144 | } |
||
145 | } |
||
146 | |||
147 | // Set $post_status based on $author_found and on author's publish_posts capability |
||
148 | if ( $author_found ) { |
||
149 | $user = new WP_User($post_author); |
||
150 | $post_status = ( $user->has_cap('publish_posts') ) ? 'publish' : 'pending'; |
||
151 | } else { |
||
152 | // Author not found in DB, set status to pending. Author already set to admin. |
||
153 | $post_status = 'pending'; |
||
154 | } |
||
155 | |||
156 | $subject = trim($subject); |
||
157 | |||
158 | if ( $content_type == 'multipart/alternative' ) { |
||
159 | $content = explode('--'.$boundary, $content); |
||
160 | $content = $content[2]; |
||
161 | |||
162 | // Match case-insensitive content-transfer-encoding. |
||
163 | if ( preg_match( '/Content-Transfer-Encoding: quoted-printable/i', $content, $delim) ) { |
||
164 | $content = explode($delim[0], $content); |
||
165 | $content = $content[1]; |
||
166 | } |
||
167 | $content = strip_tags($content, '<img><p><br><i><b><u><em><strong><strike><font><span><div>'); |
||
168 | } |
||
169 | $content = trim($content); |
||
170 | |||
171 | /** |
||
172 | * Filters the original content of the email. |
||
173 | * |
||
174 | * Give Post-By-Email extending plugins full access to the content, either |
||
175 | * the raw content, or the content of the last quoted-printable section. |
||
176 | * |
||
177 | * @since 2.8.0 |
||
178 | * |
||
179 | * @param string $content The original email content. |
||
180 | */ |
||
181 | $content = apply_filters( 'wp_mail_original_content', $content ); |
||
182 | |||
183 | if ( false !== stripos($content_transfer_encoding, "quoted-printable") ) { |
||
184 | $content = quoted_printable_decode($content); |
||
185 | } |
||
186 | |||
187 | if ( function_exists('iconv') && ! empty( $charset ) ) { |
||
188 | $content = iconv($charset, get_option('blog_charset'), $content); |
||
189 | } |
||
190 | |||
191 | // Captures any text in the body after $phone_delim as the body |
||
192 | $content = explode($phone_delim, $content); |
||
193 | $content = empty( $content[1] ) ? $content[0] : $content[1]; |
||
194 | |||
195 | $content = trim($content); |
||
196 | |||
197 | /** |
||
198 | * Filters the content of the post submitted by email before saving. |
||
199 | * |
||
200 | * @since 1.2.0 |
||
201 | * |
||
202 | * @param string $content The email content. |
||
203 | */ |
||
204 | $post_content = apply_filters( 'phone_content', $content ); |
||
205 | |||
206 | $post_title = xmlrpc_getposttitle($content); |
||
207 | |||
208 | if ($post_title == '') $post_title = $subject; |
||
209 | |||
210 | $post_category = array(get_option('default_email_category')); |
||
211 | |||
212 | $post_data = compact('post_content','post_title','post_date','post_date_gmt','post_author','post_category', 'post_status'); |
||
213 | $post_data = wp_slash($post_data); |
||
214 | |||
215 | $post_ID = wp_insert_post($post_data); |
||
216 | if ( is_wp_error( $post_ID ) ) |
||
217 | echo "\n" . $post_ID->get_error_message(); |
||
218 | |||
219 | // We couldn't post, for whatever reason. Better move forward to the next email. |
||
220 | if ( empty( $post_ID ) ) |
||
221 | continue; |
||
222 | |||
223 | /** |
||
224 | * Fires after a post submitted by email is published. |
||
225 | * |
||
226 | * @since 1.2.0 |
||
227 | * |
||
228 | * @param int $post_ID The post ID. |
||
229 | */ |
||
230 | do_action( 'publish_phone', $post_ID ); |
||
231 | |||
232 | echo "\n<p><strong>" . __( 'Author:' ) . '</strong> ' . esc_html( $post_author ) . '</p>'; |
||
233 | echo "\n<p><strong>" . __( 'Posted title:' ) . '</strong> ' . esc_html( $post_title ) . '</p>'; |
||
234 | |||
235 | if(!$pop3->delete($i)) { |
||
236 | echo '<p>' . sprintf( |
||
237 | /* translators: %s: POP3 error */ |
||
238 | __( 'Oops: %s' ), |
||
239 | esc_html( $pop3->ERROR ) |
||
240 | ) . '</p>'; |
||
241 | $pop3->reset(); |
||
242 | exit; |
||
243 | } else { |
||
244 | echo '<p>' . sprintf( |
||
245 | /* translators: %s: the message ID */ |
||
246 | __( 'Mission complete. Message %s deleted.' ), |
||
247 | '<strong>' . $i . '</strong>' |
||
248 | ) . '</p>'; |
||
249 | } |
||
250 | |||
251 | } |
||
252 | |||
253 | $pop3->quit(); |
||
254 |
There are different options of fixing this problem.
If you want to be on the safe side, you can add an additional type-check:
If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:
Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.