Ik wil een update uitvoeren maar dat lukt - ineens - niet meer. Een update een minuut eerder lukte wel en toen niet meer. Ik krijg de foutmelding
"mysqli_error() expects exactly 1 argument, 0 given in C:\wamp\www\modellenEdit.php on line 44"

Eerst dacht ik dat ik verboden tekens wilde plaatsen zoals / of dat ik tekst wilde plaatsen in een kolom voor alleen cijfers, maar dat bleek niet het geval te zijn.

Hieronder een deel van het script regel 6 t/m 44.

 "{ //query samenstellen
	$queryUpdate =
        "UPDATE
            modellen
        SET
            merk = '".$_POST['merk']."',
            artikelnummer = '".$_POST['artikel']."',
            maatschappij = '".$_POST['maatschappij']."',
            soort = '".$_POST['soort']."',
            bedrijf = '".$_POST['bedrijf']."',
            reeks = '".$_POST['reeks']."',
            klasse = '".$_POST['klasse']."',
            asindeling = '".$_POST['asindeling']."',
            lengte = '".$_POST['lengte']."',
            interieur = '".$_POST['interieur']."',
            verlichting = '".$_POST['verlichting']."',
            tijdperk = '".$_POST['tijdperk']."',
            aantal = '".$_POST['aantal']."',
            railsysteem = '".$_POST['railsysteem']."',
            stroomsoort = '".$_POST['stroomsoort']."',
            wielmerk = '".$_POST['wielmerk']."',
            wieldiameter = '".$_POST['wieldiameter']."',
            wielaslengte = '".$_POST['wielaslengte']."',
            motor = '".$_POST['motor']."',
            gemotoriseerd = '".$_POST['gemotoriseerd']."',
            decoder = '".$_POST['decoder']."',
            protocol = '".$_POST['protocol']."',
            adres = '".$_POST['adres']."',
            consist_adres = '".$_POST['consistadres']."',
            bijzonderheden = '".$_POST['bijzonder']."',
            extra_informatie = '".$_POST['extra']."',
            modelinfo = '".$_POST['modelinfo']."',
            categorie = '".$_POST['categorie']."',
            afbeelding = '".$_POST['afbeelding']."',
            OVP = '".$_POST['ovp']."',
            start_set = '".$_POST['set']."'
        WHERE
            id=".$_POST['id'];
	$resultEdit = mysqli_query($db, $queryUpdate) or die("Wijzigen is niet gelukt.<br />" . mysqli_error() . "<br /> Query: " . $queryUpdate);


Is de variabele $queryUpdate leeg? Is de syntaxis van mysqli_query verkeerd?
$db is niet leeg, daar kreeg ik geen error van.
Ivo P, echt vrolijk en gerust word ik niet van welke gevaren er allemaal dreigen wanneer je de boel niet dichttimmert. Van tijd tot tijd worden we gealarmeerd als er weer eens een hack heeft plaats gevonden. Groot gelijk om voorzichtig te zijn. Het maakt natuurlijk wel verschil of je ict-werk doet voor een bedrijf of vereniging of wanneer je zoals ik puur hobbymatig voor jezelf iets in elkaar knutselt. Maar toch, ook ik zou het allesbehalve leuk vinden wanneer ik door een typefout of zo mijn hele webapplicatie in het honderd zou sturen.

Jij stelt voor een controle d.m.v. een filter_input. Dat gaat natuurlijk ook per veld, dus bij 30 velden ofwel $_POST[]'s in mijn geval is dat natuurlijk een hele klus, net als bij escapen van je input. Overigens geldt dat ook voor typecasten. Zou ik dat willen, dan zou wat Ariën suggereert nl. databasenormalisatie of 'prepared statements'een goed idee kunnen zijn.

Ik stel me een beetje gerust met:
1. De hoofdtabel bestaat uit
* velden die met een nummer verwijzen naar idnr van te koppelen tabellen;
* velden die tekst bevatten en niet verwijzen naar enige andere tabel.
2. Het veld waar het nu over gaat is een selectieveld, geen textarea. Je kunt er niks intypen of andere keuzes maken dan worden voorgelegd. Of bestaan er toch slinkse sluipwegen behalve natuurlijk na een hack rommelen in het script zelf?
3. In de textareas kan ik natuurlijk wel -1, id=0 of '12" typen, maar die zie ik dan gewoon als tekst op het scherm verschijnen. Die hebben geen invloed op de structuur van de applicatie, denk ik.
4. Werken met subqueries, daar heb ik geen kaas van gegeten. Die zal ik dus niet zo gauw toepassen, tenzij ik zoiets nodig heb om een bepaald doel te bereiken.
5. Wat ik niet heb gedaan - een vorm van "het is gemakkelijk zonder - een inlogpagina vooraf te maken, als vorm van beveiliging. Dat is denk ik toch wel belangrijk, voor het geval dat toch ... ondanks het inloggen bij Windows of zo.

[size=xsmall]Toevoeging op 29/10/2024 14:55:30:[/size]

- Ariën - op 28/10/2024 18:39:31

