Poll
image

Pick One:

maandag 2 juli 2018, 11:46 door Redactie, 31 reacties
strcpy
28.25%
strncpy
15.76%
strlcpy
10.25%
Ik snap het niet ....
40.31%
Anders, namelijk:
5.43%
Reacties (31)
02-07-2018, 12:39 door dutchfish
Nobrainer. (ik denk wel dat sommige het hier niet mee eens zullen zijn)

strlcpy

Als je dit nu nog niet begrijpt, dan ziet het er triest uit.
02-07-2018, 13:02 door MathFox - Bijgewerkt: 02-07-2018, 13:04
std::string operator = (const std::string & )
02-07-2018, 13:04 door Anoniem
https://udel.edu/~pconrad/UnixAtUD/strcpy.html
02-07-2018, 13:23 door Anoniem
Anders: ik werk in programmeertalen waar strings niet null-terminated zijn, daar is de hele discussie niet van toepassing.
02-07-2018, 14:00 door [Account Verwijderd]
Door dutchfish: Nobrainer. (ik denk wel dat sommige het hier niet mee eens zullen zijn)

strlcpy

Als je dit nu nog niet begrijpt, dan ziet het er triest uit.

Wat fijn dat iedereen die dit niet begrijpt volgens jou triest is. Lekker arrogant. Ik kan ook wel met een paar vaktermen uit mijn vakgebied gaan strooien, grote kans dat jij die niet begrijpt. Heeft niets met intelligentie te maken maar met het vakgebied dat je gekozen hebt.
02-07-2018, 14:32 door Anoniem
Door linux4:
Door dutchfish: Nobrainer. (ik denk wel dat sommige het hier niet mee eens zullen zijn)

strlcpy

Als je dit nu nog niet begrijpt, dan ziet het er triest uit.

Wat fijn dat iedereen die dit niet begrijpt volgens jou triest is. Lekker arrogant. Ik kan ook wel met een paar vaktermen uit mijn vakgebied gaan strooien, grote kans dat jij die niet begrijpt. Heeft niets met intelligentie te maken maar met het vakgebied dat je gekozen hebt.
Ja precies, helemaal mee eens!. In mijn vakgebied is AFFF heel belangrijk (dus niet opzoeken op het internet!), maar zelf uit je geheugen even vertellen wat ik bedoel..Dan kunnen we verder kijken hoe triest het is bij sommigen!
02-07-2018, 15:50 door Anoniem
"Pick one", for what? Easy exploitability, NSA resistant security?
02-07-2018, 21:51 door Anoniem
Kies voor een programmeertaal met Bounds Checking. En kies dus bij voorkeur niet voor C als het belangrijk is om buffer overflows te voorkomen. Zie https://en.wikipedia.org/wiki/Bounds_checking#Index_checking
03-07-2018, 01:07 door Anoniem
Door Anoniem: Anders: ik werk in programmeertalen waar strings niet null-terminated zijn, daar is de hele discussie niet van toepassing.

Het is bij elke programmeertaal belangrijk dat er geen bufferoverruns plaatsvinden op strings. Ook als er een automatische beveiliging is ingebouwd in de taal.

In C zou het op arrays van chars gaan om memcpy(), zonder NUL termination.

Ik gebruik zelf zelden strcpy(), meestal strncpy(), strlcpy() is niet standaard genoeg en zit niet in de meeste C-libs. strlcpy() komt uit OpenBSD.

strcpy gebruik je als je al zeker hebt gesteld dat de lengtes in orde zijn, en waar snelheid van belang is. Eigenlijk zou je die functies moeten kunnen vervangen door memcpy(). De NUL check is overbodig.

