Archief - Q: Beveiligen php website

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

Smontje

Legacy Member
Beste,

Een tijdje geleden heb ik voor het eerst een volledige website gemaakt in php 5 en ik was mij niet bewust van website beveiliging. Een tijdje geleden was mijn website hacked "Site hacked by:Morgan".

Het probleem stelt zich volgens mijn leverancier dat ik niet controleer of de variabelen die gestuurd worden naar de index.php wel van mijn site afkomstig zijn en niet van een andere site.

De code van mijn index.php:
<?
session_start();

if(isset($_GET['page']))
$pagenumber = $_GET['page'];
else
$pagenumber = "home.php";

$_SESSION["taal"] = "nederlands";

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="robots" content="ALL">
<link href="style/style2.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="script.js"></script>
<title></title>
</head>
<body>
<div id="container">
<div id="banner">
<table class="tabel">
<tr>
<td class="tekst"><a href="index.php?page=home.php">NL</a>||
<a href="index_fr.php?page=home_fr.php">FR</a>||
<a href="index_eng.php?page=home_fr.php">ENG</a></td>
</tr>
</table>
</div>
<div id="menu">
<table class="tabel">
<tr>
<td><a href="index.php?page=home.php"><img src="images/home.jpg" border="0" /></a></td>
<td></td>
<td><a href="index.php?page=fotos.php"><img src="images/foto.jpg" border="0" /></a></td>
<td></td>
<td><a href="index.php?page=prijzen.php"><img src="images/prijs.jpg" border="0"/></a></td>
<td></td>
<td><a href="index.php?page=contact.php"><img src="images/contact.jpg" border="0" /></a></td>
<td></td>
<td><a href="index.php?page=locatie.php"><img src="images/locatie.jpg" border="0" /></a></td>
</tr>
</table>
</div>
<div id="boven"></div>
<div id="tekst">
<?
include($pagenumber);
?>
</div>
<div id="onder"></div>
</div>
</body>
</html>

Na enige tijd wat te zoeken op beveiliging van een website kwam ik volgende code tegen:
if (isset($HTTP_POST_VARS['GLOBALS']) || isset($_POST['GLOBALS']) ||
isset($HTTP_POST_FILES['GLOBALS']) || isset($_FILES['GLOBALS']) ||
isset($HTTP_GET_VARS['GLOBALS']) || isset($_GET['GLOBALS']) ||
isset($HTTP_COOKIE_VARS['GLOBALS']) || isset($_COOKIE['GLOBALS']))
{ echo "Is this a GLOBAL GPC hacking attemp?" ; exit; }

Ik vroeg mij af of dit echter voldoende is en of eventueel sommige mensen mij wat informatie kunnen geven over de verbetering van de beveiliging.

Na het gebruiken van de search heb ik af en toe zo wat informatie gelezen maar ik weet echter niet als ze van toepassing zijn voor mijn website...

mvg

Tyfius

Legacy Member
Er gaan al een aantal dingen fout.
PHP:
if(isset($_GET['page']))
$pagenumber = $_GET['page'];
else
$pagenumber = "home.php";
Hier ben je al fout bezig. Je laat de bezoeker weten hoe de pagina's noemen en doet meteen een include. Wat ik kan doen is bijvoorbeeld (eenvoudig voorgesteld):
Code:
http://www.jouwsite.be/index.php?page=http://www.mijnwebsite.be/script.php
Hier ga jij dus mijn code invoegen waardoor ik allerlei bewerkingen kan doen. Een betere oplossing is dus bijvoorbeeld:
Code:
index.php?page=home
Dit zonder de PHP extensie. En dan iets doen als:
PHP:
if (!isset($_GET['page'])) {
    $pg_include = "home.php";
} else {
    switch($_GET['page'])
    {
    case "home":
        $pg_include = "home.php";
        break;
        
    case "fotos":
        $pg_include = "fotos.php";
        break;
        
    default:
        // Zeer belangrijk.
        // Default wordt gebruikt als er geen keuze gemaakt werd
        // die gekend is.
        $pg_include = "home.php";
        break;
    }
}
Er zijn nog verscheidene andere (en veiligere) mogenlijkheden voor het beveiligen van je website maar hier ben je toch al een stukje veiliger mee.

killgore

Legacy Member
Tyfius zei:

Volledig waar, een beschouwing over het ?page= systeem staat trouwens in de sticky (tenzij ze mijn geweldige bijdrage er hebben uitgesmeten :unsure: ).

Daarnaast wil ik je ook wijzen op het gebruik van de wondermooie functie get_magic_quotes_gpc en de daarbijhorende functie addslashes (een vb. staat in link 1).

