/** * antispam_create(-) * * Insert a new abuse string into DB */ function antispam_create($abuse_string, $aspm_source = 'local') { global $DB; // Cut the crap if the string is empty: $abuse_string = trim($abuse_string); if (empty($abuse_string)) { return false; } // Check if the string already is in the blacklist: if (antispam_check($abuse_string)) { return false; } // Insert new string into DB: $sql = "INSERT INTO T_antispam( aspm_string, aspm_source )\r\n\t\t\t\t\tVALUES( '" . $DB->escape($abuse_string) . "', '{$aspm_source}' )"; $DB->query($sql); return true; }
/** * Create a new Comment and return an XML-RPC response * * @param array of params * - Item (object) * - User (object) Can be NULL for anonymous comments * - password (string) * - username (string) * - comment_parent (int) * - content (string) * - author (string) * - author_url (string) * - author_email (string) * @return xmlrpcmsg */ function xmlrpcs_new_comment($params = array(), &$commented_Item) { global $DB, $Plugins, $Messages, $Hit, $localtimenow, $require_name_email, $minimum_comment_interval; $params = array_merge(array('password' => '', 'username' => '', 'content' => '', 'comment_parent' => 0, 'author' => '', 'author_url' => '', 'author_email' => ''), $params); $comment = $params['content'] = trim($params['content']); if (!$commented_Item->can_comment(NULL)) { return xmlrpcs_resperror(5, T_('You cannot leave comments on this post!')); } $commented_Item->load_Blog(); // Make sure Blog is loaded (will be needed whether logged in or not) if (empty($params['username']) && empty($params['password'])) { // Anonymous comment // NO permission to edit! $perm_comment_edit = false; $User = NULL; $author = trim($params['author']); $email = trim($params['author_email']); if ($commented_Item->Blog->get_setting('allow_anon_url')) { $url = trim($params['author_url']); } else { $url = NULL; } // we need some id info from the anonymous user: if ($require_name_email) { // We want Name and EMail with comments if (empty($author)) { return xmlrpcs_resperror(5, T_('Please fill in your name.')); } if (empty($email)) { return xmlrpcs_resperror(5, T_('Please fill in your email.')); } } if (!empty($author) && antispam_check($author)) { return xmlrpcs_resperror(5, T_('Supplied name is invalid.')); } if (!empty($email) && (!is_email($email) || antispam_check($email))) { return xmlrpcs_resperror(5, T_('Supplied email address is invalid.')); } if (!stristr($url, '://') && !stristr($url, '@')) { // add 'http://' if no protocol defined for URL; but not if the user seems to be entering an email address alone $url = 'http://' . $url; } if (strlen($url) <= 8) { // ex: https:// is 8 chars $url = ''; } // Note: as part of the validation we require the url to be absolute; otherwise we cannot detect bozos typing in // a title for their comment or whatever... if ($error = validate_url($url, 'commenting')) { return xmlrpcs_resperror(5, T_('Supplied website address is invalid: ') . $error); } } else { $User =& $params['User']; $perm_comment_edit = $User->check_perm('blog_comment!published', 'edit', false, $commented_Item->Blog->ID); $author = $User->ID; $url = $User->url; $email = $User->email; } // Following call says "WARNING: this does *NOT* (necessarilly) make the HTML code safe.": $comment = check_html_sanity($comment, $perm_comment_edit ? 'posting' : 'commenting', $User); if ($comment === false) { // ERROR! Restore original comment for further editing: $comment = $params['content']; } if (empty($comment)) { // comment should not be empty! return xmlrpcs_resperror(5, T_('Please do not send empty comments.')); } $now = date2mysql($localtimenow); /* * Flood-protection * NOTE: devs can override the flood protection delay in /conf/_overrides_TEST.php * TODO: Put time check into query? * TODO: move that as far !!UP!! as possible! We want to waste minimum resources on Floods * TODO: have several thresholds. For example: * 1 comment max every 30 sec + 5 comments max every 10 minutes + 15 comments max every 24 hours * TODO: factorize with trackback */ $query = 'SELECT MAX(comment_date) FROM T_comments WHERE comment_author_IP = ' . $DB->quote($Hit->IP) . ' OR comment_author_email = ' . $DB->quote($email); $ok = 1; if ($then = $DB->get_var($query)) { $time_lastcomment = mysql2date("U", $then); $time_newcomment = mysql2date("U", $now); if ($time_newcomment - $time_lastcomment < $minimum_comment_interval) { $ok = 0; } } if (!$ok) { return xmlrpcs_resperror(5, sprintf(T_('You can only post a new comment every %d seconds.'), $minimum_comment_interval)); } /* end flood-protection */ /** * Create comment object. Gets validated, before recording it into DB: */ $Comment = new Comment(); $Comment->set('type', 'comment'); $Comment->set_Item($commented_Item); if ($User) { // User is logged in, we'll use his ID $Comment->set_author_User($User); } else { // User is not logged in: $Comment->set('author', $author); $Comment->set('author_email', $email); $Comment->set('author_url', $url); } if (!empty($params['comment_parent'])) { $Comment->set('in_reply_to_cmt_ID', intval($params['comment_parent'])); } $Comment->set('author_IP', $Hit->IP); $Comment->set('date', $now); $Comment->set('content', $comment); if ($perm_comment_edit) { // User has perm to moderate comments, publish automatically: $Comment->set('status', 'published'); } else { // Assign default status for new comments: $Comment->set('status', $commented_Item->Blog->get_setting('new_feedback_status')); } $action = 'submit_comment_post_' . $commented_Item->ID; // Trigger event: a Plugin could add a $category="error" message here.. $Plugins->trigger_event('BeforeCommentFormInsert', array('Comment' => &$Comment, 'original_comment' => $params['content'], 'is_preview' => false, 'action' => &$action)); if ($Messages->has_errors()) { return xmlrpcs_resperror(5, $Messages->get_string('Cannot create comment, please correct these errors:' . "\n", '', " // \n", 'xmlrpc')); } $Comment->dbinsert(); if ($Comment->ID) { // comment has not been deleted // Trigger event: a Plugin should cleanup any temporary data here.. $Plugins->trigger_event('AfterCommentFormInsert', array('Comment' => &$Comment, 'original_comment' => $params['content'])); /* * -------------------------- * New comment notifications: * -------------------------- */ // TODO: dh> this should only send published feedback probably and should also use "outbound_notifications_mode" // fp> yes for general users, but comment moderators need to receive notifications for new unpublished comments // asimo> this handle moderators and general users as well and use "outbound_notifications_mode" in case of general users // Moderators will get emails about every new comment // Subscribed user will only get emails about new published comments $executed_by_userid = empty($User) ? NULL : $User->ID; $Comment->handle_notifications(true, $executed_by_userid); } else { return xmlrpcs_resperror(99, 'Error while inserting comment: ' . $DB->last_error); } return new xmlrpcresp(new xmlrpcval($Comment->ID, 'int')); }
/** * Add a file to the system using the configured storage method * * @param integer $p_bug_id The bug id (should be 0 when adding project doc). * @param array $p_file The uploaded file info, as retrieved from gpc_get_file(). * @param string $p_table Either 'bug' or 'project' depending on attachment type. * @param string $p_title File title. * @param string $p_desc File description. * @param integer $p_user_id User id (defaults to current user). * @param integer $p_date_added Date added. * @param boolean $p_skip_bug_update Skip bug last modification update (useful when importing bug attachments). * @return void */ function file_add($p_bug_id, array $p_file, $p_table = 'bug', $p_title = '', $p_desc = '', $p_user_id = null, $p_date_added = 0, $p_skip_bug_update = false) { file_ensure_uploaded($p_file); $t_file_name = $p_file['name']; $t_tmp_file = $p_file['tmp_name']; if (!file_type_check($t_file_name)) { trigger_error(ERROR_FILE_NOT_ALLOWED, ERROR); } $t_org_filename = $t_file_name; $t_suffix_id = 1; while (!file_is_name_unique($t_file_name, $p_bug_id)) { $t_suffix_id++; $t_dot_index = strripos($t_org_filename, '.'); if ($t_dot_index === false) { $t_file_name = $t_org_filename . '-' . $t_suffix_id; } else { $t_extension = substr($t_org_filename, $t_dot_index, strlen($t_org_filename) - $t_dot_index); $t_file_name = substr($t_org_filename, 0, $t_dot_index) . '-' . $t_suffix_id . $t_extension; } } antispam_check(); $t_file_size = filesize($t_tmp_file); if (0 == $t_file_size) { trigger_error(ERROR_FILE_NO_UPLOAD_FAILURE, ERROR); } $t_max_file_size = (int) min(ini_get_number('upload_max_filesize'), ini_get_number('post_max_size'), config_get('max_file_size')); if ($t_file_size > $t_max_file_size) { trigger_error(ERROR_FILE_TOO_BIG, ERROR); } if ('bug' == $p_table) { $t_project_id = bug_get_field($p_bug_id, 'project_id'); $t_id = (int) $p_bug_id; } else { $t_project_id = helper_get_current_project(); $t_id = $t_project_id; } if ($p_user_id === null) { $p_user_id = auth_get_current_user_id(); } if ($p_date_added <= 0) { $p_date_added = db_now(); } if ($t_project_id == ALL_PROJECTS) { $t_file_path = config_get('absolute_path_default_upload_folder'); } else { $t_file_path = project_get_field($t_project_id, 'file_path'); if (is_blank($t_file_path)) { $t_file_path = config_get('absolute_path_default_upload_folder'); } } $t_unique_name = file_generate_unique_name($t_file_path); $t_method = config_get('file_upload_method'); switch ($t_method) { case DISK: file_ensure_valid_upload_path($t_file_path); $t_disk_file_name = $t_file_path . $t_unique_name; if (!file_exists($t_disk_file_name)) { if (!move_uploaded_file($t_tmp_file, $t_disk_file_name)) { trigger_error(ERROR_FILE_MOVE_FAILED, ERROR); } chmod($t_disk_file_name, config_get('attachments_file_permissions')); $c_content = ''; } else { trigger_error(ERROR_FILE_DUPLICATE, ERROR); } break; case DATABASE: $c_content = db_prepare_binary_string(fread(fopen($t_tmp_file, 'rb'), $t_file_size)); $t_file_path = ''; break; default: trigger_error(ERROR_GENERIC, ERROR); } $t_file_table = db_get_table($p_table . '_file'); $t_id_col = $p_table . '_id'; $t_param = array($t_id_col => $t_id, 'title' => $p_title, 'description' => $p_desc, 'diskfile' => $t_unique_name, 'filename' => $t_file_name, 'folder' => $t_file_path, 'filesize' => $t_file_size, 'file_type' => $p_file['type'], 'date_added' => $p_date_added, 'user_id' => (int) $p_user_id); # Oracle has to update BLOBs separately if (!db_is_oracle()) { $t_param['content'] = $c_content; } $t_query_param = db_param(); for ($i = 1; $i < count($t_param); $i++) { $t_query_param .= ', ' . db_param(); } $t_query = 'INSERT INTO ' . $t_file_table . ' ( ' . implode(', ', array_keys($t_param)) . ' ) VALUES ( ' . $t_query_param . ' )'; db_query($t_query, array_values($t_param)); if (db_is_oracle()) { db_update_blob($t_file_table, 'content', $c_content, "diskfile='{$t_unique_name}'"); } if ('bug' == $p_table) { # update the last_updated date if (!$p_skip_bug_update) { bug_update_date($p_bug_id); } # log file added to bug history history_log_event_special($p_bug_id, FILE_ADDED, $t_file_name); } }
debug_die('Invalid recipient or no permission to contact by email!'); } } elseif (empty($Comment->allow_msgform)) { // should be prevented by UI debug_die('Invalid recipient or no permission to contact by email!'); } else { $recipient_name = $Comment->get_author_name(); $recipient_address = $Comment->get_author_email(); } } if (empty($sender_name)) { $Messages->add(T_('Please fill in your name.'), 'error'); } if (empty($sender_address)) { $Messages->add(T_('Please fill in your email.'), 'error'); } elseif (!is_email($sender_address) || antispam_check($sender_address)) { $Messages->add(T_('Supplied email address is invalid.'), 'error'); } if (empty($recipient_User) && empty($recipient_address)) { // should be prevented by UI debug_die('No recipient specified!'); } // opt-out links: if ($recipient_User) { // Member: // Change the locale so the email is in the recipients language locale_temp_switch($recipient_User->locale); } else { // Visitor: // We don't know the recipient's language - Change the locale so the email is in the blog's language: locale_temp_switch($Blog->locale);
?> </td> </tr> <?php $count++; } ?> </table> <?php } } else { // There is no affected users printf('<p>' . T_('No <strong>users</strong> match the keyword [%s]') . '</p>', $keyword); } // Check if the string is already in the blacklist: if (antispam_check($keyword)) { // Already there: printf('<p>' . T_('The keyword [%s] is <strong>already handled</strong> by the blacklist.') . '</p>', htmlspecialchars($keyword)); } else { // Not in blacklist ?> <p> <input type="checkbox" name="blacklist_locally" id="blacklist_locally_cb" value="1" checked="checked" /> <label for="blacklist_locally_cb"> <?php printf(T_('<strong>Blacklist</strong> the keyword [%s] locally.'), htmlspecialchars($keyword)); ?> </label> </p> <?php
// NO permission to edit! $perm_comment_edit = false; // we need some id info from the anonymous user: if ($require_name_email) { // We want Name and EMail with comments if (empty($author)) { $Messages->add(T_('Please fill in your name.'), 'error'); } if (empty($email)) { $Messages->add(T_('Please fill in your email.'), 'error'); } } if (!empty($author) && antispam_check($author)) { $Messages->add(T_('Supplied name is invalid.'), 'error'); } if (!empty($email) && (!is_email($email) || antispam_check($email))) { $Messages->add(T_('Supplied email address is invalid.'), 'error'); } if (!stristr($url, '://') && !stristr($url, '@')) { // add 'http://' if no protocol defined for URL; but not if the user seems to be entering an email address alone $url = 'http://' . $url; } if (strlen($url) <= 8) { // ex: https:// is 8 chars $url = ''; } // Note: as part of the validation we require the url to be absolute; otherwise we cannot detect bozos typing in // a title for their comment or whatever... if ($error = validate_url($url, 'commenting')) { $Messages->add(T_('Supplied website address is invalid: ') . $error, 'error'); }
/** * Insert a new bug into the database * @return integer integer representing the bug identifier that was created * @access public * @uses database_api.php * @uses lang_api.php */ function create() { self::validate(true); antispam_check(); # check due_date format if (is_blank($this->due_date)) { $this->due_date = date_get_null(); } # check date submitted and last modified if (is_blank($this->date_submitted)) { $this->date_submitted = db_now(); } if (is_blank($this->last_updated)) { $this->last_updated = db_now(); } # Insert text information $t_query = 'INSERT INTO {bug_text} ( description, steps_to_reproduce, additional_information ) VALUES ( ' . db_param() . ',' . db_param() . ',' . db_param() . ')'; db_query($t_query, array($this->description, $this->steps_to_reproduce, $this->additional_information)); # Get the id of the text information we just inserted # NOTE: this is guaranteed to be the correct one. # The value LAST_INSERT_ID is stored on a per connection basis. $t_text_id = db_insert_id(db_get_table('bug_text')); # check to see if we want to assign this right off $t_starting_status = config_get('bug_submit_status'); $t_original_status = $this->status; # if not assigned, check if it should auto-assigned. if (0 == $this->handler_id) { # if a default user is associated with the category and we know at this point # that that the bug was not assigned to somebody, then assign it automatically. $t_query = 'SELECT user_id FROM {category} WHERE id=' . db_param(); $t_result = db_query($t_query, array($this->category_id)); $t_handler = db_result($t_result); if ($t_handler !== false) { $this->handler_id = $t_handler; } } # Check if bug was pre-assigned or auto-assigned. if ($this->handler_id != 0 && $this->status == $t_starting_status && ON == config_get('auto_set_status_to_assigned')) { $t_status = config_get('bug_assigned_status'); } else { $t_status = $this->status; } # Insert the rest of the data $t_query = 'INSERT INTO {bug} ( project_id,reporter_id, handler_id,duplicate_id, priority,severity, reproducibility,status, resolution,projection, category_id,date_submitted, last_updated,eta, bug_text_id, os, os_build,platform, version,build, profile_id, summary, view_state, sponsorship_total, sticky, fixed_in_version, target_version, due_date ) VALUES ( ' . db_param() . ',' . db_param() . ',' . db_param() . ',' . db_param() . ', ' . db_param() . ',' . db_param() . ',' . db_param() . ',' . db_param() . ', ' . db_param() . ',' . db_param() . ',' . db_param() . ',' . db_param() . ', ' . db_param() . ',' . db_param() . ',' . db_param() . ',' . db_param() . ', ' . db_param() . ',' . db_param() . ',' . db_param() . ',' . db_param() . ', ' . db_param() . ',' . db_param() . ',' . db_param() . ',' . db_param() . ', ' . db_param() . ',' . db_param() . ',' . db_param() . ',' . db_param() . ')'; db_query($t_query, array($this->project_id, $this->reporter_id, $this->handler_id, $this->duplicate_id, $this->priority, $this->severity, $this->reproducibility, $t_status, $this->resolution, $this->projection, $this->category_id, $this->date_submitted, $this->last_updated, $this->eta, $t_text_id, $this->os, $this->os_build, $this->platform, $this->version, $this->build, $this->profile_id, $this->summary, $this->view_state, $this->sponsorship_total, $this->sticky, $this->fixed_in_version, $this->target_version, $this->due_date)); $this->id = db_insert_id(db_get_table('bug')); # log new bug history_log_event_special($this->id, NEW_BUG); # log changes, if any (compare happens in history_log_event_direct) history_log_event_direct($this->id, 'status', $t_original_status, $t_status); history_log_event_direct($this->id, 'handler_id', 0, $this->handler_id); return $this->id; }
/** * Add a bugnote to a bug * return the ID of the new bugnote * @param integer $p_bug_id A bug identifier. * @param string $p_bugnote_text The bugnote text to add. * @param string $p_time_tracking Time tracking value - hh:mm string. * @param boolean $p_private Whether bugnote is private. * @param integer $p_type The bugnote type. * @param string $p_attr Bugnote Attribute. * @param integer $p_user_id A user identifier. * @param boolean $p_send_email Whether to generate email. * @param integer $p_date_submitted Date submitted (defaults to now()). * @param integer $p_last_modified Last modification date (defaults to now()). * @param boolean $p_skip_bug_update Skip bug last modification update (useful when importing bugs/bugnotes). * @param boolean $p_log_history Log changes to bugnote history (defaults to true). * @return boolean|integer false or indicating bugnote id added * @access public */ function bugnote_add($p_bug_id, $p_bugnote_text, $p_time_tracking = '0:00', $p_private = false, $p_type = BUGNOTE, $p_attr = '', $p_user_id = null, $p_send_email = true, $p_date_submitted = 0, $p_last_modified = 0, $p_skip_bug_update = false, $p_log_history = true) { $c_bug_id = (int) $p_bug_id; $c_time_tracking = helper_duration_to_minutes($p_time_tracking); $c_type = (int) $p_type; $c_date_submitted = $p_date_submitted <= 0 ? db_now() : (int) $p_date_submitted; $c_last_modified = $p_last_modified <= 0 ? db_now() : (int) $p_last_modified; antispam_check(); if (REMINDER !== $p_type) { # Check if this is a time-tracking note $t_time_tracking_enabled = config_get('time_tracking_enabled'); if (ON == $t_time_tracking_enabled && $c_time_tracking > 0) { $t_time_tracking_without_note = config_get('time_tracking_without_note'); if (is_blank($p_bugnote_text) && OFF == $t_time_tracking_without_note) { error_parameters(lang_get('bugnote')); trigger_error(ERROR_EMPTY_FIELD, ERROR); } $c_type = TIME_TRACKING; } else { if (is_blank($p_bugnote_text)) { # This is not time tracking (i.e. it's a normal bugnote) # @todo should we not trigger an error in this case ? return false; } } } # Event integration $t_bugnote_text = event_signal('EVENT_BUGNOTE_DATA', $p_bugnote_text, $c_bug_id); # insert bugnote text $t_query = 'INSERT INTO {bugnote_text} ( note ) VALUES ( ' . db_param() . ' )'; db_query($t_query, array($t_bugnote_text)); # retrieve bugnote text id number $t_bugnote_text_id = db_insert_id(db_get_table('bugnote_text')); # get user information if ($p_user_id === null) { $p_user_id = auth_get_current_user_id(); } # Check for private bugnotes. if ($p_private && access_has_bug_level(config_get('set_view_status_threshold'), $p_bug_id, $p_user_id)) { $t_view_state = VS_PRIVATE; } else { $t_view_state = VS_PUBLIC; } # insert bugnote info $t_query = 'INSERT INTO {bugnote} (bug_id, reporter_id, bugnote_text_id, view_state, date_submitted, last_modified, note_type, note_attr, time_tracking) VALUES (' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ' )'; $t_params = array($c_bug_id, $p_user_id, $t_bugnote_text_id, $t_view_state, $c_date_submitted, $c_last_modified, $c_type, $p_attr, $c_time_tracking); db_query($t_query, $t_params); # get bugnote id $t_bugnote_id = db_insert_id(db_get_table('bugnote')); # update bug last updated if (!$p_skip_bug_update) { bug_update_date($p_bug_id); } # log new bug if (true == $p_log_history) { history_log_event_special($p_bug_id, BUGNOTE_ADDED, bugnote_format_id($t_bugnote_id)); } # Event integration event_signal('EVENT_BUGNOTE_ADD', array($p_bug_id, $t_bugnote_id)); # only send email if the text is not blank, otherwise, it is just recording of time without a comment. if (true == $p_send_email && !is_blank($t_bugnote_text)) { email_bugnote_add($p_bug_id); } return $t_bugnote_id; }
/** * Check raw HTML input for different levels of sanity including: * - XHTML validation * - Javascript injection * - antispam * * Also cleans up the content on some levels: * - trimming * - balancing tags * * WARNING: this does *NOT* (necessarilly) make the HTML code safe. * It only checks on it and produces error messages. * It is NOT (necessarily) safe to use the output. * * @param string The content to format * @param string * @param integer Create automated <br /> tags? * @param string Encoding (used for SafeHtmlChecker() only!); defaults to $io_charset * @return boolean|string */ function check_html_sanity($content, $context = 'posting', $autobr = false, $encoding = NULL) { global $use_balanceTags, $admin_url; global $io_charset, $use_xhtmlvalidation_for_comments, $comment_allowed_tags, $comments_allow_css_tweaks; global $Messages; /** * @var User */ global $current_User; switch ($context) { case 'posting': case 'xmlrpc_posting': $Group =& $current_User->get_Group(); if ($context == 'posting') { $xhtmlvalidation = $Group->perm_xhtmlvalidation == 'always'; } else { $xhtmlvalidation = $Group->perm_xhtmlvalidation_xmlrpc == 'always'; } $allow_css_tweaks = $Group->perm_xhtml_css_tweaks; $allow_javascript = $Group->perm_xhtml_javascript; $allow_iframes = $Group->perm_xhtml_iframes; $allow_objects = $Group->perm_xhtml_objects; $bypass_antispam = $Group->perm_bypass_antispam; break; case 'commenting': $xhtmlvalidation = $use_xhtmlvalidation_for_comments; $allow_css_tweaks = $comments_allow_css_tweaks; $allow_javascript = false; $allow_iframes = false; $allow_objects = false; // fp> I don't know if it makes sense to bypass antispam in commenting context if the user has that kind of permissions. // If so, then we also need to bypass in several other places. $bypass_antispam = false; break; default: debug_die('unknown context: ' . $context); } $error = false; // Replace any & that is not a character or entity reference with & $content = preg_replace('/&(?!#[0-9]+;|#x[0-9a-fA-F]+;|[a-zA-Z_:][a-zA-Z0-9._:-]*;)/', '&', $content); // ANTISPAM check: if (!$bypass_antispam && ($block = antispam_check($content))) { if ($context == 'xmlrpc_posting') { $errmsg = $context == 'commenting' ? T_('Illegal content found (spam?)') : sprintf(T_('Illegal content found: blacklisted word "%s"'), $block); } else { $errmsg = $context == 'commenting' ? T_('Illegal content found (spam?)') : sprintf(T_('Illegal content found: blacklisted word «%s»'), htmlspecialchars($block)); } $Messages->add($errmsg, 'error'); $error = true; } if ($autobr) { // Auto <br />: // may put brs in the middle of multiline tags... // TODO: this may create "<br />" tags in "<UL>" (outside of <LI>) and make the HTML invalid! -> use autoP pugin? $content = autobrize($content); } $content = trim($content); if ($use_balanceTags) { // Auto close open tags: $content = balance_tags($content); } if ($xhtmlvalidation) { // We want to validate XHTML: load_class('xhtml_validator/_xhtml_validator.class.php'); $XHTML_Validator =& new XHTML_Validator($context, $allow_css_tweaks, $allow_iframes, $allow_javascript, $allow_objects, $encoding); if (!$XHTML_Validator->check($content)) { $error = true; } } else { // We do not WANT to validate XHTML, fall back to basic security checking: // This is only as strong as its regexps can parse xhtml. This is significantly inferior to the XHTML checker above. // The only advantage of this checker is that it can check for a little security without requiring VALID XHTML. if ($context == 'commenting') { // DEPRECATED but still... // echo 'allowed tags:',htmlspecialchars($comment_allowed_tags); $content = strip_tags($content, $comment_allowed_tags); } // Security checking: $check = $content; // Open comments or '<![CDATA[' are dangerous $check = str_replace('<!', '<', $check); // # # are delimiters // i modifier at the end means caseless // CHECK Styling restictions: if (!$allow_css_tweaks && preg_match('#\\s((style|class|id)\\s*=)#i', $check, $matches)) { $Messages->add(T_('Illegal CSS markup found: ') . htmlspecialchars($matches[1]), 'error'); $error = true; } // CHECK JAVASCRIPT: if (!$allow_javascript && (preg_match('¤( < \\s* //? \\s* (script|noscript) )¤xi', $check, $matches) || preg_match('#\\s((on[a-z]+)\\s*=)#i', $check, $matches) || preg_match('#=["\'\\s]*((javascript|vbscript|about):)#i', $check, $matches))) { $Messages->add(T_('Illegal javascript markup found: ') . htmlspecialchars($matches[1]), 'error'); $error = true; } // CHECK IFRAMES: if (!$allow_iframes && preg_match('¤( < \\s* //? \\s* (frame|iframe) )¤xi', $check, $matches)) { $Messages->add(T_('Illegal frame markup found: ') . htmlspecialchars($matches[1]), 'error'); $error = true; } // CHECK OBJECTS: if (!$allow_objects && preg_match('¤( < \\s* //? \\s* (applet|object|param|embed) )¤xi', $check, $matches)) { $Messages->add(T_('Illegal object markup found: ') . htmlspecialchars($matches[1]), 'error'); $error = true; } } if ($error) { if (!empty($current_User) && !empty($Group) && $current_User->check_perm('users', 'edit', false)) { $Messages->add(sprintf(T_('(Note: To get rid of the above validation warnings, you can deactivate unwanted validation rules in your <a %s>Group settings</a>.)'), 'href="' . $admin_url . '?ctrl=users&grp_ID=' . $Group->ID . '"'), 'error'); } return false; } // Return sanitized content return $content; }
/** * Attach a tag to a bug. * @param integer $p_tag_id The tag ID to attach. * @param integer $p_bug_id The bug ID to attach. * @param integer $p_user_id The user ID to attach. * @return boolean */ function tag_bug_attach($p_tag_id, $p_bug_id, $p_user_id = null) { antispam_check(); access_ensure_bug_level(config_get('tag_attach_threshold'), $p_bug_id, $p_user_id); tag_ensure_exists($p_tag_id); if (tag_bug_is_attached($p_tag_id, $p_bug_id)) { trigger_error(TAG_ALREADY_ATTACHED, ERROR); } if (null == $p_user_id) { $p_user_id = auth_get_current_user_id(); } else { user_ensure_exists($p_user_id); } $t_query = 'INSERT INTO {bug_tag} ( tag_id, bug_id, user_id, date_attached ) VALUES ( ' . db_param() . ',' . db_param() . ',' . db_param() . ',' . db_param() . ')'; db_query($t_query, array($p_tag_id, $p_bug_id, $p_user_id, db_now())); $t_tag_name = tag_get_field($p_tag_id, 'name'); history_log_event_special($p_bug_id, TAG_ATTACHED, $t_tag_name); # updated the last_updated date bug_update_date($p_bug_id); return true; }
/** * Check the validity of a given URL * * Checks allowed URI schemes and URL ban list. * URL can be empty. * * Note: We have a problem when trying to "antispam" a keyword which is already blacklisted * If that keyword appears in the URL... then the next page has a bad referer! :/ * * {@internal This function gets tested in misc.funcs.simpletest.php.}} * * @param string Url to validate * @param string Context ("posting", "commenting", "download_src", "http-https") * @param boolean also do an antispam check on the url * @return mixed false (which means OK) or error message */ function validate_url($url, $context = 'posting', $antispam_check = true) { global $Debuglog, $debug; if (empty($url)) { // Empty URL, no problem return false; } // Do not give verbose info for comments, unless debug is enabled. $verbose = $debug || $context != 'commenting'; $allowed_uri_schemes = get_allowed_uri_schemes($context); // Validate URL structure if ($url[0] == '$') { // This is a 'special replace code' URL (used in footers) if (!preg_match('~\\$([a-z_]+)\\$~', $url)) { return T_('Invalid URL $code$ format'); } } elseif (preg_match('~^\\w+:~', $url)) { // there's a scheme and therefor an absolute URL: if (substr($url, 0, 7) == 'mailto:') { // mailto:link if (!in_array('mailto', $allowed_uri_schemes)) { // Scheme not allowed $scheme = 'mailto:'; $Debuglog->add('URI scheme «' . $scheme . '» not allowed!', 'error'); return $verbose ? sprintf(T_('URI scheme "%s" not allowed.'), htmlspecialchars($scheme)) : T_('URI scheme not allowed.'); } preg_match('~^(mailto):(.*?)(\\?.*)?$~', $url, $match); if (!$match) { return $verbose ? sprintf(T_('Invalid email link: %s.'), htmlspecialchars($url)) : T_('Invalid email link.'); } elseif (!is_email($match[2])) { return $verbose ? sprintf(T_('Supplied email address (%s) is invalid.'), htmlspecialchars($match[2])) : T_('Invalid email address.'); } } elseif (substr($url, 0, 6) == 'clsid:') { // clsid:link if (!in_array('clsid', $allowed_uri_schemes)) { // Scheme not allowed $scheme = 'clsid:'; $Debuglog->add('URI scheme «' . $scheme . '» not allowed!', 'error'); return $verbose ? sprintf(T_('URI scheme "%s" not allowed.'), htmlspecialchars($scheme)) : T_('URI scheme not allowed.'); } if (!preg_match('~^(clsid):([a-fA-F0-9\\-]+)$~', $url, $match)) { return T_('Invalid class ID format'); } } elseif (substr($url, 0, 11) == 'javascript:') { // javascript: // Basically there could be anything here if (!in_array('javascript', $allowed_uri_schemes)) { // Scheme not allowed $scheme = 'javascript:'; $Debuglog->add('URI scheme «' . $scheme . '» not allowed!', 'error'); return $verbose ? sprintf(T_('URI scheme "%s" not allowed.'), htmlspecialchars($scheme)) : T_('URI scheme not allowed.'); } preg_match('~^(javascript):~', $url, $match); } else { // convert URL to IDN: $url = idna_encode($url); if (!preg_match('~^ # start ([a-z][a-z0-9+.\\-]*) # scheme :// # authorize absolute URLs only ( // not present in clsid: -- problem? ; mailto: handled above) (\\w+(:\\w+)?@)? # username or username and password (optional) ( localhost | [a-z0-9]([a-z0-9\\-])* # Don t allow anything too funky like entities \\. # require at least 1 dot [a-z0-9]([a-z0-9.\\-])+ # Don t allow anything too funky like entities ) (:[0-9]+)? # optional port specification .* # allow anything in the path (including spaces - used in FileManager - but no newlines). $~ix', $url, $match)) { // Cannot validate URL structure $Debuglog->add('URL «' . $url . '» does not match url pattern!', 'error'); return $verbose ? sprintf(T_('Invalid URL format (%s).'), htmlspecialchars($url)) : T_('Invalid URL format.'); } $scheme = strtolower($match[1]); if (!in_array($scheme, $allowed_uri_schemes)) { // Scheme not allowed $Debuglog->add('URI scheme «' . $scheme . '» not allowed!', 'error'); return $verbose ? sprintf(T_('URI scheme "%s" not allowed.'), htmlspecialchars($scheme)) : T_('URI scheme not allowed.'); } } } else { // URL is relative.. if ($context == 'commenting' || $context == 'download_src' || $context == 'http-https') { // We do not allow relative URLs in comments and download urls return $verbose ? sprintf(T_('URL "%s" must be absolute.'), htmlspecialchars($url)) : T_('URL must be absolute.'); } $char = substr($url, 0, 1); if ($char != '/' && $char != '#') { // must start with a slash or hash (for HTML anchors to the same page) return $verbose ? sprintf(T_('URL "%s" must be a full path starting with "/" or an anchor starting with "#".'), htmlspecialchars($url)) : T_('URL must be a full path starting with "/" or an anchor starting with "#".'); } } if ($antispam_check) { // Search for blocked keywords: if ($block = antispam_check($url)) { return $verbose ? sprintf(T_('URL "%s" not allowed: blacklisted word "%s".'), htmlspecialchars($url), $block) : T_('URL not allowed'); } } return false; // OK }
} elseif (empty($_POST["prenom"])) { $erreur .= "Voornaam ist obligatorisch."; $etat = "not"; } elseif (empty($_POST["pays"])) { $erreur .= "Land iist obligatorisch."; $etat = "not"; } elseif (empty($_POST["telephone"])) { $erreur .= "Telefoon ist obligatorisch."; $etat = "not"; } elseif (empty($_POST["email"])) { $erreur .= "E-mail ist obligatorisch."; $etat = "not"; } elseif (!$Utils->valid_email($_POST["email"])) { $erreur .= "E-mail ist ungultig."; $etat = "not"; } elseif (antispam_check() == false) { $erreur = "Anti-Spam ergebnis der berechnung ist falsch, bitte versuchen sie es erneut!"; $etat = "not"; } //Send mail if ($etat == "send") { $passage_ligne = "\r\n"; //=====Declaration des messages au format HTML $message_html = "\r\n\t\t<div style=\"padding-top:10px;padding-left:10px;color:#707070;font-size:12px;font-style:Verdana;\">\r\n\t\t\t\tDemande via le formulaire Commande<br/>\r\n\t\t\t\t\r\n\t\t\t\t<span style=\"font-weight:bolder;\">Résumé du formulaire:</span><br /><br />\r\n\t\t\t\t<span style=\"font-weight:bolder;\">Demande:</span><br /><br />" . $_POST["demande"] . " <br />" . "Adressé par : <br />" . $_POST["par"] . "<br />" . "Nom & Prénom: " . $_POST["nom"] . " " . $_POST["nom"] . "<br />" . "Etablissement: " . $_POST["etablissement"] . "<br />" . "TVA: " . $_POST["tva"] . "<br />" . "Adresse: " . $_POST["adresse"] . "<br />" . "Code Postal - Ville: " . $_POST["cpville"] . "<br />" . "Pays: " . $_POST["pays"] . "<br />" . "Téléphone: " . $_POST["telephone"] . "<br />" . "Portable: " . $_POST["portable"] . "<br />" . "Email: " . $_POST["email"] . "<br />" . "Fax: " . $_POST["fax"] . "<br />" . "Demande de contact par : " . $_POST["opinions"] . "<br />" . "Urgence de la demande: " . $_POST["urgence"] . "<br />" . "</div>"; //=====Creation de la boundary $boundary = "-----=" . md5(rand()); $boundary_alt = "-----=" . md5(rand()); //=====Definition du sujet $sujet = "Formulaire de contact | " . date("d/m/Y") . " " . date("H:i"); //========= //=====Creation du header de l'e-mail
// Core param validation if (empty($sender_name)) { $Messages->add(T_('Please fill in your name.'), 'error'); } if (empty($sender_address)) { $Messages->add(T_('Please fill in your email.'), 'error'); } elseif (!is_email($sender_address) || antispam_check($sender_address)) { $Messages->add(T_('Supplied email address is invalid.'), 'error'); } if (empty($subject)) { $Messages->add(T_('Please fill in the subject of your message.'), 'error'); } if (empty($message)) { // message should not be empty! $Messages->add(T_('Please do not send empty messages.'), 'error'); } elseif ($antispam_on_message_form && antispam_check($message)) { // a blacklisted keyword ha sbeen found in the message: $Messages->add(T_('The supplied message is invalid / appears to be spam.'), 'error'); } // Build message footer: $BlogCache =& get_Cache('BlogCache'); $message_footer = ''; if (!empty($comment_id)) { // Getting current blog info: $Blog =& $BlogCache->get_by_ID($blog); // Required $message_footer .= T_('Message sent from your comment:') . "\n" . url_add_param($Blog->get('url'), 'p=' . $post_id . '#' . $comment_id, '&') . "\n\n"; } elseif (!empty($post_id)) { // Getting current blog info: $Blog =& $BlogCache->get_by_ID($blog); // Required
/** * Check raw HTML input for different levels of sanity including: * - XHTML validation * - Javascript injection * - antispam * * Also cleans up the content on some levels: * - trimming * - balancing tags * * WARNING: this does *NOT* (necessarilly) make the HTML code safe. * It only checks on it and produces error messages. * It is NOT (necessarily) safe to use the output. * * @param string The content to format * @param string * @param User User (used for "posting" and "xmlrpc_posting" context). Default: $current_User * @param string Encoding (used for XHTML_Validator only!); defaults to $io_charset * @return boolean|string */ function check_html_sanity($content, $context = 'posting', $User = NULL, $encoding = NULL) { global $use_balanceTags, $admin_url; global $io_charset, $use_xhtmlvalidation_for_comments, $comment_allowed_tags, $comments_allow_css_tweaks; global $Messages; if (empty($User)) { /** * @var User */ global $current_User; $User = $current_User; } // Add error messages $verbose = true; switch ($context) { case 'posting': case 'xmlrpc_posting': $Group = $User->get_Group(); if ($context == 'posting') { $xhtmlvalidation = $Group->perm_xhtmlvalidation == 'always'; } else { $xhtmlvalidation = $Group->perm_xhtmlvalidation_xmlrpc == 'always'; } $allow_css_tweaks = $Group->perm_xhtml_css_tweaks; $allow_javascript = $Group->perm_xhtml_javascript; $allow_iframes = $Group->perm_xhtml_iframes; $allow_objects = $Group->perm_xhtml_objects; $bypass_antispam = $Group->perm_bypass_antispam; break; case 'commenting': $xhtmlvalidation = $use_xhtmlvalidation_for_comments; $allow_css_tweaks = $comments_allow_css_tweaks; $allow_javascript = false; $allow_iframes = false; $allow_objects = false; // fp> I don't know if it makes sense to bypass antispam in commenting context if the user has that kind of permissions. // If so, then we also need to bypass in several other places. $bypass_antispam = false; break; case 'general_array_params': $xhtmlvalidation = false; $allow_css_tweaks = true; $allow_javascript = false; $allow_iframes = false; $allow_objects = false; $bypass_antispam = false; // Do not add error messages in this context $verbose = false; break; case 'head_extension': $xhtmlvalidation = true; // We disable everything else, because the XMHTML validator will set explicit rules for the 'head_extension' context $allow_css_tweaks = false; $allow_javascript = false; $allow_iframes = false; $allow_objects = false; $bypass_antispam = false; // Do not add error messages in this context $verbose = false; break; default: debug_die('unknown context: ' . $context); } $error = false; // Replace any & that is not a character or entity reference with & $content = preg_replace('/&(?!#[0-9]+;|#x[0-9a-fA-F]+;|[a-zA-Z_:][a-zA-Z0-9._:-]*;)/', '&', $content); // ANTISPAM check: $error = !$bypass_antispam && ($block = antispam_check($content)); if ($error && $verbose) { // Add error message if ($context == 'xmlrpc_posting') { $errmsg = $context == 'commenting' ? T_('Illegal content found (spam?)') : sprintf(T_('Illegal content found: blacklisted word "%s".'), $block); } else { $errmsg = $context == 'commenting' ? T_('Illegal content found (spam?).') : sprintf(T_('Illegal content found: blacklisted word «%s».'), htmlspecialchars($block)); } $Messages->add($errmsg, 'error'); } $content = trim($content); if ($use_balanceTags && $context != 'general_array_params') { // Auto close open tags: // Auto close only if the content is NOT from a general array param where open and closed html tags may appear separately $content = balance_tags($content); } if ($xhtmlvalidation) { // We want to validate XHTML: load_class('xhtml_validator/_xhtml_validator.class.php', 'XHTML_Validator'); $XHTML_Validator = new XHTML_Validator($context, $allow_css_tweaks, $allow_iframes, $allow_javascript, $allow_objects, $encoding); if (!$XHTML_Validator->check($content)) { $error = true; } } else { // We do not WANT to validate XHTML, fall back to basic security checking: // This is only as strong as its regexps can parse xhtml. This is significantly inferior to the XHTML checker above. // The only advantage of this checker is that it can check for a little security without requiring VALID XHTML. if ($context == 'commenting') { // DEPRECATED but still... // echo 'allowed tags:',htmlspecialchars($comment_allowed_tags); $content = strip_tags($content, $comment_allowed_tags); } // Security checking: $check = $content; // Open comments or '<![CDATA[' are dangerous $check = str_replace('<!', '<', $check); // # # are delimiters // i modifier at the end means caseless // CHECK Styling restictions: $css_tweaks_error = !$allow_css_tweaks && preg_match('#\\s((style|class|id)\\s*=)#i', $check, $matches); if ($css_tweaks_error && $verbose) { $Messages->add(T_('Illegal CSS markup found: ') . htmlspecialchars($matches[1]), 'error'); } // CHECK JAVASCRIPT: $javascript_error = !$allow_javascript && (preg_match('~( < \\s* //? \\s* (script|noscript) )~xi', $check, $matches) || preg_match('#\\s((on[a-z]+)\\s*=)#i', $check, $matches) || preg_match('#=["\'\\s]*((javascript|vbscript|about):)#i', $check, $matches)); if ($javascript_error && $verbose) { $Messages->add(T_('Illegal javascript markup found: ') . htmlspecialchars($matches[1]), 'error'); } // CHECK IFRAMES: $iframe_error = !$allow_iframes && preg_match('~( < \\s* //? \\s* (frame|iframe) )~xi', $check, $matches); if ($iframe_error && $verbose) { $Messages->add(T_('Illegal frame markup found: ') . htmlspecialchars($matches[1]), 'error'); } // CHECK OBJECTS: $object_error = !$allow_objects && preg_match('~( < \\s* //? \\s* (applet|object|param|embed) )~xi', $check, $matches); if ($object_error && $verbose) { $Messages->add(T_('Illegal object markup found: ') . htmlspecialchars($matches[1]), 'error'); } // Set the final error value based on all of the results $error = $error || $css_tweaks_error || $javascript_error || $iframe_error || $object_error; } if ($error) { if ($verbose && !empty($User) && !empty($Group) && $User->check_perm('users', 'edit', false)) { $Messages->add(sprintf(T_('(Note: To get rid of the above validation warnings, you can deactivate unwanted validation rules in your <a %s>Group settings</a>.)'), 'href="' . $admin_url . '?ctrl=groups&grp_ID=' . $Group->ID . '"'), 'error'); } return false; } // Return sanitized content return $content; }
<?php //Si l'internaute est déjà connecté, inutile qu'il vienne sur cette page if (isset($_SESSION['connect'])) { include './modules/error.php'; } else { //On inclut les fonctions de la page include './modules/compte/fonctions/inscription.php'; if (isset($_POST['bouton'])) { //On va vérifier qu'aucun champ est vide verifEmptyRow(); //On va vérifier que le captcha est bon antispam_check(); //On va maintenant vérifier les deux mots de passe verifMdp(); //On va vérifier que l'adresse email rentré est correcte verifEmail(); //On va vérifier que le nom d'utilisateur n'est pas déjà pris verifUser(); //On a fait tous les tests de vérification, on peut lancer la requête d'inscription inscription(); $_SESSION['connect'] = true; // On active la variable de connexion $_SESSION['id'] = $db_realmd->lastInsertId(); } else { //On génère le captcha $captcha = antispam_ins(); } //On inclut maintenant le HTML de la page include './modules/compte/html/inscription.php'; //On n'inclut pas le menu de gauche car on utilise un autre type de vue