Dit klopt ook niet. Of ben je helderziend? Want $queryUpdate is nog niet gedefinieerd, wat daaronder gebeurt, en daarvoor wil je al weten wat erin staat?

Deze regel verplaatst na het voltooien van de Update.
if($resultEdit === TRUE)
	{
        echo "De SQL-query is: ".$queryUpdate."<br><br>
		Rij nummer".$_POST['id']." is bijgewerkt<br>\n
		<a href=\"javascript:window.close()\">Terug naar overzicht</a>";
	}

Resultaat:
De SQL-query is: UPDATE modellen SET merk = '10 ', artikelnummer = '37075', maatschappij = '6', soort = '20', bedrijf = '', reeks = '232TC 411', klasse = '4', asindeling = '24', lengte = '16.90', interieur = 'nee', verlichting = '10', tijdperk = '2', aantal = '1', railsysteem = '2', stroomsoort = '4', wielmerk = '10', wieldiameter = '0', wielaslengte = '0', motor = '4', gemotoriseerd = 'ja', decoder = '4', protocol = '5', adres = 'automatisch', consist_adres = '', bijzonderheden = '', extra_informatie = 'Oorspronkelijk Pruisisch ontwerp (T18) voor de Reichseisenbahnen in Elsaß-Lothringen. Door de SNCF werden de locomotieven geregistreerd als SNCF Serie 1-232 TC met de nummers 401 t/m 427.', modelinfo = '', categorie = '3', afbeelding = '218', OVP = '2', start_set = '0' WHERE id=202


Over je mysqli_real_escape_string() vraag:

Ik heb deze als volgt aangepast

mysqli_real_escape_string($db, $_POST['set']);

Ik krijg nu geen waarschuwing/foutmelding meer. De waarde van $_POST['set'] was "leeg" (niks opgegeven als value in de option-regel) en is een 0 geworden, ondanks de $_POST['set'] = null;. Ik denk niet dat het lukt om de waarde [i]NULL[[/u] in de database gezet te krijgen.
Het gaat er niet om wat er in jouw html-formulier ingevuld kan worden.
Iemand die kwaad wil, probeert daar niet alle waarden die jij in een pulldown plaatst, maar zet daar values naar zijn keuze in.
Dat kun je al doen door met "inspect" in de source van de pagina te rommelen.
Maar liever nog gebruikt iemand dan een speciale tool daarvoor.

Iets als Postman of Insomnia.

Voorbeeld: het ging om het als Afgehandeld markeren van een itme in een lijst. Een simpele klik op het icoontje.
Dan volgt een ajax call met een paar parameters, maar voor het gemak even 1 parameter met het id in kwestie.


Dat ene id, zeg 42, staat dan in een url, of in geval van POST in de body van de call.

https://example.com/setafgehandeld.php?id=42

Onze vriend vulde daar in zijn tool voor in:

https://example.com/afgehandeld?id=42&#32;+&#32;((SELECT&#32;FROM&#32;(SELECT&#32;SLEEP(4)))A&apos; ......)

(ter info &#32; staat voor een spatie en&apos; voor een aprostrof / quootje)

Op ..... gaat het nog even door. In elk geval gaat het om het idee: In plaats van
UPDATE tabel SET afgehandeld = 1 WHERE id = '42'
komt er nu een heel stuk extra bij, waarbij we nu alleen maar een vertraging hebben, maar ook enge dingen kunnen gebeuren.


Het vervelende is, dat je nooit meer snel dergelijke lekken kunt terugvinden: zoals hierboven cast je zelf $_POST['set'] naar een integer.
Ik ben gewend dat $_POST['set'] de onbewerkte versie is, zoals het binnenkomt.
zo behandel ik hem dan ook.

maar als je dat "altijd" zo beveiligt, dan gaat het mis als je ergens bedenkt dat ZET een betere naam is en je dat vergeet aan te passen bij het casten. Of een van de andere 10 redenen waarom dit mis zou gaan. Dan is "altijd" niet meer van toepassing.

En ook in het geval van teksten: je kunt nog zo goed aannemen dat de tekst veilig is en geen hacking kan bevatten: ook een legitieme ' in een tekst over PHP'ers kan een probleem opleveren.

En mijn voorkeur zou ook zijn om altijd prepared statements te gebruiken: het is korter en voorkomt zoektochten of iets al op een andere mnier veilig is gemaakt.
Ivo P op 29/10/2024 15:35:59

En mijn voorkeur zou ook zijn om altijd prepared statements te gebruiken: het is korter en voorkomt zoektochten of iets al op een andere manier veilig is gemaakt.


Ik heb even gekeken bij prepared statements. Interessant!!!
Voor mij is dat erg "omdenken", de vertaalslag maken van hoe ik php geleerd heb in het boek 'Basiscursus' en mijn applicatie ombouwen. Ik weet niet of ik er genoeg energie voor heb en uitdaging in zie om zo'n klus op te pakken en af te maken. Naast dit werk heb ik meer taken op mijn bord die soms veel energie vragen - wat voor doet even niet terzake = en tijd vergen.
Dat de applicatie weer werkt na de kwestie "Kan geen verbinding maken met Localhost" is al heel wat.

Hopelijk gaat het je lukken! Succes!

Reageren