Skip to content

CSRF zaštita

2.5.x ✅ 4.0.x ✅

Cross-Site Request Forgery (CSRF) napadi varaju korisnike da izvrše neželjene radnje na web-mjestu na kojem su autentificirani. XOOPS pruža ugrađenu CSRF zaštitu kroz XoopsSecurity class.

  • Najbolje sigurnosne prakse - Opsežan sigurnosni vodič
  • Sanitizacija unosa - MyTextSanitizer i provjera valjanosti
  • SQL-Injection-Prevention - Sigurnosne prakse baze podataka

Napad CSRF događa se kada:

  1. Korisnik je autentificiran na vašoj XOOPS stranici
  2. Korisnik posjećuje zlonamjernu web stranicu
  3. Zlonamjerna stranica šalje zahtjev vašoj XOOPS stranici koristeći sesiju korisnika
  4. Vaša stranica obrađuje zahtjev kao da dolazi od legitimnog korisnika

XOOPS pruža XoopsSecurity class za zaštitu od CSRF napada. Ovaj class upravlja sigurnosnim tokenima koji moraju biti included u obrascima i potvrđeni prilikom obrade zahtjeva.

Sigurnosni class generira jedinstvene tokene koji su pohranjeni u korisničkoj sesiji i moraju biti included u obrascima:

$security = new XoopsSecurity();
// Get token HTML input field
$tokenHTML = $security->getTokenHTML();
// Get just the token value
$tokenValue = $security->createToken();

Prilikom obrade slanja obrasca provjerite je li token valjan:

$security = new XoopsSecurity();
if (!$security->check()) {
redirect_header('index.php', 3, _MD_TOKENEXPIRED);
exit();
}

Kada koristite XOOPS obrazac classes, zaštita tokena je jednostavna:

// Create a form
$form = new XoopsThemeForm('Add Item', 'form_name', 'submit.php');
// Add form elements
$form->addElement(new XoopsFormText('Title', 'title', 50, 255, ''));
$form->addElement(new XoopsFormTextArea('Content', 'content', ''));
// Add hidden token field - ALWAYS include this
$form->addElement(new XoopsFormHiddenToken());
// Add submit button
$form->addElement(new XoopsFormButton('', 'submit', _SUBMIT, 'submit'));

Za prilagođene HTML obrasce koji ne koriste XoopsForm:

// In your form template or PHP file
$security = new XoopsSecurity();
?>
<form method="post" action="submit.php">
<input type="text" name="title" />
<textarea name="content"></textarea>
<!-- Include the token -->
<?php echo $security->getTokenHTML(); ?>
<button type="submit">Submit</button>
</form>

Prilikom generiranja obrazaca u Smarty templates:

// In your PHP file
$security = new XoopsSecurity();
$GLOBALS['xoopsTpl']->assign('token', $security->getTokenHTML());
{* In your template *}
<form method="post" action="submit.php">
<input type="text" name="title" />
<textarea name="content"></textarea>
{* Include the token *}
<{$token}>
<button type="submit">Submit</button>
</form>
// In your form processing script
$security = new XoopsSecurity();
// Verify the token
if (!$security->check()) {
redirect_header('index.php', 3, _MD_TOKENEXPIRED);
exit();
}
// Token is valid, process the form
$title = $_POST['title'];
// ... continue processing
$security = new XoopsSecurity();
if (!$security->check()) {
// Get detailed error information
$errors = $security->getErrors();
// Log the error
error_log('CSRF token validation failed: ' . implode(', ', $errors));
// Redirect with error message
redirect_header('form.php', 3, 'Security token expired. Please try again.');
exit();
}

Kada radite sa zahtjevima AJAX, include token u vašem zahtjevu:

// JavaScript - get token from hidden field
var token = document.querySelector('input[name="XOOPS_TOKEN_REQUEST"]').value;
// Include in AJAX request
fetch('ajax_handler.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: 'action=save&XOOPS_TOKEN_REQUEST=' + encodeURIComponent(token)
});
// PHP AJAX handler
$security = new XoopsSecurity();
if (!$security->check()) {
echo json_encode(['error' => 'Invalid security token']);
exit();
}
// Process AJAX request

Za dodatnu zaštitu, posebno za AJAX zahtjeve, također možete provjeriti HTTP referer:

$security = new XoopsSecurity();
// Check referer header
if (!$security->checkReferer()) {
echo json_encode(['error' => 'Invalid request']);
exit();
}
// Also verify the token
if (!$security->check()) {
echo json_encode(['error' => 'Invalid token']);
exit();
}
$security = new XoopsSecurity();
// Perform both checks
if (!$security->checkReferer() || !$security->check()) {
redirect_header('index.php', 3, 'Security validation failed');
exit();
}