Het voordeel van standaard C lib functies is dat ze in assembler of machinetaal zijn geimplementeerd, waardoor ze erg snel zijn.
03-07-2018, 10:43 door Bitwiper
Dit helpt in elk geval niet (de middelste 3 regels heb ik ingesorongen maar die spaties verwijdert security.nl):
char* kopieerpad(char* in) {
char teruggave[81]; // paden zijn nooit langer dan 80 chars (1 extra voor de nul)
strncpy(teruggave, in, strlen(in));
return teruggave;
}
Voor de minder ervaren (C/C++) programmeurs: gebruikmaken van null-terminated strings is in veel gevallen het snelst en kost het minste geheugen. Voorwaarde is dat je niet een string waarvan je de lengte niet weet, kopieert naar een buffer (een door jou gereserveerd stukje geheugen) van vaste grootte. Want als de bron-string te lang is, wordt het geheugen achter die buffer overschreven: dit noemen we een buffer-overflow.

Als de lengte van de bron-string bepaald wordt door een gebruiker (user input, denk aan lang op het toetsenbord leunen met de cursor in een invoerveld) en je daarmee zonder checks aan de gang gaat, liggen exploits op de loer.

In het voorbeeld hierboven is "netjes" van strncpy gebruik gemaakt, maar strlen erin doet dat volledig teniet.
03-07-2018, 10:45 door Krakatau - Bijgewerkt: 03-07-2018, 10:46
Door dutchfish: Nobrainer. (ik denk wel dat sommige het hier niet mee eens zullen zijn)

strlcpy

Als je dit nu nog niet begrijpt, dan ziet het er triest uit.

Heel mooi (strlcpy) echter niet standaard: https://en.wikibooks.org/wiki/C_Programming/C_Reference/nonstandard/strlcpy. Dus toch maar strncpy en even zelf achteraf een afsluitende zero-byte schrijven in de bestemming.
03-07-2018, 11:31 door MathFox
Door Bitwiper: Dit helpt in elk geval niet (de middelste 3 regels heb ik ingesorongen maar die spaties verwijdert security.nl):
char* kopieerpad(char* in) {
char teruggave[81]; // paden zijn nooit langer dan 80 chars (1 extra voor de nul)
strncpy(teruggave, in, strlen(in));
return teruggave;
}
OOPS, je geeft een pointer naar een lokale variabele terug aan de aanroepende routine. De variabele teruggave kan door andere functies overschreven worden.
03-07-2018, 16:43 door SPer
Door Anoniem:
Door Anoniem: Anders: ik werk in programmeertalen waar strings niet null-terminated zijn, daar is de hele discussie niet van toepassing.

Het is bij elke programmeertaal belangrijk dat er geen bufferoverruns plaatsvinden op strings. Ook als er een automatische beveiliging is ingebouwd in de taal.

In C zou het op arrays van chars gaan om memcpy(), zonder NUL termination.

Ik gebruik zelf zelden strcpy(), meestal strncpy(), strlcpy() is niet standaard genoeg en zit niet in de meeste C-libs. strlcpy() komt uit OpenBSD.

strcpy gebruik je als je al zeker hebt gesteld dat de lengtes in orde zijn, en waar snelheid van belang is. Eigenlijk zou je die functies moeten kunnen vervangen door memcpy(). De NUL check is overbodig.

Het voordeel van standaard C lib functies is dat ze in assembler of machinetaal zijn geimplementeerd, waardoor ze erg snel zijn.

