is data die via ajax naar een php file gestuurd wordt via de browser manipuleerbaar?

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Jack Maessen

Jack Maessen

27/06/2020 13:01:03
Quote Anchor link
Voor het maximaal toegestane aantal getypte karakters in een textarea gebruik ik een counter die het aantal getypte karakters weergeeft en de waarde van die counter stuur ik via ajax naar een php file die dit serverside checkt.

Dit is de funcite van de counter:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
// counting characters textarea
function CountCharacters() {
    var body = tinymce.activeEditor.getBody();
    var content = tinymce.trim(body.innerText || body.textContent);
    return content.length;
};


In de ajax stuur ik hem op deze manier naar de php file:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
// count chars input
var countchars = CountCharacters();
$.ajax({
    url: 'comment.php',
    type: 'POST',
    data: {
               .......
               countchars:countchars
              }

De check in php:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
$countchars
= $_POST['countchars']; // countchars
$max_chars_allowed = 200;
if( $countchars > $max_chars_allowed ) {
    echo 'maximale toegestane aantal karakters overschreden';
    ......

?>

Mijn vraag is nu: is het mogelijk dat iemand (via de browserinspector) de waarde van de javascript var var countchars kan manipuleren zodat ajax een ander aantal karkaters naar de php file stuurt dan dat er in werkelijkheid getypt is in de textarea? en zodoende dus een comment kan plaatsen dat boven het toegestane aantal karakters ligt?
Gewijzigd op 27/06/2020 13:02:14 door Jack Maessen
 
PHP hulp

PHP hulp

29/03/2024 13:57:48
 
- Ariën  -
Beheerder

- Ariën -

27/06/2020 13:14:38
Quote Anchor link
Niet als deze nog eens in PHP beperkt wordt.
 
Rob Doemaarwat

Rob Doemaarwat

27/06/2020 14:59:41
Quote Anchor link
1) Ja, deze is manipuleerbaar. Dus zoals Ariën hierboven al aangeeft zul je bij het daadwerkelijk versturen van de tekst deze nogmaals op lengte moeten controleren.

2) Waarom doe je deze check niet gewoon helemaal client-side (in javascript)? Scheelt je weer een round-trip naar de server. Minder belasting op je server & snellere response voor de gebruiker.
 
Thomas van den Heuvel

Thomas van den Heuvel

27/06/2020 16:16:21
Quote Anchor link
Rob Doemaarwat op 27/06/2020 14:59:41:
2) Waarom doe je deze check niet gewoon helemaal client-side (in javascript)? Scheelt je weer een round-trip naar de server. Minder belasting op je server & snellere response voor de gebruiker.


Ik begrijp waarschijnlijk verkeerd met wat je met "helemaal client-side" bedoelt, maar is dit niet juist het probleem, dat de topicstarter (data die afkomstig is van) de gebruiker niet kan vertrouwen (en dit zou je ook nooit moeten doen), en daarom genoodzaakt is om (ook) een server-side controle uit te voeren, wat overigens altijd aan te bevelen is.

De huidige controle in PHP is ook niet goed, want zoals je zelf al aangaf kan countchars gemanipuleerd worden. Vervolgens accepteer je aan de PHP-zijde blindelings dat dit ook het daadwerkelijk aantal ingevoerde karakters is. Een betere controle is dus om het aantal karakters opnieuw te tellen aan de PHP-zijde.

Functies zoals strlen() tellen echter het aantal bytes en niet het aantal karakters, dus het is waarschijnlijk veiliger om een "multi byte aware" functie te gebruiken zoals mb_strlen().

Misschien is dit ook een uitgelezen moment om je (verder) te verdiepen in multibyte-karakters en character encoding en hoe je dit correct integreert in je site en database.
Gewijzigd op 27/06/2020 16:24:18 door Thomas van den Heuvel
 
Rob Doemaarwat

Rob Doemaarwat

27/06/2020 21:02:38
Quote Anchor link
Voor zover ik het zie wordt client-side het aantal karakters al geteld, en wordt server-side dit aantal alleen nog met de $max_chars_allowed vergeleken + evt. foutmelding. Die foutmelding zal client-side dan wel weer getoond worden.

Dan is dus alleen het *aantal karakters* naar de server gegaan. Ik heb even aangenomen dat de tekst zelf uiteindelijk ook naar de server gaat, en dan doe je uiteraard nogmaals (server-side) de lengte check.

De check tussendoor (+ evt. melding) is dus puur "een stukje informatie" naar de gebruiker toe (en niet het "eindoordeel"). Het lijkt me dus niet echt nodig om hiervoor de server lastig te vallen.
 