Tokeni imaju ograničen vijek trajanja kako bi spriječili napade ponavljanjem. Ovo možete konfigurirati u postavkama XOOPS ili elegantno rukovati isteklim tokenima:

$security = new XoopsSecurity();
if (!$security->check()) {
// Token may have expired
// Regenerate form with new token
redirect_header('form.php', 3, 'Your session has expired. Please submit the form again.');
exit();
}

Kada imate više obrazaca na istoj stranici, svaki bi trebao imati svoj token:

// Form 1
$form1 = new XoopsThemeForm('Form 1', 'form1', 'submit1.php');
$form1->addElement(new XoopsFormHiddenToken('token1'));
// Form 2
$form2 = new XoopsThemeForm('Form 2', 'form2', 'submit2.php');
$form2->addElement(new XoopsFormHiddenToken('token2'));

Uvijek koristite tokene za operacije promjene stanja

Section titled “Uvijek koristite tokene za operacije promjene stanja”

Uključite tokene u bilo kojem obliku koji:

  • Stvara podatke
  • Ažurira podatke
  • Briše podatke
  • Mijenja korisničke postavke
  • Izvodi bilo koju radnju administrative

Nemojte se oslanjati isključivo na provjeru preporuke

Section titled “Nemojte se oslanjati isključivo na provjeru preporuke”

Zaglavlje HTTP referera može biti:

  • Ogoljen alatima za privatnost
  • Nedostaje u nekim preglednicima
  • Lažna u nekim slučajevima

Uvijek koristite provjeru tokena kao svoju primarnu obranu.

Regenerirajte tokene na odgovarajući način

Section titled “Regenerirajte tokene na odgovarajući način”

Razmotrite ponovno generiranje tokena:- Nakon uspješne predaje obrasca

  • Nakon prijave/odjave
  • U redovitim intervalima za duge sesije
$security = new XoopsSecurity();
if (!$security->check()) {
// Store form data temporarily
$_SESSION['form_backup'] = $_POST;
// Redirect back to form with message
redirect_header('form.php?restore=1', 3, 'Please resubmit the form.');
exit();
}

Problem: Sigurnosna provjera ne uspijeva s “token nije pronađen”

Rješenje: Provjerite je li polje tokena included u vašem obrascu:

$form->addElement(new XoopsFormHiddenToken());

Problem: Korisnici vide “token je istekao” nakon dugog ispunjavanja obrasca

Rješenje: Razmotrite korištenje JavaScript za povremeno osvježavanje tokena:

// Refresh token every 10 minutes
setInterval(function() {
fetch('refresh_token.php')
.then(response => response.json())
.then(data => {
document.querySelector('input[name="XOOPS_TOKEN_REQUEST"]').value = data.token;
});
}, 600000);

Problem: AJAX zahtjevi nisu uspjeli provjeriti valjanost tokena

Rješenje: Osigurajte da se token prosljeđuje sa svakim AJAX zahtjevom i provjerite ga na strani poslužitelja:

// AJAX handler
header('Content-Type: application/json');
$security = new XoopsSecurity();
if (!$security->check(true, false)) { // Don't clear token for AJAX
http_response_code(403);
echo json_encode(['error' => 'Invalid token']);
exit();
}
form.php
<?php
require_once dirname(__DIR__) . '/mainfile.php';
$security = new XoopsSecurity();
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!$security->check()) {
redirect_header('form.php', 3, 'Security token expired. Please try again.');
exit();
}
// Process valid submission
$title = $myts->htmlSpecialChars($_POST['title']);
// ... save to database
redirect_header('success.php', 3, 'Item saved successfully!');
exit();
}
// Display form
$GLOBALS['xoopsOption']['template_main'] = 'mymodule_form.tpl';
include XOOPS_ROOT_PATH . '/header.php';
$form = new XoopsThemeForm('Add Item', 'add_item', 'form.php');
$form->addElement(new XoopsFormText('Title', 'title', 50, 255, ''));
$form->addElement(new XoopsFormTextArea('Content', 'content', ''));
$form->addElement(new XoopsFormHiddenToken());
$form->addElement(new XoopsFormButton('', 'submit', _SUBMIT, 'submit'));
$GLOBALS['xoopsTpl']->assign('form', $form->render());
include XOOPS_ROOT_PATH . '/footer.php';

#sigurnost #csrf #xoops #forms #tokeni #XoopsSecurity