Ja in dit geval is natuurlijk de vraag welk antwoord ze willen, de meest veilige de meest onveilige ? het is in ieder geval zeker dat strcpy niet de meest veilige is. een opmerking van een eerder reageerder die meld dat het een nobrainer is en triest dat je het niet begrijpt zal ik maar verder niet op reageren.
03-07-2018, 20:11 door Anoniem
strlcpy lijkt me "the secure way"
03-07-2018, 23:20 door Anoniem
Mijn C programmas (en C++ programmas, op een andere manier) werken eigenlijk zoveel mogelijk met ptr/len en zo min mogelijk kopiëren van data. Data komt binnen, wordt geinspecteert, invarianten worden opgezet, en vervolgens onderhouden. Als er een string apart gehouden moet worden staat'ie al in z'n geheel in de werkbuffer en hoeft dus niet aanelkaar geknutseld te worden, alleen maar gedupliceerd. Heel de str* functiefamilie gebruik ik nauwlijks, alleen als het echt moet.
04-07-2018, 07:55 door Bitwiper - Bijgewerkt: 04-07-2018, 07:59
Door MathFox:
Door Bitwiper:
char* kopieerpad(char* in) {
char teruggave[81]; // paden zijn nooit langer dan 80 chars (1 extra voor de nul)
strncpy(teruggave, in, strlen(in));
return teruggave;
}
OOPS, je geeft een pointer naar een lokale variabele terug aan de aanroepende routine. De variabele teruggave kan door andere functies overschreven worden.
Je hebt 100% gelijk. Ik had beter bijv. de lengte terug kunnen geven in dit (sowieso onzinnige) voorbeeld. Of de pointer teruggave als parameter meegeven (en het alloceren van geheugen daarvoor de verantwoordelijkheid van de caller maken), maar dat zou het voorbeeld nog complexer maken.

Zonder iets aan jouw opmerking te willen afdoen: strings als null-terminated behandelen heeft ook een ander security risico in zich, namelijk strings die 1 of meer nul-bytes bevatten.

Een bekend voorbeeld is een certificaat met een nul-byte in de domeinnaam, zoals Dan Kaminsky en Moxie Marlinspike onafhankelijk van elkaar ontdekten en presenteerden op de Blackhat 2009 conferentie. Het lukte elk van hen (onafhankelijk van elkaar) om een certificaat te verkrijgen voor een domeinnaam zoals ing.nl0.whatever.tld, waarbij die 0 een byte is met de waarde nul. Doordat browsers die "string" parsten met str* functies, werd het een geldig certificaat voor ing.nl.

Dit soort aanvallen staan bekend als null byte injections en ook web applicaties kunnen hier kwetsbaar voor zijn, zoals o.a. https://resources.infosecinstitute.com/null-byte-injection-php/ beschrijft.

(Het kan geen kwaad om eens te checken hoe jouw implementatie van std::string operator = (const std::string & ) hiermee omgaat ;-)
04-07-2018, 11:17 door Anoniem
strlcpy en strncpy mogen volgens sommige de juiste zijn, maar naar mijn idee zijn ze dat niet. Het heeft namelijk helemaal geen zin om een string te kopieeren naar een buffer die te klein is. Controleer dus eerst of er genoeg ruimte is in *dest (of reserveer dat via alloc), en kopieer alleen als dat zo is. In dat geval is strcpy dus goed genoeg.
04-07-2018, 11:44 door Anoniem
@Bitwiper: De 'scope' in je voorbeeld was niet goed. Moeilijk/lang verhaal: https://en.wikipedia.org/wiki/Scope_(computer_science)#Function_scope

Je hebt ook nog een goede kans dat je compiler de 81 bytes op de stack gooit. Voor het aanroepen van je functie wordt de stack pointer dan verlaagd met voldoende ruimte en dat is dan je lokale array. Bij het verlaten van je functie wordt de stack pointer dan weer opgehoogd. Maar 81 bytes zou tegenwoordig geen probleem meer moeten zijn..
04-07-2018, 12:36 door Anoniem
door Bitwiper: Doordat browsers die "string" parsten met str* functies, werd het een geldig certificaat voor ing.nl.
Denk je dat dit voorkomen had kunnen worden door in browsers strl*functies te ondersteunen en te gebruiken?
04-07-2018, 12:52 door Anoniem
Door Anoniem: strlcpy en strncpy mogen volgens sommige de juiste zijn, maar naar mijn idee zijn ze dat niet. Het heeft namelijk helemaal geen zin om een string te kopieeren naar een buffer die te klein is. Controleer dus eerst of er genoeg ruimte is in *dest (of reserveer dat via alloc), en kopieer alleen als dat zo is. In dat geval is strcpy dus goed genoeg.