Thomas van den Heuvel

Thomas van den Heuvel

27/06/2020 22:25:03
Quote Anchor link
Ik neem aan dat je dit alleen serverside checkt als je daadwerkelijk klaar bent met typen en het bericht hebt vestuurd, niet dat je dit telkens opnieuw controleert tijdens het typen.

Je kunt alles aan de clientzijde manipuleren, dus op die informatie zou ik gewoon niet bouwen.

Op het moment dat iemand besluit om de JavaScript zo te manipuleren dat het maximaal aantal karakters overschreden kan worden, dan moet hij/zij dit zelf weten, maar de consequentie is dan wel dat als 'ie dit probeert te versturen dat de server het dan niet accepteert, mits de controles hiervoor niet corrumpeerbaar zijn :).

Hier tussendoor allerlei checks voor uitvoeren (die mogelijk niet betrouwbaar zijn en dus ook op een veilige manier moeten plaatsvinden) lijkt mij overbodige overhead, vooral als dit alles via AJAX loopt, zelfs al heb je dan een uiteindelijke "round-trip naar de server" dan merkt een gebruiker hier mogelijk niets van omdat deze de huidige pagina toch niet verlaat.
 
Jack Maessen

Jack Maessen

27/06/2020 22:27:22
Quote Anchor link
Ja wat ik bedoel: Ik kan de input serverside testen met strlen. En dit is ook het veiligste. Maar het probleem wat zich voordoet is dat de javascript length niet exact overeenkomt met de strlen van php. Er zit soms meer dan 10 karakters verschil tussen. Overigens, ik heb str_tags al gebruikt en ook str_replace voor karakters als &nbsp; etc. Daaroverheen ipv strlen mb_strlen gebruikt. En nog een verschil tussen js lenght en php mb_strlen. Dus toen dacht ik: gebruik 1 variable, die van js, en stuur die mee met ajax naar de php. Want wat is het geval: de counter telt af als je begint te typen. Er komt een moment dat ie aangeeft bijv: "2 karakters nog over, van de 100". Dan stop je met typen om er niet overheen te gaan en submit je. Vervolgens test php de input en zegt dat de string 103 karakters bevat. Want strlen is niet hetzelfdee als de length van javascript. Das dus lullig.
Als ik dus 1 variable gebruik, die van de js en die naar php stuur heb ik geen verschil meer. Maar...alles wat er meegestuurd wordt via ajax kan gemanipuleerd worden. Maw: manipuleer via de browserinspector dat er 50 karkaters getypt zijn, (terwijl erin werkelijkheid 150 karakters in de textarea getypt zijn) en de php loop wordt gebypassed omdat hij 50 aangeleverd krijgt om te checken.
Gewijzigd op 27/06/2020 22:38:56 door Jack Maessen
 
Thomas van den Heuvel

Thomas van den Heuvel

27/06/2020 22:43:57
Quote Anchor link
Jack Maessen op 27/06/2020 22:27:22:
Ja wat ik bedoel: Ik kan de input serverside testen met strlen. En dit is ook het veiligste.

Het veiligste? Je bedoelt dat je dit aan de serverkant opnieuw controleert? Ja, dat is altijd het verstandigste.

Jack Maessen op 27/06/2020 22:27:22:
Want wat is het geval: de counter telt af als je begint te typen.

Uhm, dat zijn dus toetsaanslagen, dat hoeft toch niet overeen te stemmen met het daadwerkelijk aantal ingetypte karakters?

Jack Maessen op 27/06/2020 22:27:22:
Er komt een moment dat ie aangeeft bijv: "2 karakters nog over, van de 100". Dan stop je met typen om er niet overheen te gaan en submit je. Vervolgens test php de input en zegt dat de string 103 karakters bevat. Want strlen is niet hetzelfdee als de length van javascript. Das dus lullig.

Een betere vraag zou dan dus zijn: hoe telt JavaScript precies (bytes of karakters) en hoe is dit verschil te verklaren?

En strlen() in PHP is dus niet de juiste functie om karakters te tellen.
Gewijzigd op 27/06/2020 22:46:18 door Thomas van den Heuvel
 
Jack Maessen

Jack Maessen

27/06/2020 22:50:49
Quote Anchor link
Klopt @Thomas. Ik heb een issue tussen de length van js en de mb_strlen van php. die zijn niet hetzelfde.
Overigens, js counter heb ik nu zo gemaakt:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
// counting characters textarea
function CountCharacters() {
    var body = tinymce.activeEditor.getBody();
    var content = tinymce.trim(body.innerText || body.textContent);
    content = content.replace(/\r\n|\r|\n/g, "\n");
    return content.length;
};

