Fix #yogosha8450
This commit is contained in:
parent
ed2ca6af79
commit
60b90056c4
@ -22,27 +22,6 @@
|
||||
* \brief Page to create/edit/view partnership
|
||||
*/
|
||||
|
||||
//if (! defined('NOREQUIREDB')) define('NOREQUIREDB', '1'); // Do not create database handler $db
|
||||
//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER', '1'); // Do not load object $user
|
||||
//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); // Do not load object $mysoc
|
||||
//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1'); // Do not load object $langs
|
||||
//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION', '1'); // Do not check injection attack on GET parameters
|
||||
//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION', '1'); // Do not check injection attack on POST parameters
|
||||
//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK', '1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on).
|
||||
//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on)
|
||||
//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK', '1'); // Do not check style html tag into posted data
|
||||
//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); // If there is no need to load and show top and left menu
|
||||
//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); // If we don't need to load the html.form.class.php
|
||||
//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); // Do not load ajax.lib.php library
|
||||
//if (! defined("NOLOGIN")) define("NOLOGIN", '1'); // If this page is public (can be called outside logged session). This include the NOIPCHECK too.
|
||||
//if (! defined('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
|
||||
//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT', 'auto'); // Force lang to a particular value
|
||||
//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule'); // Force authentication handler
|
||||
//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN', 1); // The main.inc.php does not make a redirect if not logged, instead show simple error message
|
||||
//if (! defined("FORCECSP")) define('FORCECSP', 'none'); // Disable all Content Security Policies
|
||||
//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
|
||||
//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification
|
||||
|
||||
// Load Dolibarr environment
|
||||
require '../main.inc.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
|
||||
|
||||
@ -37,8 +37,6 @@ if (!$user->admin) {
|
||||
$rowid = GETPOST('rowid', 'int');
|
||||
$entity = GETPOST('entity', 'int');
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
$update = GETPOST('update', 'alpha');
|
||||
$delete = GETPOST('delete', 'none'); // Do not use alpha here
|
||||
$debug = GETPOST('debug', 'int');
|
||||
$consts = GETPOST('const', 'array');
|
||||
$constname = GETPOST('constname', 'alphanohtml');
|
||||
|
||||
@ -64,7 +64,7 @@ if (!$sortorder) {
|
||||
|
||||
$defaulturl = GETPOST('defaulturl', 'alphanohtml');
|
||||
$defaultkey = GETPOST('defaultkey', 'alphanohtml');
|
||||
$defaultvalue = GETPOST('defaultvalue', 'none');
|
||||
$defaultvalue = GETPOST('defaultvalue', 'restricthtml');
|
||||
|
||||
$defaulturl = preg_replace('/^\//', '', $defaulturl);
|
||||
|
||||
|
||||
@ -493,9 +493,9 @@ if (empty($reshook)) {
|
||||
if ($action == 'add') {
|
||||
$mesgs = array();
|
||||
|
||||
$object->email_from = (string) GETPOST("from", "none"); // Must allow 'name <email>'
|
||||
$object->email_replyto = (string) GETPOST("replyto", "none"); // Must allow 'name <email>'
|
||||
$object->email_errorsto = (string) GETPOST("errorsto", "none"); // Must allow 'name <email>'
|
||||
$object->email_from = (string) GETPOST("from", 'alphawithlgt'); // Must allow 'name <email>'
|
||||
$object->email_replyto = (string) GETPOST("replyto", 'alphawithlgt'); // Must allow 'name <email>'
|
||||
$object->email_errorsto = (string) GETPOST("errorsto", 'alphawithlgt'); // Must allow 'name <email>'
|
||||
$object->title = (string) GETPOST("title");
|
||||
$object->sujet = (string) GETPOST("sujet");
|
||||
$object->body = (string) GETPOST("bodyemail", 'restricthtml');
|
||||
@ -531,11 +531,11 @@ if (empty($reshook)) {
|
||||
if ($action == 'settitle') {
|
||||
$object->title = trim(GETPOST('title', 'alpha'));
|
||||
} elseif ($action == 'setemail_from') {
|
||||
$object->email_from = trim(GETPOST('email_from', 'none')); // Must allow 'name <email>'
|
||||
$object->email_from = trim(GETPOST('email_from', 'alphawithlgt')); // Must allow 'name <email>'
|
||||
} elseif ($action == 'setemail_replyto') {
|
||||
$object->email_replyto = trim(GETPOST('email_replyto', 'none')); // Must allow 'name <email>'
|
||||
$object->email_replyto = trim(GETPOST('email_replyto', 'alphawithlgt')); // Must allow 'name <email>'
|
||||
} elseif ($action == 'setemail_errorsto') {
|
||||
$object->email_errorsto = trim(GETPOST('email_errorsto', 'none')); // Must allow 'name <email>'
|
||||
$object->email_errorsto = trim(GETPOST('email_errorsto', 'alphawithlgt')); // Must allow 'name <email>'
|
||||
} elseif ($action == 'settitle' && empty($object->title)) {
|
||||
$mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentities("MailTitle"));
|
||||
} elseif ($action == 'setfrom' && empty($object->email_from)) {
|
||||
|
||||
@ -527,9 +527,9 @@ class Facture extends CommonInvoice
|
||||
|
||||
// Fields coming from GUI (priority on template). TODO Value of template should be used as default value on GUI so we can use here always value from GUI
|
||||
$this->fk_project = GETPOST('projectid', 'int') > 0 ? ((int) GETPOST('projectid', 'int')) : $_facrec->fk_project;
|
||||
$this->note_public = GETPOST('note_public', 'none') ? GETPOST('note_public', 'restricthtml') : $_facrec->note_public;
|
||||
$this->note_private = GETPOST('note_private', 'none') ? GETPOST('note_private', 'restricthtml') : $_facrec->note_private;
|
||||
$this->model_pdf = GETPOST('model', 'alpha') ? GETPOST('model', 'alpha') : $_facrec->model_pdf;
|
||||
$this->note_public = GETPOSTISSET('note_public') ? GETPOST('note_public', 'restricthtml') : $_facrec->note_public;
|
||||
$this->note_private = GETPOSTISSET('note_private') ? GETPOST('note_private', 'restricthtml') : $_facrec->note_private;
|
||||
$this->model_pdf = GETPOSTISSET('model') ? GETPOST('model', 'alpha') : $_facrec->model_pdf;
|
||||
$this->cond_reglement_id = GETPOST('cond_reglement_id', 'int') > 0 ? ((int) GETPOST('cond_reglement_id', 'int')) : $_facrec->cond_reglement_id;
|
||||
$this->mode_reglement_id = GETPOST('mode_reglement_id', 'int') > 0 ? ((int) GETPOST('mode_reglement_id', 'int')) : $_facrec->mode_reglement_id;
|
||||
$this->fk_account = GETPOST('fk_account') > 0 ? ((int) GETPOST('fk_account')) : $_facrec->fk_account;
|
||||
|
||||
@ -196,7 +196,8 @@ if ($action == 'add' && !$cancel) {
|
||||
}
|
||||
$object->amount = $amount;
|
||||
$object->label = GETPOST("label", 'alpha');
|
||||
$object->note = GETPOST("note", 'none');
|
||||
$object->note = GETPOST("note", 'restricthtml');
|
||||
$object->note_private = GETPOST("note", 'restricthtml');
|
||||
|
||||
if (empty($object->datep)) {
|
||||
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("DatePayment")), null, 'errors');
|
||||
@ -236,7 +237,7 @@ if ($action == 'add' && !$cancel) {
|
||||
$paiement->amounts = array($object->id=>$amount); // Tableau de montant
|
||||
$paiement->paiementtype = GETPOST("type_payment", 'alphanohtml');
|
||||
$paiement->num_payment = GETPOST("num_payment", 'alphanohtml');
|
||||
$paiement->note = GETPOST("note", 'none');
|
||||
$paiement->note = GETPOST("note", 'restricthtml');
|
||||
|
||||
if (!$error) {
|
||||
$paymentid = $paiement->create($user, (int) GETPOST('closepaidtva'));
|
||||
|
||||
@ -56,7 +56,7 @@ if (!defined('USE_CUSTOM_REPORT_AS_INCLUDE')) {
|
||||
}
|
||||
|
||||
$search_yaxis = GETPOST('search_yaxis', 'array');
|
||||
$search_graph = GETPOST('search_graph', 'none');
|
||||
$search_graph = GETPOST('search_graph', 'restricthtml');
|
||||
|
||||
// Load variable for pagination
|
||||
$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
|
||||
|
||||
@ -641,7 +641,7 @@ function GETPOST($paramname, $check = 'alphanohtml', $method = 0, $filter = null
|
||||
}
|
||||
|
||||
// Check rule
|
||||
if (preg_match('/^array/', $check)) { // If 'array' or 'array:restricthtml' or 'array:aZ09'
|
||||
if (preg_match('/^array/', $check)) { // If 'array' or 'array:restricthtml' or 'array:aZ09' or 'array:intcomma'
|
||||
if (!is_array($out) || empty($out)) {
|
||||
$out = array();
|
||||
} else {
|
||||
|
||||
@ -185,7 +185,7 @@ $listofexamplesforlink = 'Societe:societe/class/societe.class.php<br>Contact:con
|
||||
<?php } else { ?>
|
||||
<td><?php echo $form->textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc")).$form->textwithpicto($langs->trans("Computedpersistent"), $langs->trans("ComputedpersistentDesc"), 1, 'warning'); ?></td>
|
||||
<?php } ?>
|
||||
<td class="valeur"><textarea name="computed_value" id="computed_value" class="quatrevingtpercent" rows="<?php echo ROWS_4 ?>"><?php echo (GETPOST('computed_value', 'none') ?GETPOST('computed_value', 'none') : ''); ?></textarea></td>
|
||||
<td class="valeur"><textarea name="computed_value" id="computed_value" class="quatrevingtpercent" rows="<?php echo ROWS_4 ?>"><?php echo (GETPOSTISSET('computed_value') ? GETPOST('computed_value', 'restricthtml') : ''); ?></textarea></td>
|
||||
</tr>
|
||||
<!-- Default Value (at sql setup level) -->
|
||||
<tr class="extra_default_value"><td><?php echo $langs->trans("DefaultValue").' ('.$langs->trans("Database").')'; ?></td><td class="valeur"><input id="default_value" type="text" name="default_value" size="5" value="<?php echo (GETPOST('default_value', 'alpha') ?GETPOST('default_value', 'alpha') : ''); ?>"></td></tr>
|
||||
|
||||
@ -39,7 +39,6 @@
|
||||
//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT', 'auto'); // Force lang to a particular value
|
||||
//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule'); // Force authentication handler
|
||||
//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN', 1); // The main.inc.php does not make a redirect if not logged, instead show simple error message
|
||||
//if (! defined("FORCECSP")) define('FORCECSP', 'none'); // Disable all Content Security Policies
|
||||
//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
|
||||
//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification
|
||||
|
||||
|
||||
@ -57,7 +57,7 @@ if ($action == 'update') {
|
||||
$label = GETPOST('EXTERNALSITE_LABEL', 'alphanohtml');
|
||||
|
||||
// exturl can be an url or a HTML string
|
||||
$exturl = GETPOST('EXTERNALSITE_URL', 'none');
|
||||
$exturl = GETPOST('EXTERNALSITE_URL', 'restricthtml');
|
||||
$exturl = dol_string_onlythesehtmltags($exturl, 1, 1, 0, 1);
|
||||
$exturl = dol_string_onlythesehtmlattributes($exturl);
|
||||
|
||||
@ -110,7 +110,7 @@ print '<tr class="oddeven">';
|
||||
print '<td class="fieldrequired">'.$langs->trans("ExternalSiteURL")."</td>";
|
||||
print '<td><textarea class="flat minwidth500" name="EXTERNALSITE_URL">';
|
||||
|
||||
$exturl = GETPOST('EXTERNALSITE_URL', 'none');
|
||||
$exturl = GETPOST('EXTERNALSITE_URL', 'restricthtml');
|
||||
$exturl = dol_string_onlythesehtmltags($exturl, 1, 1, 0, 1);
|
||||
$exturl = dol_string_onlythesehtmlattributes($exturl);
|
||||
|
||||
|
||||
@ -42,7 +42,6 @@
|
||||
//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT', 'auto'); // Force lang to a particular value
|
||||
//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule'); // Force authentication handler
|
||||
//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN', 1); // The main.inc.php does not make a redirect if not logged, instead show simple error message
|
||||
//if (! defined("FORCECSP")) define('FORCECSP', 'none'); // Disable all Content Security Policies
|
||||
//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
|
||||
//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification
|
||||
|
||||
|
||||
@ -661,7 +661,7 @@ if (!defined('NOLOGIN')) {
|
||||
// Verification security graphic code
|
||||
if ($test && GETPOST("username", "alpha", 2) && !empty($conf->global->MAIN_SECURITY_ENABLECAPTCHA) && !isset($_SESSION['dol_bypass_antispam'])) {
|
||||
$sessionkey = 'dol_antispam_value';
|
||||
$ok = (array_key_exists($sessionkey, $_SESSION) === true && (strtolower($_SESSION[$sessionkey]) === strtolower(GETPOST('code', 'none'))));
|
||||
$ok = (array_key_exists($sessionkey, $_SESSION) === true && (strtolower($_SESSION[$sessionkey]) === strtolower(GETPOST('code', 'restricthtml'))));
|
||||
|
||||
// Check code
|
||||
if (!$ok) {
|
||||
|
||||
@ -767,7 +767,7 @@ if ($dirins && $action == 'addlanguage' && !empty($module)) {
|
||||
|
||||
// remove/delete File
|
||||
if ($dirins && $action == 'confirm_removefile' && !empty($module)) {
|
||||
$relativefilename = dol_sanitizePathName(GETPOST('file', 'none'));
|
||||
$relativefilename = dol_sanitizePathName(GETPOST('file', 'restricthtml'));
|
||||
if ($relativefilename) {
|
||||
$dirnametodelete = dirname($relativefilename);
|
||||
$filetodelete = $dirins.'/'.$relativefilename;
|
||||
|
||||
@ -40,7 +40,6 @@
|
||||
//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT', 'auto'); // Force lang to a particular value
|
||||
//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule'); // Force authentication handler
|
||||
//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN', 1); // The main.inc.php does not make a redirect if not logged, instead show simple error message
|
||||
//if (! defined("FORCECSP")) define('FORCECSP', 'none'); // Disable all Content Security Policies
|
||||
//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
|
||||
//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification
|
||||
if (!defined('NOSESSION')) define('NOSESSION', '1'); // On CLI mode, no need to use web sessions
|
||||
|
||||
@ -448,10 +448,8 @@ if ($action == "dosign" && empty($cancel)) {
|
||||
$("#clearsignature").on("click",function(){
|
||||
$("#signature").jSignature("clear");
|
||||
$("#signbutton").attr("disabled",true);
|
||||
/* $("#clearsignature").css("display","none"); */
|
||||
});
|
||||
|
||||
/* $("#clearsignature").css("display","none"); */
|
||||
$("#signbutton").attr("disabled",true);
|
||||
});
|
||||
</script>';
|
||||
|
||||
@ -173,7 +173,7 @@ if (empty($reshook) && $action == 'create_ticket' && GETPOST('save', 'alpha')) {
|
||||
// Check Captcha code if is enabled
|
||||
if (!empty($conf->global->MAIN_SECURITY_ENABLECAPTCHA)) {
|
||||
$sessionkey = 'dol_antispam_value';
|
||||
$ok = (array_key_exists($sessionkey, $_SESSION) === true && (strtolower($_SESSION[$sessionkey]) === strtolower(GETPOST('code', 'none'))));
|
||||
$ok = (array_key_exists($sessionkey, $_SESSION) === true && (strtolower($_SESSION[$sessionkey]) === strtolower(GETPOST('code', 'restricthtml'))));
|
||||
if (!$ok) {
|
||||
$error++;
|
||||
array_push($object->errors, $langs->trans("ErrorBadValueForCode"));
|
||||
|
||||
@ -277,7 +277,7 @@ if ($action == 'add' && empty($cancel)) {
|
||||
$paiement->amounts = array($object->id=>$amount); // Tableau de montant
|
||||
$paiement->paiementtype = $type_payment;
|
||||
$paiement->num_payment = GETPOST("num_payment", 'alphanohtml');
|
||||
$paiement->note = GETPOST("note", 'none');
|
||||
$paiement->note = GETPOST("note", 'restricthtml');
|
||||
|
||||
if (!$error) {
|
||||
$paymentid = $paiement->create($user, (int) GETPOST('closepaidsalary'));
|
||||
|
||||
@ -110,8 +110,8 @@ if ($action == 'add_payment' || ($action == 'confirm_paiement' && $confirm == 'y
|
||||
$paiement->amounts = $amounts; // Tableau de montant
|
||||
$paiement->paiementtype = GETPOST("paiementtype", 'alphanohtml');
|
||||
$paiement->num_payment = GETPOST("num_payment", 'alphanohtml');
|
||||
$paiement->note = GETPOST("note", 'none');
|
||||
$paiement->note_private = GETPOST("note", 'none');
|
||||
$paiement->note = GETPOST("note", 'restricthtml');
|
||||
$paiement->note_private = GETPOST("note", 'restricthtml');
|
||||
|
||||
if (!$error) {
|
||||
$paymentid = $paiement->create($user, (GETPOST('closepaidsalary') == 'on' ? 1 : 0));
|
||||
|
||||
@ -404,7 +404,7 @@ if (empty($reshook)) {
|
||||
$object->firstname = GETPOST("firstname", 'alphanohtml');
|
||||
$object->login = GETPOST("login", 'alphanohtml');
|
||||
$object->gender = GETPOST("gender", 'aZ09');
|
||||
$object->pass = GETPOST("password", 'none');
|
||||
$object->pass = GETPOST("password", 'none'); // We can keep 'none' for password fields
|
||||
$object->api_key = (GETPOST("api_key", 'alphanohtml')) ? GETPOST("api_key", 'alphanohtml') : $object->api_key;
|
||||
if (!empty($user->admin)) {
|
||||
$object->admin = GETPOST("admin", "int"); // admin flag can only be set/unset by an admin user. A test is also done later when forging sql request
|
||||
|
||||
@ -290,7 +290,7 @@ if ($modulepart == 'barcode') {
|
||||
if (in_array($encoding, array('EAN8', 'EAN13'))) {
|
||||
$code = GETPOST("code", 'alphanohtml');
|
||||
} else {
|
||||
$code = GETPOST("code", 'none'); // This can be rich content (qrcode, datamatrix, ...)
|
||||
$code = GETPOST("code", 'restricthtml'); // This can be rich content (qrcode, datamatrix, ...)
|
||||
}
|
||||
|
||||
if (empty($generator) || empty($encoding)) {
|
||||
|
||||
@ -437,6 +437,25 @@ class CodingPhpTest extends PHPUnit\Framework\TestCase
|
||||
$this->assertTrue($ok, 'Found a $_SERVER[\'QUERY_STRING\'] without dol_escape_htmltag neither dol_string_nohtmltag around it, in file '.$file['relativename'].'. Bad.');
|
||||
|
||||
|
||||
// Check GETPOST(... 'none');
|
||||
$ok=true;
|
||||
$matches=array();
|
||||
preg_match_all('/GETPOST\s*\(([^\)]+),\s*["\']none["\']/i', $filecontent, $matches, PREG_SET_ORDER);
|
||||
foreach ($matches as $key => $val) {
|
||||
var_dump($val);
|
||||
if (!in_array($val[1], array(
|
||||
"'replacestring'", "'htmlheader'", "'WEBSITE_HTML_HEADER'", "'WEBSITE_CSS_INLINE'", "'WEBSITE_JS_INLINE'", "'WEBSITE_MANIFEST_JSON'", "'PAGE_CONTENT'", "'WEBSITE_README'",
|
||||
"'search_status'", '"mysqldump"', '"postgresqldump"', "'db_pass_root'", "'db_pass'", '"pass"', '"pass1"', '"pass2"', '"password"', "'password'", '"MAIN_MAIL_SMTPS_PW"'))) {
|
||||
$ok=false;
|
||||
break;
|
||||
}
|
||||
//if ($reg[0] != 'db') $ok=false;
|
||||
}
|
||||
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
|
||||
$this->assertTrue($ok, 'Found a GETPOST that use \'none\' as a parameter in file '.$file['relativename'].' and param is not an allowed parameter for using none - Bad.');
|
||||
//exit;
|
||||
|
||||
|
||||
// Test that first param of print_liste_field_titre is a translation key and not the translated value
|
||||
$ok=true;
|
||||
$matches=array();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user