Dat is precies het irritante aan het gebruik van "veilige" functies. Ik doe altijd eerst dergelijke checks (zoals dat hoort) en dan is het gebruik van zo'n str*cpy functie eigenlijk nutteloos geworden, je had net zo goed memcpy kunnen gebruiken.

Het is een vorm van schijnveiligheid. Je bent pas goed met veiligheid bezig als je die functies niet meer nodig hebt. Dat is het paradoxale.

@Gisteren, 23:20 door Anoniem
Inderdaad, respect voor je inzicht. Pointers zijn meestal ook het snelste. Het voordeel is laag geheugengebruik en snelheid. Je kunt bijvoorbeeld ook met pointers sorteren zonder de data te kopieren. Je moet dan wel goed controle houden over de lengte. En het is niet voor iedereen te volgen.

In het algemeen schrijf ik code die door ieder mens met een beetje kennis te volgen is. Dat is voor mij een vereiste want er is geen tijd om puzzels op te lossen bij acute security dreigingen. Ik heb een broertje dood aan programmeurs die onleesbare code gebruiken.
04-07-2018, 17:47 door Bitwiper - Bijgewerkt: 04-07-2018, 17:52
Door Anoniem: strlcpy en strncpy mogen volgens sommige de juiste zijn, maar naar mijn idee zijn ze dat niet. Het heeft namelijk helemaal geen zin om een string te kopieeren naar een buffer die te klein is. Controleer dus eerst of er genoeg ruimte is in *dest [...]
Als *dest van het type char* is en jij hier niet zelf geheugen voor gealloceerd hebt, kun je nergens aan zien hoe groot die buffer is. Het misschien wel grootste probleem van C strings is dat bij normaal gebruik strings nooit langer worden dan een specifieke lengte, maar dat een aanvaller een mogelijkheid ontdekt om een langere string aan te bieden.

@Anoniem 11:44: eens.

Door Anoniem:
door Bitwiper: Doordat browsers die "string" parsten met str* functies, werd het een geldig certificaat voor ing.nl.
Denk je dat dit voorkomen had kunnen worden door in browsers strl*functies te ondersteunen en te gebruiken?
Uit https://www.freebsd.org/cgi/man.cgi?query=strlcpy&sektion=3&manpath=FreeBSD+11.2-RELEASE+and+Ports:
strlcpy() copies up to dstsize - 1 characters from the string src to dst, NUL-terminating the result if dstsize is not 0.
Dat lijkt te suggereren dat het om een memcpy gaat die gegarandeerd voor een terminating zero zorgt (tenzij dstsize 0 is). Echter het gaat hier om C strings en die zijn null-terminated. Daardoor kun je "up to" ook zo uitleggen dat deze stopt na het kopiëren van een nul-byte, en -discutabel- is dat het juiste gedrag.

Vandaar ook mij laatste opmerking voor Mathfox: de implementor van operator = kan als "service" voor code met mixed C en "stringclass strings" functionaliteit hebben toegevoegd die stopt nadat er een nul-byte is gekopieerd.

Het is lastig te zeggen wiens schuld het "verkeerd omgaan" met een 0 halverwege een string is. Daarmee is het geen C-string, want die zijn null-terminated. Een nul-byte is ook geen legaal karakter in een domeinnaam, dus browsermakers kun je het niet verwijten als zij str* functies voor het verwerken ervan gebruiken. Het probleem is dat nul-bytes halverwege values in ASN.1 structuren wel zijn toegestaan en dus getransporteerd worden van cybercrimineel naar de browser van de eindgebruiker. Feitelijk is de aanvrager van het certificaat fout omdat hij een illegaal karakter in een domeinnaam gebruikt (maar wat kun je verwachten van cybercriminelen en security-onderzoekers die op exploits wijzen), en de certificaatverstrekker zou je fout kunnen noemen omdat deze niet heeft gecontroleerd of de domeinnaam uitsluitend uit toegestane karakters bestond.