En de lengte van de userinput serverside test ik zo:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$count_chars_comment = mb_strlen(strip_tags(preg_replace("/&#?[a-z0-9]+;/i"," ",$_POST['comment']))); // length of string

Maar er blijft een verschil in lengte tussen die 2...
Gewijzigd op 27/06/2020 22:51:31 door Jack Maessen
 
- Ariën  -
Beheerder

- Ariën -

27/06/2020 22:51:32
Quote Anchor link
En heb je ook getest waar het verschil in zit?
 
Jack Maessen

Jack Maessen

27/06/2020 22:52:44
Quote Anchor link
ik ben bang dat het verschil het gevolg is van de tinymce textarea die ik gebruik. Geen idee hoe ik ze synchroon krijg...
 
Ozzie PHP

Ozzie PHP

27/06/2020 23:11:51
Quote Anchor link
Jack Maessen op 27/06/2020 22:52:44:
ik ben bang dat het verschil het gevolg is van de tinymce textarea die ik gebruik. Geen idee hoe ik ze synchroon krijg...

Door een textarea zonder tinymce te gebruiken?
 
- Ariën  -
Beheerder

- Ariën -

27/06/2020 23:13:25
Quote Anchor link
Kan je de text niet in een console.log() opvangen? En dan vergelijken met die uit PHP.
 
Jack Maessen

Jack Maessen

27/06/2020 23:57:46
Quote Anchor link
Ik gbruik nu deze, die komt het meest in de buurt van js length:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$count_chars_comment = mb_strlen(strip_tags(trim(preg_replace("/&#?[a-z0-9]+;/i"," ",$_POST['comment']))), 'UTF-8');

Het probleem zit hem nie tin plain text. 2000 karakters gekopieerd en geplakt geven allebei 2000 karakters aan. Maar als ik de emoticons van de tinymce ga gebruiken, of bold lines maak, underlines en italic teksten, dan gaat er een verschil optreden

Tja, als een politeman een lasergun op je richt en zegt dat ie 55 aflas op zijn apparaat en jouw snelheidsmeter geeft 50 aan, heb je hetzelfde probleem. Twee verschillende meetinstrumenten. Altijd misère... :)
Gewijzigd op 28/06/2020 00:04:36 door Jack Maessen
 
- Ariën  -
Beheerder

- Ariën -

28/06/2020 00:57:33
Quote Anchor link
Je kan je wel staren op het aantal, maar het verschil van de werkelijke string lijkt mij juist interessanter.
 
Thomas van den Heuvel

Thomas van den Heuvel

28/06/2020 16:14:25
Quote Anchor link
Okay. Er kan in ieder geval een verschil zijn tussen de lengte van de zichtbare, leesbare tekst en de (onzichtbare) opmaak(regels) die tinyMCE hier vervolgens aan toevoegt. Maar het zou niet nodig hoeven zijn om hier allemaal reguliere expressies op los te laten. En als je dan een controle hierop aan beide zijden op verschillende wijzen implementeert dan is het natuurlijk niet zo verwonderlijk dat de waarden afwijken.

Laten we hier eens anders naar kijken.

Wat is op dit moment de reden om de invoer te limiteren? Heeft dit echt te maken met fysieke beperkingen zoals bijvoorbeeld opslagruimte in een tabelkolom, of heeft dit een andere reden? Als er in wezen niet zo'n limitering is, dan zou je de textuele delen als *indicatie* kunnen nemen voor de lengte?
Gewijzigd op 28/06/2020 16:15:14 door Thomas van den Heuvel
 
Jack Maessen

Jack Maessen

29/06/2020 16:37:31
Quote Anchor link
Nee ik gebruik dit script niet voor mezelf. Dit is een blogsystem dat ik op Github wil plaatsen. Maar als de gebruiker een limitet op de input wil zetten, wil ik hem daartoe de mogelijkheid geven
 
- Ariën  -
Beheerder

- Ariën -

29/06/2020 17:17:06
Quote Anchor link
Jammer dat je nog geen antwoord op mijn vraag geeft. Maar zowel client-side als serverside moet je gewoon het aantal karakters controleren. Een serversidecheck is ook niet iets waar je op hoeft te besparen, want dit is toch een onwaarneembare nanoseconde of wat.....

Als het aantal ergens mank loopt, dient te worden uitgezocht waar het verschil in zit.
 



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.