Probleem met beveiligen VAN.

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Marco Eilander

Marco Eilander

04/01/2014 17:30:26
Quote Anchor link
Hallo,

Ik ben bezig met een upload systeem, en daarvoor is een beveiliging erg belangrijk.
Nu weet ik alleen niet HOE ik het moet beveiligen. Ik heb het systeem laten testen door professionele scripters (een bedrijf), die ik goed ken, en hadden op één of ander manier een afbeelding kunnen verwijderen, terwijl het IP overeen moet komen met die van jou. Ook heb ik ergens een keer gelezen dat hidden inputs niet handig zijn, en dat je daarmee ook kan "prutsen", helaas weet ik (nog) geen andere mogelijke vervanging.

Waar het bestand verwijderd kan worden :

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
<html>
<head>
<style>
html{
background-color:#F2F2F2;
}
.layout{
margin:20px auto;
width:680px;

}
.btn{
border-radius:5px;
background-image: url('images/btn-bg1.png');
height:30px;
width:123px;
border:1px solid #98BCC7;
color:#2B567F;
font-weight:bold;
cursor:pointer;
}
.btn:hover{
border-radius:5px;
background-image: url('images/btn2.png');
height:30px;
width:123px;
border:1px solid #98BCC7;
color:#2B567F;
}
.menulinks{
margin-right:5px;
width:160px;
float:left;
}
.afbeelding{
width:100%;
margin-top:30px;
text-align:Center;
}
h1{
background-color:#2B567F;
color:White;
text-shadow: 2px 2px 2px black;
margin-bottom:0px;
margin-top:0px;
text-align:Center;
}
h2{
color:#2B567F;
text-align:Center;
font-size:20px;
}
.layer{
border:1px solid #aaa;
background-color:White;
width:500px;
padding:3px;
border-radius:5px;
float:right;
}
.layer_btm{
border:1px solid #aaa;
margin-top:5px;
background-color:White;
width:500px;
padding:3px;
border-radius:5px;
float:right;
color:Gray;
}

.content{
border:1px solid #aaa;
background-color:White;
padding:2px;
border-radius:5px;
}
.melding-fout{
color:red;
border:1px solid red;
background-color:#FFE3E3;
}
h4{
text-align:center;
margin:5px;
font-size:18px;
}
img{
border:1px solid silver;
padding:1px;
max-width:470px;
max-height:470px;
}
hr{
border:0;
border-bottom:1px dashed silver;
}
li{
list-style-type:none;
margin-left:-30px;
}

.kopje{
border-bottom-left-radius:5px;
border-bottom-right-radius:5px;
border:1px solid #aaa;
background-color:White;
margin-bottom:5px;
}
</style>
<title>Afbeelding uploaden</title>
</head>
<body>
<div class="layout">
<div class="menulinks">

<h1>Navigatie</h1>
<div class="kopje">
<ul>

<li><a href="http://uplo.nl/">Bestand uploaden</a><li>
<li>
<?php
require_once('config/config.php');

$result = mysql_query("SELECT * FROM uploadsysteem WHERE ip = '".$_SERVER['REMOTE_ADDR']."'");
$num_rows = mysql_num_rows($result);

echo "<a href='http://uplo.nl/mijnuploads.php'>Mijn bestanden(<b>".$num_rows."</b>)</a>";

?>

</li>
</ul>
</div>

<h1>Statistieken</h1>
<div class="kopje">
<ul>
<li>
<?php
require_once('config/config.php');

$result = mysql_query("SELECT * FROM uploadsysteem");
$num_rows = mysql_num_rows($result);

echo "<b>Aantal uploads: </b>".$num_rows."</a>";

?>

</li>
</ul>
</div>
</div>
<div class="layer">
<h1>afbeelding verwijderen</h1>
<?php


    //-- ip adres omzetten in een variable
    $ip = $_SERVER['REMOTE_ADDR'];

    //-- haal het specifieke nieuwsbericht uit de database
    //-- informatie ophalen uit het database

    $sql = "SELECT * FROM uploadsysteem WHERE ip = '".$ip."' AND bestand = '".$_POST['bestand']."'";
    $res = mysql_query($sql);
    $row = mysql_fetch_array($res);


