is data die via ajax naar een php file gestuurd wordt via de browser manipuleerbaar?
Dit is de funcite van de counter:
Code (php)
1
2
3
4
5
6
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;
};
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)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
// count chars input
var countchars = CountCharacters();
$.ajax({
url: 'comment.php',
type: 'POST',
data: {
.......
countchars:countchars
}
var countchars = CountCharacters();
$.ajax({
url: 'comment.php',
type: 'POST',
data: {
.......
countchars:countchars
}
De check in php:
Code (php)
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
Niet als deze nog eens in PHP beperkt wordt.
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.
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
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.
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.
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
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
Overigens, js counter heb ik nu zo gemaakt:
Code (php)
1
2
3
4
5
6
7
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;
};
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)
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
En heb je ook getest waar het verschil in zit?
ik ben bang dat het verschil het gevolg is van de tinymce textarea die ik gebruik. Geen idee hoe ik ze synchroon krijg...
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?
Kan je de text niet in een console.log() opvangen? En dan vergelijken met die uit PHP.
Code (php)
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
Je kan je wel staren op het aantal, maar het verschil van de werkelijke string lijkt mij juist interessanter.
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
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
Als het aantal ergens mank loopt, dient te worden uitgezocht waar het verschil in zit.