1<?php 2 3// service closed until we can filter spam 4//die ('[CLOSED]'); 5 6include_once 'note-reasons.inc'; 7include_once 'spam-lib.inc'; 8include_once 'functions.inc'; 9 10$mailto = 'php-notes@lists.php.net'; 11$failto = 'jimw@php.net, alindeman@php.net, danbrown@php.net'; 12 13function validateUser($user) { 14 $ret = filter_var($user, FILTER_VALIDATE_EMAIL); 15 16 // If its not a valid email then strip all tags and \r & \n (since this will be used in the mail "from" header) / 17 if(!$ret) { 18 $ret = filter_var($user, FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_HIGH); 19 $ret = str_replace(["\r", "\n"], "", $ret); 20 } 21 return trim($ret); 22} 23 24 25$user = filter_input(INPUT_POST, "user", FILTER_CALLBACK, ["filter" => FILTER_CALLBACK, "options" => "validateUser"]); 26$note = filter_input(INPUT_POST, "note", FILTER_UNSAFE_RAW); 27$sect = filter_input(INPUT_POST, "sect", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_HIGH); 28$ip = filter_input(INPUT_POST, "ip", FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE|FILTER_FLAG_NO_RES_RANGE); 29$redirip = filter_input(INPUT_POST, "redirip", FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE|FILTER_FLAG_NO_RES_RANGE); 30 31if (empty($user) || empty($note) || empty($sect) || !$ip) 32 die("missing some parameters."); 33 34 35/* SPAM Checks ******************************************/ 36$note_lc = strtolower($note); 37 38// Disallow URL SPAM 39if (check_spam_urls($note_lc, 4)) { 40 die ('[SPAM WORD]'); 41} 42 43// Compare the text against a known list of bad words 44if (check_spam_words($note_lc, $words_blacklist)) { 45 die('[SPAM WORD]'); 46} 47 48// Check if the IP is blacklisted 49if (($spamip=is_spam_ip($_SERVER['REMOTE_ADDR'])) || ($spamip=is_spam_ip($ip)) || ($redirip && $spamip=is_spam_ip($redirip))) { 50 die ("[SPAMMER] $spamip"); 51} 52 53unset($note_lc); 54/* End SPAM Checks ******************************************/ 55 56db_connect(); 57 58/* 59After a discussion in #php about the 60vulnerability of the user notes system, 61I decided to implement a bit of hack 62prevention. This makes sure that only 633 notes can be submitted per minute, which 64is very reasonable considering the current 65flow of notes usually submitted. This prevents 66a large flood of notes from coming in. 67*/ 68$query = 'SELECT COUNT(*) FROM note WHERE ts >= (NOW() - INTERVAL 1 MINUTE)'; 69$result = db_query_safe($query); 70 71if (!$result) { 72 mail ($failto, 73 'failed manual note query', 74 "Query Failed: $query\nError: ".mysql_error(), 75 'From: php-webmaster@lists.php.net', 76 '-fnoreply@php.net' 77 ); 78 die("failed to query note db"); 79} 80 81list ($count) = mysql_fetch_row ($result); 82 83if ($count >= 3) { 84 //Send error to myself. If this happens too many times, I'll increase 85 //the amount of allowed notes 86 mail ('alindeman@php.net,didou@php.net,danbrown@php.net', 87 '[php-notes] Quota exceeded', 88 'Too many notes submitted in one minute. Consider increasing quota' . "\n" . 89 'Occured at '.date ('M d, Y g:i:s A') . "\n" . 90 "User : $user\n" . 91 "Section: $sect\n" . 92 "Note : $note", 93 'From: php-webmaster@lists.php.net', 94 '-fnoreply@php.net' 95 ); 96 die ('[TOO MANY NOTES]'); 97} 98 99$sect = trim(preg_replace('/\.php$/','',$sect)); 100 101//na = not approved. Don't display notes until they are approved by an editor 102//This has been reverted until it has been discussed further. 103 104$query = "INSERT INTO note (user, note, sect, ts, status) VALUES (?, ?, ?,NOW(), NULL)"; 105if (db_query_safe($query, [$user, $note, $sect])) { 106 $new_id = mysql_insert_id(); 107 $msg = $note; 108 109 $msg .= "\n----\n"; 110 $msg .= "Server IP: {$_SERVER['REMOTE_ADDR']}"; 111 if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) || isset($_SERVER['HTTP_VIA'])) { 112 $msg .= " (proxied:"; 113 if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { 114 $msg .= " " . hsc($_SERVER['HTTP_X_FORWARDED_FOR']); 115 } 116 if (isset($_SERVER['HTTP_VIA'])) { 117 $msg .= " " . hsc($_SERVER['HTTP_VIA']); 118 } 119 $msg .= ")"; 120 } 121 $msg .= "\nProbable Submitter: {$ip}" . ($redirip ? ' (proxied: '.htmlspecialchars($redirip).')' : ''); 122 123 $msg .= "\n----\n"; 124// $msg .= $spam_data; 125// $msg .= "\n----\n"; 126 127 $msg .= "Manual Page -- http://php.net/manual/en/$sect.php\n"; 128 $msg .= "Edit -- https://master.php.net/note/edit/$new_id\n"; 129 //$msg .= "Approve -- https://master.php.net/manage/user-notes.php?action=approve+$new_id&report=yes\n"; 130 foreach ($note_del_reasons AS $reason) { 131 $msg .= "Del: " 132 . str_pad($reason, $note_del_reasons_pad) 133 . "-- https://master.php.net/note/delete/$new_id/" . urlencode($reason) ."\n"; 134 } 135 136 // @phan-suppress-next-line PhanParamSuspiciousOrder - weird global padding count, but ok 137 $msg .= str_pad('Del: other reasons', $note_del_reasons_pad) . "-- https://master.php.net/note/delete/$new_id\n"; 138 $msg .= "Reject -- https://master.php.net/note/reject/$new_id\n"; 139 $msg .= "Search -- https://master.php.net/manage/user-notes.php\n"; 140 # make sure we have a return address. 141 if (!$user) $user = "php-general@lists.php.net"; 142 # strip spaces in email address, or will get a bad To: field 143 $user = str_replace(' ','',$user); 144 mail($mailto,"note $new_id added to $sect",$msg,"From: $user\r\nMessage-ID: <note-$new_id@php.net>", "-fnoreply@php.net"); 145} else { 146 // mail it. 147 mail($failto, 148 'failed manual note query', 149 "Query Failed: $query\nError: ".mysql_error(), 150 'From: php-webmaster@lists.php.net', 151 "-fnoreply@php.net"); 152 die("failed to insert record"); 153} 154 155 156 157 158 159//var_dump(is_spammer('127.0.0.1')); // false 160//var_dump(is_spammer('127.0.0.2')); // true 161 162?> 163