Kortom, niet zozeer de str* functies maar null-terminated strings kunnen ondingen zijn als je geen rekening houdt met hun beperkingen. Helaas kom je er niet of nauwelijks omheen als je Windows of Linux programma's schrijft, en bovendien heb je bij tijdkritische programma's niet de ellende van full stops veroorzaakt door garbage collectors.
04-07-2018, 19:08 door Anoniem
17:47 door Bitwiper: ok thanks. Het gaat om CVE-2009-2408 zie ik, zo te zien in nss (network security services)

Wat mij nog wel opviel is
https://bugzilla.mozilla.org/show_bug.cgi?id=639220

Dit gaat dus over een aanpassing van strcpy naar het robuustere strlcpy in nsframe.cpp van Firefox 3.5 (.16).

Het ziet er niet naar uit dat het de oplossing was voor die Blackhat bug,
maar blijkbaar heeft Chen Liu nog eens goed gekeken, en deze "minder sterke punten" in NSS ook nog gevonden,
nadat eerder in Firefox 3.5(.2?) het Blackhat probleem al was opgelost.
05-07-2018, 15:32 door Anoniem
Door Anoniem: Mijn C programmas (en C++ programmas, op een andere manier) werken eigenlijk zoveel mogelijk met ptr/len en zo min mogelijk kopiëren van data. Data komt binnen, wordt geinspecteert, invarianten worden opgezet, en vervolgens onderhouden. Als er een string apart gehouden moet worden staat'ie al in z'n geheel in de werkbuffer en hoeft dus niet aanelkaar geknutseld te worden, alleen maar gedupliceerd. Heel de str* functiefamilie gebruik ik nauwlijks, alleen als het echt moet.
Strlcpy is dan ook in de eerste plaats in het leven geroepen om het minder robuuste strcpy en strncpy in reeds geschreven software te vervangen, en in de toekomst te gebruiken waar je anders genoemde oude functies zou gebruiken.
05-07-2018, 16:04 door johanw - Bijgewerkt: 05-07-2018, 16:13
Door Bitwiper: Dit helpt in elk geval niet (de middelste 3 regels heb ik ingesorongen maar die spaties verwijdert security.nl):
char teruggave[81]; // paden zijn nooit langer dan 80 chars (1 extra voor de nul)
Afgezien van alle andere commentaar: tenzij je nog onder DOS programmeert kunnen onder windows UNC paden tegenwoordig veel langer zijn, en onder Unix achten kon dat al veel eerder.
05-07-2018, 19:13 door Anoniem
Door Bitwiper:
Als *dest van het type char* is en jij hier niet zelf geheugen voor gealloceerd hebt, kun je nergens aan zien hoe groot die buffer is.
Hoe kan je een char* hebben waar je naar wil schrijven waar je niet de grootte van weet?!? En daarbij, als je de grootte niet weet, dan heb je ook niks aan strncpy en strlcpy. Beetje vreemde opmerking dus.
05-07-2018, 19:50 door Bitwiper
Door johanw:
Door Bitwiper: Dit helpt in elk geval niet (de middelste 3 regels heb ik ingesorongen maar die spaties verwijdert security.nl):
char teruggave[81]; // paden zijn nooit langer dan 80 chars (1 extra voor de nul)
Afgezien van alle andere commentaar: tenzij je nog onder DOS programmeert kunnen onder windows UNC paden tegenwoordig veel langer zijn, en onder Unix achten kon dat al veel eerder.
Weet ik, een kopieertool die ik in ca. 1999 schreef voor onder NT4 kan, voor zover er vrij geheugen is, onbeperkt lange paden aan. In het voorbeeld heb ik bewust 80 gebruikt (en geen 2048 o.i.d) omdat Bill Gates ongetwijfeld gezegd heeft dat dit voor altijd genoeg zou zijn, en natuurlijk om de kans op buffer overflows realistisch te laten zijn. Helaas kom ik dit soort code af en toe nog tegen (welliswaar niet met 80 maar bijv. met MAXPATH).