if(mysql_num_rows($res) == 0) {
//*als er geen afbeelding overeen komt met het IP of andersom.
echo 'Er is geen afbeelding gevonden.';
}
else{

//foto invoeren
$sizer = "http://www.uplo.nl/uploads/".$row['bestand']."";
//afmetingen van de foto ophalen
$size = getimagesize($sizer);
//$breedte geeft als resultaat de breedte van de foto weer in pixels
$breedte = $size[0];
//$hoogte geeft als resultaat de hoogte van de foto weer in pixels
$hoogte = $size[1];

echo '
<div class="afbeelding"><img src=http://www.uplo.nl/uploads/'
.$row['bestand'].' ??/></div><Hr>
<p>Je staat op het punt deze afbeelding te verwijderen. Weet je het zeker?</p>
</table>
<table>
<tr>
<td>
<form action="bevestiging.php" method="POST">
<input type="hidden" name="bestand" value="'
.$_POST['bestand'].'"/>
<input type="submit" class="btn" name="verwijderen" value="Ja, verwijderen"/>
</form>
</td>
<td>
<form action="http://uplo.nl/mijnafbeeldingen" method="POST">
<input type="submit" class="btn" value="nee, terug"/>
</form>
</td>
</tr>
</table>
'
;
}

if($row['ip'] == $_SERVER['REMOTE_ADDR']){
if(isset($_POST['verwijderen'])){
echo "Je hebt <b>".$_POST['bestand']."</b> succesvol verwijderd.<hr>";
$myFile = "uploads/".$_POST['bestand']."";
unlink($myFile);
mysql_query("DELETE FROM uploadsysteem WHERE bestand = '".$_POST['bestand']."' AND ip = '".$_SERVER['REMOTE_ADDR']."'");
echo "<META HTTP-EQUIV=Refresh CONTENT='1; URL=mijnuploads.php'>";
}
}

?>


</div>
<div class="layer_btm">
&copy;2014 Uplo.nl - Alle rechten voorbehouden.
</div>
</div>
</body>
</html>


We gaan met de website nog niet officieel van start, het stukje CSS komt nog apart in een .css. ;)
Verder zat ik nog te denken, betreft het terug kijken van jouw geüploade bestanden.

Een inlog / registratie systeem is opzicht erg handig, maar vind het nogal onhandig om eerst te moeten inloggen, voordat je een afbeelding kan uploaden, terwijl het de bedoeling is, dat het snel kan.
 
PHP hulp

PHP hulp

22/12/2024 18:24:53
 
- SanThe -

- SanThe -

04/01/2014 18:06:42
Quote Anchor link
Begin eens met de query's te beveiligen. Die zijn nu lek.
 
Joakim Broden

Joakim Broden

04/01/2014 18:15:20
Quote Anchor link
'professionele scripters'... Volgens mij valt dat wel mee, want jou script is zo lek als wat. Als je wilt kun je met 1 simpele regel je hele database verwijderen etc. Zo goed hebben die 'professionele scripters' niet goed. Dus wat Santhe al zei -> SQL injection..
 
Bart V B

Bart V B

04/01/2014 18:25:41
Quote Anchor link
Klopt, SQL injection is mogelijk.
Maar dat niet alleen.
Je bent denk ik een beetje lost in de theorie. :P
Om te beginnen als ik iets zou uploaden, en dat doe ik onderweg, dan gaat mijn ip regelmatig veranderen.
Dus daar gaat het al mis. Je hebt nu iets wat zou werken als je 100% kunt zeggen het ip adres verandert nooit..
Maar dat is niet zo.

Wat werkt wel,
ga met sessions werken.
Een login systeem is handig als je op 2 dingen wil controleren. (username, password)
Maar dat wens je niet, of weet je niet hoe je dat moet maken?
Want dat is de enige manier om er voor te zorgen dat met geautoriseerd is om iets te doen.
En dan zeker niet op ip alleen controleren, maar of men is ingelogd.
O ja, en vergeet niet het uploaden zelf.
Want dat is ook heel veel controleren:
- Welk bestand formaat.
- Juiste extentie.
- bestandsgrootte.
Om zomaar wat te noemen.
 
Marco Eilander

Marco Eilander

04/01/2014 19:50:17
Quote Anchor link
@- SanThe - , doe ik dat met "mysql_escape_string" en / of zijn er nog meerdere functies die ik daar voor nodig heb? Zoja, dan ga ik mij daar verder in verdiepen betreft mysql_escape_string.

@Metal Hertog Jan, ik heb de scripters enkel mijn website gegeven, om dingen uit te proberen, en hun vertelde mij dus, dat het mogelijk was om dingen te verwijderen etc. Ze hebben niet mijn script zelf gezien.

@Bart V B, Het uploaden zelf is al zo'n beetje klaar :
- Extentie : jpg, jpeg, png, bmp, gif.
- bestandsgrootte toegestaan, minder dan : 300000.
- Alle formaten mogen, als het maar niet te groot is qua bestandsgrootte.
- de / het afbeelding krijgt een nieuwe naam. (5 characters : hoofdletters,gewone letters en cijfers)
- Er word gekeken of de naam reeks al in gebruik is.

De reden dat ik geen login systeem wou / wil, is dat het makkelijk en snel te gebruiken moet zijn.
Al is het wel handig en makkelijker om zo bij je bestanden te komen, en verdwijnen je afbeeldingen ook niet, mocht je ergens anders zijn met internet (3G of op andermans WI-FI).

Anders zal ik toch maar een login systeem eromheen moeten maken.
 
- Ariën  -
Beheerder

- Ariën -

04/01/2014 19:54:52
Quote Anchor link
Zorg er in ieder geval voor dat PHP-bestanden geweigerd worden.
Je zult vast niet de eerste zijn die d.m.v. een zgn. shell gehacked wordt.
 
Marco Eilander

Marco Eilander

04/01/2014 20:17:54
Quote Anchor link
- Aar - op 04/01/2014 19:54:52:
Zorg er in ieder geval voor dat PHP-bestanden geweigerd worden.
Je zult vast niet de eerste zijn die d.m.v. een zgn. shell gehacked wordt.



Hier een klein stukje van het uploaden :
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function generateRandomString($length = 5) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $randomString;
}


$allowedExts = array("gif", "jpeg", "jpg", "png");
$temp = explode(".", $_FILES["file"]["name"]);
$extension = end($temp);
$_FILES["file"]["name"] = str_replace($_FILES["file"]["name"], "".generateRandomString().".".$extension."", $_FILES["file"]["name"]);
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/x-png")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 300000)
&& in_array($extension, $allowedExts))
  {
  if ($_FILES["file"]["error"] > 0)
    {
    echo "Return Code: " . $_FILES["file"]["error"] . "<br>";
    }
  else

    {
 
Obelix Idefix

Obelix Idefix

04/01/2014 21:15:31
Quote Anchor link
je hebt het wel over mysql_real_escape_string, maar staat niet in de code die je laat zien.

Waarom meerdere keren require_once('config/config.php')?

Selecteer het veld/de velden die je wilt ipv *
Waar is foutafhandeling?
Wat gebeurt er nu als de query om welke reden niet lukt?
Waarom
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$ip = $_SERVER['REMOTE_ADDR'];

Het opnemen van een hidden-field is door bijna iedereen (met een beetje kennis) aan te passen. Je zou daardoor dus andere gegevens versturen via het formulier dan wat je verwacht.
Waarom werken met tabellen?
Waarom 2 formulieren, waarbij 1 geen name heeft?
Je geeft eerst een melding dat een bestand succesvol verwijderd is, terwijl je het bestand daarna pas gaat (proberen te) verwijderen.

Tot slot: ik zou overstappen op mysqli; mysql heeft zijn langste tijd gehad.
Gewijzigd op 04/01/2014 21:17:18 door Obelix Idefix
 
Marco Eilander

Marco Eilander

04/01/2014 21:40:34
Quote Anchor link
@oblix, als je nog eens goed terug leest, heb ik gezegd, wat ik weet over de gevolgen van hidden inputs...
Ik vraag er ook niet voor niks bij, of iemand een andere mogelijkheid / mogelijke optie weet.

Betreft het 2x hebben van de require_once, is, omdat ik het stukje gekopieerd heb, van het stukje dat er boven staat. En heb daarbij nog niet de require_once weg gehaald.


Het ip gebruik ik om in het database op te slaan.
De fout afhandeling staat verder helemaal onderin, aangezien die pas zichtbaar word, wanneer de afbeelding niet bestaat en / of als iemand er probeert te komen met een ip adres, dat niet overeen komt.


Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<form action="http://uplo.nl/mijnafbeeldingen" method="POST">
<input type="submit" class="btn" value="nee, terug"/>
</form>

Heeft zo ver ik weet, geen naam nodig. Aangezien het alleen maar zorgt, dat je weer terug gaat naar een andere pagina, zonder verdere benodigdheden. Daarom staan er ook niet meerdere inputs in.


Moet ik anders 1 form maken, met :

- een submit met de naam : terug
- een submit met de naam : verwijderen

Vervolgens een isset maken voor beide submits, met ieder zijn eigen werking?
Ik zal de succes verwijderd melding onder het unlink stukje plaatsen. ;)
Gewijzigd op 04/01/2014 21:43:39 door Marco Eilander
 
Obelix Idefix

Obelix Idefix

04/01/2014 21:54:37
Quote Anchor link
Je geeft aan iets gelezen te hebben over 'prutsen' met hidden fields. Zoals het er staat, heb ik niet het idee dat je er zeker van bent dat het risico's met zich meebrengt.

Waarom maak je $ip aan? Je kunt toch prima werken met $_SERVER['REMOTE_ADDR'] ?
Daarnaast is al aangegeven dat het gebruik van ip niet zo veel zegt. Het kan wisselen en wat met bv een school of bedrijf?

Foutafhandeling hoort bij het uitvoeren van het maken van een verbinding met een database en het uitvoeren van een query; stel dat het niet lukt om verbinding te maken/query uit te voeren, dan ga je met je huidige code problemen krijgen. Je controleert namelijk nergens of hetgeen jij wilt ook gebeurt.
Bouw dus foutafhandeling in.

1 Formulier lijkt mij netter/beter. Je moet nu ook al controleren welke submit is geklikt, daar verandert niet zo veel aan.

Ik zou overigens het stuk php-code naar boven verplaatsen: eerst alles in php en dan pas output leveren (o.b.v. de php).

Marco Eilander op 04/01/2014 19:50:17:
Anders zal ik toch maar een login systeem eromheen moeten maken.

Dat lijkt me de beste en (indien goed uitgevoerd de) meest veilige oplossing.
Gewijzigd op 04/01/2014 21:55:02 door Obelix Idefix
 
Local Dev

Local Dev

04/01/2014 22:34:38
Quote Anchor link
Een gebruiker identificeren mbt tot zijn/haar ip adres, is not done .. ip adressen veranderen regelmatig bij sommige aanbieders, en bij tablets en smartphones is dit totaal onbruikbaar.

Zelfde geld voor het gebruik van mac adressen, een gebruiker gebruikt niet altijd hetzelfde medium om zijn/haar uploads te bekijken/bewerken.

Laat gebruikers gewoon inloggen met gebruikersnaam/email en wachtwoord, dit is veel betrouwbaarder dan wat jij nu wilt bereiken.
 
Marco Eilander

Marco Eilander

07/01/2014 10:46:14
Quote Anchor link
Ik heb nu een login systeem gemaakt en worden de afbeeldingen opgeslagen in het database onder hun naam.
Plus : ik heb het inloggen met sessions gedaan.

Helaas heb ik nog niet echt hulp gekregen, waar ik het nodig heb.


Heb ik "mysql_real_escape_string" nodig om mijn scripts te beveiligen tegen SQL injecties?
Zoja, hoe en waar moet ik deze functie gebruiken?
 
- Ariën  -
Beheerder

- Ariën -

07/01/2014 11:15:49
Quote Anchor link
Je moet met die functie je $_POST, $_GET, en $_COOKIE variabelen beschermen als je die in je query gebruikt.
Kijk overigens direct even naar de MySQLi-functiebibliotheek i.p.v. die van MySQL. Want per 5.5 zijn deze oude MySQL-functies al bestempeld als 'uitgefaseerd'.
 
Marco Eilander

Marco Eilander

07/01/2014 15:07:20
Quote Anchor link
@ - Aar -, de reden om het in pb te vragen, was om het "on-topic" te houden.

Dit geeft mijn website aan :

> PHP 5.3.27
> MySQL Version 5.5.34
>
> Kan ik dan al wel over gaan op MySQLi?
> Ik ben inmiddels hier aan het lezen over MySQLi :
> http://www.w3schools.com/php/php_ref_mysqli.asp
 
Obelix Idefix

Obelix Idefix

07/01/2014 16:28:42
Quote Anchor link
Het is niet zo dat mysqli pas vanaf 5.5 bestaat, dus je zou nu al over kunnen op mysqli.
Maar heb je zelf al getest of mysqli werkt? Jij kunt die vraag beter beantwoorden dan wij.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.