een functie die ikzelf gebruik geeft dan bv:
PHP:
function getPostVar($var,$default = "")
{
	if(isset($_POST[$var]))
	{
		if(is_numeric($default) && (empty($_POST[$var]) || !is_numeric($_POST[$var])) ) return $default;
		if(!get_magic_quotes_gpc()) return addslashes($_POST[$var]);
		return $_POST[$var];
	}
	return $default;
}

Die is_numeric check heb ik zelf ingebouwd om te vermijden dat ik strings krijg bij waarden die volledig numeriek moeten zijn zoals id's, offsets, ... . Je kan dat er of course uitlaten naargelang je eigen wensen ;).

Een 3e opmerking, die ook te maken heeft met security, maar eerder user-side: Ik zou niet afgaan op het php-session systeem.

Imho is het beste (& enige) dat je moet doen bij de gebruiker op 1 of andere manier een identificatiecode opslaan die niet-repetitief is zoals de sids van php & niet simpel te traceren. Hashes van bepaalde gebruikersspecifieke zaken zijn daarvoor zeer goed.

Naargelang van die identificatiecode zet je zelf een sessionsysteem op en sla je alle sessie-informatie lokaal beveiligd (liefst encrypted dus) op. Het systeem daarvoor kan je natuurlijk zelf kiezen (een eigen filesystem of een bestaand db-systeem).

Een 4e, ZEER belangrijk punt is op 1 of andere manier uw referer checken. Als je bijvoorbeeld een gebruiker ziet inloggen op je pagina en hij komt van een externe site is het aangeraden die gebruikersaccount te blokeren en de gebruiker zelf op de hoogte te stellen. Een "veelgebruikte" taktiek is immers je inlogpagina namaken, zo de gegevens krijgen (dit is echt niet zo moeilijk te doen) & daarna je doorverwijzen naar de gewone site met die logingegevens. Vele gewone gebruikers hebben dit niet onmiddellijk door & zullen hun account niet blokkeren of zo tot het te laat is. Worst-case-scenario is dat die gebruiker eigenlijk een admin is.

edit: enkele zeer belangrijke zaken:
gebruik nooit exec of een dergelijke functie zonder dat je 100% zeker bent dat het argument dat je er aan meegeeft veillig is. Laat desnoods elke beveiligingsfunctie van php (zoals addslashes) er op los, maar als een dergelijke functie beïnvloedbaar is zijn ze in staat om meer als je website te hacken.

Die laatste 3 zijn natuurlijk meer advanced maar imho zeer belangrijk te onthouden eenmaal je wat verder gaat. User input & zaken als exec/include/... zijn vitaal, daar mag je nooit denken als "ja, maar die extra check vertraagt mijn applicatie".

Smontje

Legacy Member
Dank je voor de goeie uitleg, kzal het sebiet eens invoeren

Smontje

Legacy Member
Ik gebruik nu op mijn index pagina de volgende code om te includen...

PHP:
	if (!isset($_GET['page'])) 
	{
		$pg_include = "home.php";
	} 
	else 
	{
		switch($_GET['page'])
		{
			case "home":
				$pg_include = "home.php";
				break;
				
			case "fotos":
				$pg_include = "fotos.php";
				break;
			
			case "prijzen":
				$pg_include = "prijzen.php";
				break;
				
			case "contact":
				$pg_include = "contact.php";
				break;
			
			case "locatie":
				$pg_include = "locatie.php";
				break;
				
			default:
				// Zeer belangrijk.
				// Default wordt gebruikt als er geen keuze gemaakt werd
				// die gekend is.
				$pg_include = "home.php";
				break;
		}
	}

Maar als ik nu op gelijk welke link op mijn pagina klik wordt steeds dezelfde pagina include namelijk "home.php". Ik zie het probleem niet op eerste zicht, kan iemand mij hierin helpen?

killgore

Legacy Member
Ik gok dat je url verkeerd wordt doorgegeven.

deze post kan misschien ook nuttig zijn, dat je niet met een switch van 100 regels komt binnenkort :p.

edit: ik merk wel juist dat in die code daar die in_array moet vervangen worden door array_key_exists.

Misschien dat een mod dit kan aanpassen?

RpR

Legacy Member
Ook is het nogal zinloos van te kijken of een var gezet is als ge een default in uw switch hebt staan.

Tyfius

Legacy Member
Niet per se. Het kan zijn dat hij wilt doorverwijzen naar een 404 pagina. Die komt dan bij de default te staan.

killgore

Legacy Member
RpR zei:
Ook is het nogal zinloos van te kijken of een var gezet is als ge een default in uw switch hebt staan.

oja?

PHP:
<?php
error_reporting(E_ALL);
switch($_GET["bla"])
{
	default:
		echo "hallo";
}
?>

Zal een fout geven.
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan