Probleem met beveiligen VAN.
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)
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
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">
©2014 Uplo.nl - Alle rechten voorbehouden.
</div>
</div>
</body>
</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">
©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.
Begin eens met de query's te beveiligen. Die zijn nu lek.
'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..
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.
@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.
Je zult vast niet de eerste zijn die d.m.v. een zgn. shell gehacked wordt.
- 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.
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)
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
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
{
$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
{
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
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
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)
1
2
3
2
3
<form action="http://uplo.nl/mijnafbeeldingen" method="POST">
<input type="submit" class="btn" value="nee, terug"/>
</form>
<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
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
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.
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?
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'.
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
Maar heb je zelf al getest of mysqli werkt? Jij kunt die vraag beter beantwoorden dan wij.