De ontwikkelaars van Sharepoint lijken trouwens nog steeds op MAXPATH (256 meen ik) te zijn blijven steken. Niet dat ik buffer overflows gezien heb, maar langere paden geven foutmeldingen of andere irritante problemen:-(

Ow wacht, het zou sinds vorig jaar maar liefst 5 x 80 zijn (zie https://blogs.technet.microsoft.com/wbaer/2017/05/09/new-maxpath-limits-in-sharepoint-and-onedrive/) - wat m.i. nog steeds veel te kort is als jouw gebruikers leesbare en zelf-verklarende map- en bestandsnamen wensen te gebruiken - hetgeen m.i. voor de hand ligt in een muis-klik OS omgeving...
05-07-2018, 21:50 door Anoniem
Door Krakatau:
Door dutchfish: Nobrainer. (ik denk wel dat sommige het hier niet mee eens zullen zijn)

strlcpy

Als je dit nu nog niet begrijpt, dan ziet het er triest uit.

Heel mooi (strlcpy) echter niet standaard: https://en.wikibooks.org/wiki/C_Programming/C_Reference/nonstandard/strlcpy. Dus toch maar strncpy en even zelf achteraf een afsluitende zero-byte schrijven in de bestemming.
Libraries zijn er om te worden gebruikt.

Maar weet je wat het is met strlcpy, het is aan de ene kant veiliger omdat het zaken uit handen van de programmeur neemt en de dingen die het moet doen automatisch perfect doet met de juiste stringlengte, maar dat betekent anderzijds dat de programmeur uit het oog kan verliezen wat nou juiste stringlengte is van een bepaalde string.

Het effect van C-programmeurs die niet meer met zekerheid weten wat de stringlengte van de strings is
kan vervolgens leiden tot andere fouten. Dus perfect is strlcpy ook niet als we even deze menselijke factor meenemen in de beoordeling.
06-07-2018, 15:50 door Anoniem
Door Anoniem: Het is bij elke programmeertaal belangrijk dat er geen bufferoverruns plaatsvinden op strings. Ook als er een automatische beveiliging is ingebouwd in de taal.
Natuurlijk, maar dan heb je het over bugs in de implementatie van de compiler of interpreter van de taal zelf. Een programmeur in zo'n taal heeft niets met strcpy, strncpy of strlcpy te maken, en in die context is de hele discussie over welke functie je voorkeur heeft niet van toepassing. Daar sloeg mijn "anders" op.
08-07-2018, 23:18 door Anoniem
Jammer dat dir niet in het lijstje stond!
09-07-2018, 13:30 door Anoniem
Door Anoniem:
Door linux4:
Door dutchfish: Nobrainer. (ik denk wel dat sommige het hier niet mee eens zullen zijn)

strlcpy

Als je dit nu nog niet begrijpt, dan ziet het er triest uit.

Wat fijn dat iedereen die dit niet begrijpt volgens jou triest is. Lekker arrogant. Ik kan ook wel met een paar vaktermen uit mijn vakgebied gaan strooien, grote kans dat jij die niet begrijpt. Heeft niets met intelligentie te maken maar met het vakgebied dat je gekozen hebt.
Ja precies, helemaal mee eens!. In mijn vakgebied is AFFF heel belangrijk (dus niet opzoeken op het internet!), maar zelf uit je geheugen even vertellen wat ik bedoel..Dan kunnen we verder kijken hoe triest het is bij sommigen!
Dan weet ik in iedergeval dat wanneer dit gebruikt word bij mijn bedrijf, alles kapot is en niet meer te repareren valt. Behalve het gebouw zelf ;)
09-07-2018, 13:31 door Anoniem
Ik ben meer van de leesbare programmeertalen ;) Copy in Pascal of Pythons .copy()
Reageren

Deze posting is gelocked. Reageren is niet meer mogelijk.