Toon posts:

[Forumgame] Vind de kwetsbaarheid!

Pagina: 1 2 Laatste
Acties:

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-11 14:08
@ChessSpider
Je wilt beweren dat die code een XSS-lek bevat :?

Je zou hoogstens page als array kunnen inkoppen, waardoor htmlentities een foutmelding geeft. Maar dat is geen exploit.

[ Voor 49% gewijzigd door frickY op 16-05-2008 23:58 ]


  • Patriot
  • Registratie: December 2004
  • Laatst online: 20:16

Patriot

Fulltime #whatpulsert

frickY schreef op vrijdag 16 mei 2008 @ 23:56:
@ChessSpider
Je wilt beweren dat die code een XSS-lek bevat :?

Je zou hoogstens page als array kunnen inkoppen, waardoor htmlentities een foutmelding geeft. Maar dat is geen exploit.
Een array via GET? Kan dat?

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-11 14:08
Geen probleem;

probeermaar.php
PHP:
1
2
3
<?php
print_r($_GET);
?>


Resultaa van probeermaar.php?var%5B%5D=waarde1&var%5B%5D=waarde2
code:
1
2
3
4
5
6
7
8
Array
(
    [var] => Array
        (
            [0] => waarde1
            [1] => waarde2
        )
)

5B en 5D zijn de hexwaarden voor square brackets

[ Voor 82% gewijzigd door frickY op 17-05-2008 00:08 ]


  • ChessSpider
  • Registratie: Mei 2006
  • Laatst online: 29-09 19:35
frickY schreef op vrijdag 16 mei 2008 @ 23:56:
@ChessSpider
Je wilt beweren dat die code een XSS-lek bevat :?

Je zou hoogstens page als array kunnen inkoppen, waardoor htmlentities een foutmelding geeft. Maar dat is geen exploit.
Yup, XSS lek.
Tip; character encoding.

Deze lek zal niet voor iedereen werken. Zo heb je bijvoorbeeld een IE browser nodig waarbij (Character-)Encoding op Auto-Select staat. Bij mij lukte het niet om IE8 op auto-select te zetten, maar wel op IE7. Als je wilt kan je hier testen;

http://chessspider.no-ip.info/blaat.php?

[ Voor 29% gewijzigd door ChessSpider op 17-05-2008 00:06 ]


  • Patriot
  • Registratie: December 2004
  • Laatst online: 20:16

Patriot

Fulltime #whatpulsert

ChessSpider schreef op zaterdag 17 mei 2008 @ 00:04:
[...]


Yup, XSS lek.
Tip; character encoding.

Deze lek zal niet voor iedereen werken. Zo heb je bijvoorbeeld een IE browser nodig waarbij (Character-)Encoding op Auto-Select staat. Bij mij lukte het niet om IE8 op auto-select te zetten, maar wel op IE7. Als je wilt kan je hier testen;

http://chessspider.no-ip.info/blaat.php?
WTF! Dat is een goeie, dát wist ik niet.

EDIT: Wacht.. waarom werkt het op mijn localhost niet..\

EDIT: -- Nog even niet --

[ Voor 44% gewijzigd door Patriot op 17-05-2008 00:12 ]


  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

Patriot schreef op zaterdag 17 mei 2008 @ 00:00:
[...]


Een array via GET? Kan dat?
Sure:

code:
1
blaat.php?array[meuk]=kwaak&array[]=blaat&array[]=woei


geeft:

PHP:
1
2
3
4
5
print_r($_GET['array']);
/* 
Array ( 'meuk'=> 'kwaak',
0 => 'blaat'
1 => 'woei') */

[/ te laat ]

Stop uploading passwords to Github!


  • ChessSpider
  • Registratie: Mei 2006
  • Laatst online: 29-09 19:35
Patriot schreef op zaterdag 17 mei 2008 @ 00:07:
[...]


WTF! Dat is een goeie, dát wist ik niet.

EDIT: Wacht.. waarom werkt het op mijn localhost niet..
Wacht nog even met zeggen ;)

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

ChessSpider schreef op zaterdag 17 mei 2008 @ 00:11:
[...]


Wacht nog even met zeggen ;)
laat me raden... local intranet zone? :P

Stop uploading passwords to Github!


  • ChessSpider
  • Registratie: Mei 2006
  • Laatst online: 29-09 19:35
SchizoDuckie schreef op zaterdag 17 mei 2008 @ 00:17:
[...]

laat me raden... local intranet zone? :P
Neej, ga even zoeken gast :)

  • Patriot
  • Registratie: December 2004
  • Laatst online: 20:16

Patriot

Fulltime #whatpulsert

Sorry, maar ik ga het nu toch echt (sortof) verklappen (dat is uiteindelijk ook gewoon de bedoeling ;)).
Ik snap dat het komt door de character encoding. Wat ik echter niet begrijp is waarom het niet in Fx werkt. Het komt er toch op neer dat als je de page-variabele als UTF-8 verstuurd, htmlentities() deze niet escaped?

  • ChessSpider
  • Registratie: Mei 2006
  • Laatst online: 29-09 19:35
Patriot schreef op zaterdag 17 mei 2008 @ 00:29:
Sorry, maar ik ga het nu toch echt (sortof) verklappen (dat is uiteindelijk ook gewoon de bedoeling ;)).
Ik snap dat het komt door de character encoding. Wat ik echter niet begrijp is waarom het niet in Fx werkt. Het komt er toch op neer dat als je de page-variabele als UTF-8 verstuurd, htmlentities() deze niet escaped?
Als IE7 in de eerste 4096 characters een UTF-7 encoded string vind, terwijl er geen character encoding word meegestuurd, maakt hij er automatisch UTF-7 van.
De htmlentities() weet niet dat de character encoding als UTF-7 word gezien, dus die ziet letterlijk dit voorbij komen:
code:
1
+ADw-script+AD4-alert(document.location)+ADw-/script+AD4-

Daar gaat hij niks escapen, en word het zo naar de browser gestuurd. IE herkent het als UTF-7, en veranderd de character encoding accordingly.

Dit kan natuurlijk alleen als:
Er geen character encoding is meegegeven
Character encoding op auto-select staat

Probeer bovenstaande tekst te kopieren en te plakken in de voorbeeld. Als het goed is krijg je dan een alertbox te zien met de URL. Je kan het ook forceren; bijvoorbeeld door in FireFox naar de URL te gaan, en dan handmatig de character encoding op UTF-7 te zetten.


Fx verandert dus niet zijn encoding opeens naar UTF-7.

Hier nog een voorbeeld en wat uitleg, waar ik mijn voorbeeld ook grotendeels van heb gestolen:
http://shiflett.org/blog/2005/dec/google-xss-example

[ Voor 7% gewijzigd door ChessSpider op 17-05-2008 00:38 ]


  • Patriot
  • Registratie: December 2004
  • Laatst online: 20:16

Patriot

Fulltime #whatpulsert

ChessSpider schreef op zaterdag 17 mei 2008 @ 00:35:
[...]


Als IE7 in de eerste 4096 characters een UTF-7 encoded string vind, terwijl er geen character encoding word meegestuurd, maakt hij er automatisch UTF-7 van.
De htmlentities() weet niet dat de character encoding als UTF-7 word gezien, dus die ziet letterlijk dit voorbij komen:
code:
1
+ADw-script+AD4-alert(document.location)+ADw-/script+AD4-

Daar gaat hij niks escapen, en word het zo naar de browser gestuurd. IE herkent het als UTF-7, en veranderd de character encoding accordingly.

Dit kan natuurlijk alleen als:
Er geen character encoding is meegegeven
Character encoding op auto-select staat

Probeer bovenstaande tekst te kopieren en te plakken in de voorbeeld. Als het goed is krijg je dan een alertbox te zien met de URL. Je kan het ook forceren; bijvoorbeeld door in FireFox naar de URL te gaan, en dan handmatig de character encoding op UTF-7 te zetten.
Hmm, nou, het is een aparte. Anyway, ik zal hem niet vaak tegenkomen omdat ik sowieso een charset meestuur.

  • user109731
  • Registratie: Maart 2004
  • Niet online
Er staat er geeneen meer open, dus maar een nieuwe. Een sprintf-like functie om query parameters te escapen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function format_query() {
    $args = func_get_args();
    if(count($args) == 0)
        die('error');

    $query = array_shift($args);
    $expected_args = substr_count($query, '?');

    if(count($args) != $expected_args) {
        printf('expected %d args, but got %d', $expected_args, count($args));
        exit();
    }
    foreach($args as $arg) {
        // replace next ? with next argument
        $arg = my_escape($arg); // my_escape is safe for all input
        $query = preg_replace('#\?#', $arg, $query, 1);
    }
    return $query;
}

Kan zo gebruikt worden:
PHP:
1
$sql = format_query("SELECT * FROM table WHERE x = '?' AND y = ?", "foo", 5);

Iemand? :)

[ Voor 10% gewijzigd door user109731 op 17-05-2008 08:52 ]


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

doordat die my_escape lokaal op 1 argument werkt weet je niet of de query zelf ' ' bevat.
(zie voorbeeld: x = '?' en y = ?)

Daardoor kun je denk'k alsnog SQL-injection doen.

(ik ken helemaal de ballen van php, dus ik blaat maar wat aan)

Next?
C++:
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
class CFixedSizeString
{
  public:
     CFixedSizeString(const std::string& str)
     {
        if (strlen(str.c_str()) > 255)
           throw "badly sized string";
        strncpy(buffer, str.data(), str.size());
     }
     bool operator<(const CFixedSizeString& right) { return strcmp(buffer, right.buffer) < 0; }
     virtual void print() { std::cout << buffer; }
     virtual ~CFixedSizeString() { }
  private:
    char buffer[256];
};

int main()
{
  std::set<CFixedSizeString> strings;
  std::string str;
  CFixedSizeString fsstr;
  std::cin >> str;
  while (str != "")
  {
    fsstr = CFixedSizeString(str)
    strings.insert(fsstr);
    std::cin >> str;
  }
  std::cout << "Unieke woorden: " << std::endl;
  for (std::set<CFixedSizeString>::iterator it = strings.begin(), end = strings.end(); it != end; ++it)
  {
    it->print();
    std::cout << std::endl;
  }
  return 0;
}


edit: bugfix :P

ASSUME makes an ASS out of U and ME


  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 19:30

Sebazzz

3dp

Je returned niet uit main() dus deze zal zowieso niet compilen.

@hieronder: Het is in ieder geval een goede gewoonte om het te doen. Je hoeft in HTML4 sommige tags niet af te sluiten, maar het is ook een goede gewoonte om dat te doen :)

[ Voor 58% gewijzigd door Sebazzz op 17-05-2008 10:03 ]

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

afhankelijk van welke compiler en hoe streng de opties staan, that is.
Normaal wordt 0 gereturned als er niets staat.

Heb het even toegevoegd, maar daar zit het probleem niet.

@hierboven: gelukkig is het niet uit gewoonte maar was ik het gewoon even vergeten ;)

[ Voor 34% gewijzigd door H!GHGuY op 17-05-2008 10:07 ]

ASSUME makes an ASS out of U and ME


  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
H!GHGuY schreef op zaterdag 17 mei 2008 @ 09:54:
(ik ken helemaal de ballen van php, dus ik blaat maar wat aan)
.data() geeft een string die niet null-terminated is terwijl strcmp dat wel verwacht, waar door 'ie over je boundries gaat. Zou verder niet weten hoe je er een exploit voor maakt.

PS. je hebt een virtual void ~CFixedSizeString dus 't compiled sowieso niet.

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

PrisonerOfPain schreef op zaterdag 17 mei 2008 @ 10:26:
[...]


.data() geeft een string die niet null-terminated is terwijl strcmp dat wel verwacht, waar door 'ie over je boundries gaat. Zou verder niet weten hoe je er een exploit voor maakt.

PS. je hebt een virtual void ~CFixedSizeString dus 't compiled sowieso niet.
Je hebt een 2de bug gevonden, hoewel dit niet die is die ik zoek. Ik kon er even goed strncmp van maken met n=256.
Je bent echter wel op de goede weg.

Voorbeeldje heb ik niet door een compiler gehaald of getest, er kunnen dus idd foutjes zoals die destructor in staan, ik corrigeer het even.


Na even grondig denken over mijn voorbeeld heb ik een aanpassing moeten maken omdat ik even fout zat...

[ Voor 9% gewijzigd door H!GHGuY op 17-05-2008 11:37 ]

ASSUME makes an ASS out of U and ME


  • Cartman!
  • Registratie: April 2000
  • Niet online
Patriot schreef op vrijdag 16 mei 2008 @ 22:36:
[...]


Je levert zelf anders ook wel erg weinig context hoor. Je wil gewoon zeggen dat men dingen moet escapen, maar sommige dingen hoef je echt niet te escapen. Als je als developer de gebruikte variabele declareert is het niet nodig (mits er geen tekens in staan die de boel opfucken), en zéker geen exploit.

EDIT:

En wat SchizoDuckie bedoelt is dat je impliceert dat het één bepaald type is, terwijl het zomaar een ander type zou kunnen zijn (maar daar ben je zelf bij I guess).
Het gaat niet zozeer om het escapen dus want als je die waarde zelf samenstelt en je weet dat daar geen onveilige karakters inzitten is er geen probleem. Valt me tegen dat niemand het ziet eigenlijk. Als je een hash geeft aan een entry in een database dan moet je eerst checken of die hash er al niet is... De kans op collisions is niet heel groot maar zeker aanwezig. 2 entries met dezelfde hashes kan een hoop problemen opleveren (kijk bijv. naar youtube die de hash uit de url gebruikt als id).

Nog een keer de code:

PHP:
1
2
3
4
5
6
7
$strSql = '
    INSERT INTO
        video
    SET
        filename = "' . $strFilename . '",
        hash = "' . sha1(time()) . '"
    ';


En over het prefixen: bij ons op t werk is het een code standaard. Iedereen houdt zich daar keurig aan en dat is echt handig tijdens het doorkijken van een script.

[ Voor 6% gewijzigd door Cartman! op 17-05-2008 11:41 ]


  • Cavorka
  • Registratie: April 2003
  • Laatst online: 27-03-2018

Cavorka

Internet Entrepreneur

Cartman! schreef op zaterdag 17 mei 2008 @ 11:41:
[...]
PHP:
1
2
3
4
5
6
7
$strSql = '
    INSERT INTO
        video
    SET
        filename = "' . $strFilename . '",
        hash = "' . sha1(time()) . '"
    ';
Zonder user input (hetzij via _POST, of via _GET) valt er natuurlijk weinig te exploiten... :) Maar misschien zie ik hier gewoon niet veel in, alleen een query is misschien iets te abstract.

Enige wat ik kan verzinnen is dat dit niet handig is en dat je misschien beter dit kan doen:
code:
1
sha1(time() .  $strFilename)

the-blueprints.com - The largest free blueprint collection on the internet: 50000+ drawings.


  • Cartman!
  • Registratie: April 2000
  • Niet online
Het probleem is dat je dan nog steeds duplicates kunt krijgen in je database en dat wil je niet. Dus gewoon een functie maken die een hash genereert, checkt of ie niet voorkomt en als dat zo is recursief zichzelf aanroepen om een nieuwe te maken totdat je een unieke hebt. Je gaat toch ook geen nieuwsberichten hetzelfde id geven?

  • EdwinG
  • Registratie: Oktober 2002
  • Laatst online: 22:31
Cartman! schreef op zaterdag 17 mei 2008 @ 12:57:
Het probleem is dat je dan nog steeds duplicates kunt krijgen in je database en dat wil je niet. Dus gewoon een functie maken die een hash genereert, checkt of ie niet voorkomt en als dat zo is recursief zichzelf aanroepen om een nieuwe te maken totdat je een unieke hebt. Je gaat toch ook geen nieuwsberichten hetzelfde id geven?
Het probleem is dat met jouw voorbeeld niet direct duidelijk is waar de gemaakte hash voor dient. En het kan net zo goed zijn dat je daarnaast nog een kolom met auto_increment als primary key gebruikt.

Bezoek eens een willekeurige pagina


  • Cartman!
  • Registratie: April 2000
  • Niet online
Maar dan nog, bij Youtube zal iedere video vast een id hebben maar je krijgt deze gepresenteert adhv. de hash. Als een hash niet uniek hoeft te zijn dan heb je er niks aan in een database imo, tenzij deze als checksum dient.

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 19:30

Sebazzz

3dp

Als je unieke hashes wilt moet je natuurlijk met microtime of iets dergelijks gaan werken. De kans dat je twee gelijke hashes krijgt...

@hieronder: Wel volgens mijn C++ boek (C++ Grand Cru, Steve nogwat)

[ Voor 20% gewijzigd door Sebazzz op 17-05-2008 14:36 ]

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:10

.oisyn

Moderator Devschuur®

Demotivational Speaker

Sebazzz schreef op zaterdag 17 mei 2008 @ 09:59:
Je returned niet uit main() dus deze zal zowieso niet compilen.
main() behoeft geen return statement. Maar de return-type is wel altijd int.
@hieronder: Het is in ieder geval een goede gewoonte om het te doen
Waarom? main() is sowieso een special case (main() mag bijvoorbeeld ook niet aangeroepen worden door eigen code). 'return x' is in feite hetzelfde als 'exit(x)'. Waarom is dát dan geen goede gewoonte om neer te zetten? Als je een return-waarde onzinnig vind maak je 'm void, dat mag bij main() helaas niet. En in main() is geen return is hetzelfde als return 0 - iedere fatsoenlijke C++er weet dat :)

H!GHGuY: de bug is dat CFixedString::buffer nooit wordt afgesloten met een terminating 0. Je had gewoon strcpy() moeten gebruiken ipv strncpy(), wat mogelijk is omdat je de lengte daarvoor toch controleert.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

.oisyn schreef op zaterdag 17 mei 2008 @ 14:05:
[...]

main() behoeft geen return statement. Maar de return-type is wel altijd int.


[...]

Waarom? main() is sowieso een special case (main() mag bijvoorbeeld ook niet aangeroepen worden door eigen code). 'return x' is in feite hetzelfde als 'exit(x)'. Waarom is dát dan geen goede gewoonte om neer te zetten? Als je een return-waarde onzinnig vind maak je 'm void, dat mag bij main() helaas niet. En in main() is geen return is hetzelfde als return 0 - iedere fatsoenlijke C++er weet dat :)

H!GHGuY: de bug is dat CFixedString::buffer nooit wordt afgesloten met een terminating 0. Je had gewoon strcpy() moeten gebruiken ipv strncpy(), wat mogelijk is omdat je de lengte daarvoor toch controleert.
er zit wel een terminating 0 in hoor ;) kijk nog maar eens goed...

Ik ben echter niet helemaal zeker dat het voorbeeld 100% klopt, maar mits minimale aanpassingen moet het toch zeker lukken...

Verklap'k em ?

[ Voor 7% gewijzigd door H!GHGuY op 17-05-2008 14:39 ]

ASSUME makes an ASS out of U and ME


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Ik kan er grandioos naast zitten, maar de redenering is zo:

je buffer moet je zo construeren:
code:
1
2
3
4
5
0:[256karakters zonder whitespace met minstens 1 \0 karakter - kan exploit code bevatten]
256:[vptr wijst naar 260]
260:[vptr0 wijst naar 268 of 0]
264:[vptr1 wijst naar 268 of 0]
268:[exploit code]


inlezen van een std::string kijkt naar EOF of whitespace. NUL-karakters worden afaik gewoon mee ingelezen.
strlen leest tot de eerste NUL-byte, str.data geeft alle data + bijhorende .size() (groter dan de strlen)
dus je kopieert over de vptr pointer. Doordat de initiele CFixedSizeString op de stack staat kun je de offsets daarvan gebruiken om tijdens de laatste inleesopdracht je code te injecteren met gekende offsets.

Door uiteindelijk de print() opdracht op te roepen jump je naar je exploit code.

Ik vermoed echter dat de set pointers naar CFixedSizeString zal moeten bevatten of anders wordt tijdens de copy-constructor actie de vptr van het geinserteerde object juist gezet.

ASSUME makes an ASS out of U and ME


  • Patriot
  • Registratie: December 2004
  • Laatst online: 20:16

Patriot

Fulltime #whatpulsert

Cartman! schreef op zaterdag 17 mei 2008 @ 13:35:
Maar dan nog, bij Youtube zal iedere video vast een id hebben maar je krijgt deze gepresenteert adhv. de hash. Als een hash niet uniek hoeft te zijn dan heb je er niks aan in een database imo, tenzij deze als checksum dient.
Dat zal allemaal gerust zo zijn hoor, maar niks van dit alles is uit de code te halen die jij geeft. Je geeft alleen de declaratie van een variabele, dat het een query betreft impliceert dan nog dat je het waarschijnlijk uit zou voeren maar dan houdt het toch echt wel op..

De fout is volgens jou dat er niet gekeken word of die hash al bestaat, maar uit je voorbeeld is onmogelijk te halen dat de hash uniek moet zijn. En dat een hash die niet uniek hoeft te zijn niet nuttig is, is ook niet waar. Je komt ze bijvoorbeeld vaak tegen in gebruikerssystemen. Een gebruiker die zijn wachtwoord is vergeten krijgt dan vaak een hash toegestuurd via de mail, waarna hij op een pagina alleen zijn wachtwoord kan veranderen als de hash klopt.

Je voorbeeld is leuk geprobeerd, maar helaas te abstract en ik kan me ook niet voorstellen dat het echt een exploit is.

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Cartman! schreef op zaterdag 17 mei 2008 @ 12:57:
Het probleem is dat je dan nog steeds duplicates kunt krijgen in je database en dat wil je niet. Dus gewoon een functie maken die een hash genereert, checkt of ie niet voorkomt en als dat zo is recursief zichzelf aanroepen om een nieuwe te maken totdat je een unieke hebt. Je gaat toch ook geen nieuwsberichten hetzelfde id geven?
Op die manier kan het nog steeds mis gaan. Twee users submitted verschillende files met toevallig dezelfde hash waarde. Eerste process queried de database of er duplicates zijn en vindt die niet. Op dat moment kicked het tweede process in, queried ook de database, en vindt ook geen duplicates. Vervolgens gaan ze allebei lekker insert queries draaien, en voila, een duplicate hash.

maw. je moet dan een atomic query maken die eerst select en dan conditioneel insert. Maar dan moet je nieuwe hashes kunnen genereren en loopen in je query: niet handig. Dus moet je je database locken gedurende de tijd dat je select/insert script draait. Dan kan je je site DoS-en door heel veel files te submitten ;)

concurrency exploits zijn natuurlijk ook leuk. Ik kan me wel iets indenken dat een Os een syncrhonized multiple producer/consumer buffer bijhoudt als event queue, maar dat op de simpelete manier met twee semaphores doet. Ik heb geen zin om een voorbeeld te geven, dat wordt te ingewikkeld. Het idee is in ieder geval dat je door een race-conditie naar hetzelfde slot kan schrijven als een ander process, en zo priviliged events zou kunnen faken ....

[ Voor 32% gewijzigd door Zoijar op 17-05-2008 15:48 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:10

.oisyn

Moderator Devschuur®

Demotivational Speaker

H!GHGuY schreef op zaterdag 17 mei 2008 @ 14:37:
[...]


er zit wel een terminating 0 in hoor ;) kijk nog maar eens goed...
Nou wijs het maar aan dan, want ik zie het niet. strncpy() schrijft maximaal n characters. n is gelijk aan str.size(), dus strncpy() vult buffer met n characters zonder trailing 0.
H!GHGuY schreef op zaterdag 17 mei 2008 @ 14:54:
Ik kan er grandioos naast zitten
klopt ;)
strlen leest tot de eerste NUL-byte, str.data geeft alle data + bijhorende .size() (groter dan de strlen)
dus je kopieert over de vptr pointer.
Fout, om drie redenen. De vtable pointer staat meestal vooraan in de class, en dus niet achter buffer. Dit is wel zo praktisch omdat typeid() en dynamic_cast ook op void pointers moet kunnen werken. Als de vtable pointer achter buffer staat is het daadwerkelijke type zo goed als niet te achterhalen.

De andere reden is dat ook strncpy() niet altijd n characters kopiëert, maar maximaal n characters. Hij ie een 0 tegenkomt en i<n dan stopt dus gewoon. Je functie kopiëert daarom nooit meer dan 255 tekens door de if die ervoor staat. Als je altijd exact n characters wilt kopiëren moet je memcpy() gebruiken. En sowieso zelf de trailing 0 erachter zetten, want ook strncpy() doet dat niet als er al n characters geschreven zijn.

De derde noemde je zelf al:
Ik vermoed echter dat de set pointers naar CFixedSizeString zal moeten bevatten of anders wordt tijdens de copy-constructor actie de vptr van het geinserteerde object juist gezet.
Klopt als een bus ;)

[ Voor 8% gewijzigd door .oisyn op 17-05-2008 22:11 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Ach Zojar, jammer dat je nog niet gehoord hebt van Database Transactions. Dat maakt je hypothetisch voorbeeld onmogelijk.

Verwijderd

H!GHGuY schreef op zaterdag 17 mei 2008 @ 09:54:
C++:
1
2
3
4
5
6
7
8
9
class CFixedSizeString
{
  public:
     CFixedSizeString(const std::string& str)
     {
        if (strlen(str.c_str()) > 255)
           throw "badly sized string";
        strncpy(buffer, str.data(), str.size());
     }
Normaal gebruik ik geen std::string, maar is deze aanname wel juist: strlen(str.c_str())==str.size(). Als de string meerdere '\0' characters heeft, kan dat evt mis gaan...

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:10

.oisyn

Moderator Devschuur®

Demotivational Speaker

En als je even door had gelezen dan was je erachter gekomen dat dat idd de clue was ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Verwijderd schreef op zaterdag 17 mei 2008 @ 21:35:
Ach Zojar, jammer dat je nog niet gehoord hebt van Database Transactions. Dat maakt je hypothetisch voorbeeld onmogelijk.
Het zal je verbazen waar ik allemaal van gehoord heb ;) Zoals ik al zei, dan moet je een atomic query gebruiken, en dat kan idd middels een transaction. Maar aangezien het hier om kwetsbaarheden ging, merk ik op dat dit niet doen ook vaak een kwestbaarheid kan opleveren. Ik heb genoeg code gezien in het verleden die op deze manier records insert: select max(id) from users, fetch record set $result, insert user met id=$result. (in mijn tijd was MySQL overigens de meest gebruikte database icm web-development, en in de oude versies had je helaas niet de luxe van transaction support)

[ Voor 9% gewijzigd door Zoijar op 18-05-2008 11:52 ]


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

.oisyn schreef op zaterdag 17 mei 2008 @ 19:12:
[...]

Nou wijs het maar aan dan, want ik zie het niet. strncpy() schrijft maximaal n characters. n is gelijk aan str.size(), dus strncpy() vult buffer met n characters zonder trailing 0.


[...]

klopt ;)

[...]

Fout, om drie redenen. De vtable pointer staat meestal vooraan in de class, en dus niet achter buffer. Dit is wel zo praktisch omdat typeid() en dynamic_cast ook op void pointers moet kunnen werken. Als de vtable pointer achter buffer staat is het daadwerkelijke type zo goed als niet te achterhalen.

De andere reden is dat ook strncpy() niet altijd n characters kopiëert, maar maximaal n characters. Hij ie een 0 tegenkomt en i<n dan stopt dus gewoon. Je functie kopiëert daarom nooit meer dan 255 tekens door de if die ervoor staat. Als je altijd exact n characters wilt kopiëren moet je memcpy() gebruiken. En sowieso zelf de trailing 0 erachter zetten, want ook strncpy() doet dat niet als er al n characters geschreven zijn.

De derde noemde je zelf al:

[...]

Klopt als een bus ;)
niet schieten is altijd mis ;)

Leer ik zelf ook gelijk wat bij...

ASSUME makes an ASS out of U and ME


  • EdwinG
  • Registratie: Oktober 2002
  • Laatst online: 22:31
Volgens mij zijn we nu door de puzzels heen. Wie plaatst de volgende?

Bezoek eens een willekeurige pagina


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:10

.oisyn

Moderator Devschuur®

Demotivational Speaker

Tja, na de simpele buffer overruns en triviale XSS voorbeelden hebben we het wel zo'n beetje gehad. Ik kan me nog iets voorstellen met een UBB-achtige parser waarin je URLs of IMGs kunt stoppen waarbij je ook op moet passen dat daarin geen javascript oid is uit te voeren, maar dan wordt het voorbeeld al snel te complex om hier te posten.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Ach, klassieker die ik bijna wekelijks voorbij zie komen :
code:
1
2
3
$res = mysql_query('SELECT username FROM users WHERE name="pietje";'); 
$row = mysql_fetch_assoc($result);
$query2= mysql_query('update rechten set (adminright=True) where username="' . $row['username'] . '"');

[ Voor 3% gewijzigd door Gomez12 op 20-05-2008 20:34 ]


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Dankzij het verschil tussen $res en $result gaat daar niets fout, behalve dan dat je een whopping notice krijgt. :P

{signature}


  • Cartman!
  • Registratie: April 2000
  • Niet online
Het is sowieso niet handig om in de rechtentabel de naam te gebruiken ipv. het userid, is dat wat je bedoeld? Moeten er trouwens geen quotes om True heen? En de haakjes zijn ook overbodig.

offtopic: het adminright=true is ook erg beperkend voor een applicatie... ;)

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Volgens mij zit er geen fout in? Je kan je registreren als piet" OR 1=1 maar ik denk dat niet eens gaat werken (zowiezo niet als je pietje hard erin bakt).
Cartman! schreef op dinsdag 20 mei 2008 @ 21:10:
Het is sowieso niet handig om in de rechtentabel de naam te gebruiken ipv. het userid, is dat wat je bedoeld? Moeten er trouwens geen quotes om True heen? En de haakjes zijn ook overbodig.

offtopic: het adminright=true is ook erg beperkend voor een applicatie... ;)
Dan wordt het meer een "Debug mijn script" topic...

[ Voor 58% gewijzigd door Megamind op 20-05-2008 21:12 ]


  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 00:02

Onbekend

...

Wat gebeurt er als $row leeg is?

Speel ook Balls Connect en Repeat


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
row is leeg want $result bestaat ook al niet. ;) En dan gebeurd er niet veel, want al je users hebben een username.

Maar goed, het is een buggy versie van een security lek welke reeds in het begin van het topic langskwam. :P

[ Voor 17% gewijzigd door Voutloos op 20-05-2008 21:24 ]

{signature}


  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Wie garandeert dat wat er in de users tabel staat correct is?

De fout is nu juist dat niemand hier kan vertellen of pietje geen username van : pietje" or 1=1 or name="pietje staat.

Username is nog steeds userinvoer, dat het eerst in een dbase heeft gestaan is niet relevant.

Zoals ik al zei kom ik wekelijks progjes tegen die ooit in een ver verleden geen inputcontroles deden / ergens een inputcontrole vergeten ( in een ver weg liggend form wat bijna niemand gebruikt ). Waardoor je nooit userinput moet vertrouwen, onafhankelijk van de bron ( formulier posten of dbase )

En ik zie nu dat ik toch beter moet opletten met posten, $res == $result....

Na 3x verbeteren nog deze fout laten zitten... Maarja, ik geloof dat het maar beter is als ik hier niet meer ga posten :)

Na 3x verbeteren nog meerdere fouten laten zitten... Ik moet geloof echt stoppen met posten in dit topic...

[ Voor 20% gewijzigd door Gomez12 op 20-05-2008 21:44 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:10

.oisyn

Moderator Devschuur®

Demotivational Speaker

En laten we voor het gemak dan ook maar even vergeten dat mysql gaat vallen over die ; aan het eind van de eerste query ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Maar post dan een voorbeeld script dat relevant is, en niet een script en dan achteraf zeggen, oh maar pietje kan ook iets anders zijn, want dat kan het niet zijn in jou script. :?

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Megamind schreef op dinsdag 20 mei 2008 @ 21:48:
Maar post dan een voorbeeld script dat relevant is, en niet een script en dan achteraf zeggen, oh maar pietje kan ook iets anders zijn, want dat kan het niet zijn in jou script. :?
username kan toch iets anders zijn als name?

Maar door de vele fouten van mijn post is het hele punt waardeloos geworden.

Maar vergelijk het eens met een willekeurig netwerk-systeem, name kan een korte code zijn om iemand aan te duiden ( id's houden de meeste mensen niet zo van, voelen ze zich zo'n nummertje ) terwijl username de voornaam van de gebruiker kan zijn.

Btw fout 1500, username en name moeten omdraaien. Op deze manier loopt het db-schema raar.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:10

.oisyn

Moderator Devschuur®

Demotivational Speaker

Gomez12 schreef op dinsdag 20 mei 2008 @ 21:54:
Btw fout 1500, username en name moeten omdraaien.
Die je zelf al maakt. Een username is namelijk juist typisch het ding waarmee je inlogt, en name het ding wat publiek weergegeven wordt om de de persoon aan te duiden. Maar idd, noem het dan loginname en displayname.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 00:02

Onbekend

...

Laat ik er maar eens een stuk code posten. Voor het gemak weer in PHP. :)

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
<?php

// Als voorbeeld definiëer ik dit lokaal, maar zou uit een DB moeten komen o.i.d..
$ThisUserID = 3; // User ID van deze gebruiker.
$TargetUserID = 6; // User ID van de begunstigde. (Dit getal mag niet gelijk zijn aan $ThisUserID en moet natuurlijk een bestaande gebruiker zijn.
$AccountThisUser = 600; // Het bedrag wat deze gebruiker in bezit heeft.
$AccountTargetUser = 420; // Het bedrag wat de andere gebruiker in bezit heeft.

if ( isset($_GET["Donate"]) )
{   
    if ( is_numeric($_GET["Donate"]) )
    {
        if ( is_int( intval($_GET["Donate"]) ) )
        {
            $Donation = $_GET["Donate"];
            
            if ( $Donation <= $AccountThisUser )
            {
                $AccountThisUser = $AccountThisUser - $Donation;
                $AccountTargetUser = $AccountTargetUser + $Donation;
            }
            else
                die("You do not have enough money!");
        }
        else
            die("Error");
    }
    else
        die("Error");
}
else
    die("Error");

// En dit moet weer in de DB geschreven worden.
echo "Account this user: &euro; ".$AccountThisUser.",--<br>";
echo "Account target user: &euro; ".$AccountTargetUser.",--<br>";

Speel ook Balls Connect en Repeat


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:13

Creepy

Tactical Espionage Splatterer

Onbekend: je kan een negatieve waarde voor Donate meegeven waardoor je de huidige user zijn account ophoogt ten koste van de targetUser.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • stereohead
  • Registratie: April 2006
  • Laatst online: 21:21
Haha, dat is nog is een mooi exploit voorbeeld.


Ik zou 'Account*' trouwens vervangen door 'Amount*'.

[ Voor 39% gewijzigd door stereohead op 20-05-2008 23:11 ]


  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 00:02

Onbekend

...

Da's snel! Hij was toch niet moeilijk hè? :P
Maar ik kom zoiets toch weleens vaker tegen. Gelukkig niet met geldbedragen. :)

Speel ook Balls Connect en Repeat


  • The Fox NL
  • Registratie: Oktober 2004
  • Laatst online: 17-11 13:15
Regel 13 geeft zo te zien ook altijd true terug.

  • Patriot
  • Registratie: December 2004
  • Laatst online: 20:16

Patriot

Fulltime #whatpulsert

The Fox NL schreef op dinsdag 20 mei 2008 @ 23:20:
Regel 13 geeft zo te zien ook altijd true terug.
Klopt.

Ik denk trouwens dat het enigszins belangrijk is om in dit topic even vast te stellen dat je duidelijk moet zijn over waar bepaalde waarden vandaan komen. Zoals Onbekend het doet is het prima, hij declareert daar simpelweg variabelen, maar zegt wel erbij waar ze normaliter vandaan zouden komen.

In het voorbeeld Gomez12 staat hardcoded "pietje" in de query, er kan daardoor in principe niets misgaan. Het was niet duidelijk dat die waarde van de gebruiker moest komen.

Dat hebben we al eerder gehad in dit topic, en het is natuurlijk niet onlogisch dat je daar over valt.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:10

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik blijf het trouwens suf vinden dat na al die jaren PHP nog altijd geen fatsoenlijke int of float validatie functies heeft. Voor int kom je dan nog weg met ctype_digit(), maar voor floats is de enige fatsoenlijke manier eigenlijk zelf een regex in elkaar flansen die hopelijk maar aan de regels van PHP voldoet.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 00:02

Onbekend

...

The Fox NL schreef op dinsdag 20 mei 2008 @ 23:20:
Regel 13 geeft zo te zien ook altijd true terug.
Ja, dat heb je goed gezien. Ik had dit stukje code even snel gemaakt met de nadruk dat een integer negatieve waarden kan bevatten.

Is_int mag inderdaad vervallen omdat het door de functie intval al altijd een integer is geworden.
En ik zie hiermee dat er nog een foutje in de code kan ontstaan als iemand bijvoorbeeld "1e10" invoert.
Op regel 15 moet het volgende staan: $Donation = intval($_GET["Donate"]);

Speel ook Balls Connect en Repeat


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Dat deze niet idempotente actie via GET ipv POST aangeroepen wordt, is ook een security probleem. B)

En die fout zie ik nog véél vaker. :'( Dat hele volkstammen het verschil tussen GET en POST (idempotentie) niet kennen is echt een serieus probleem. Het betreft niet alleen PHP'ers, maar er zijn er wel relatief veel die echt geen snars snappen van HTTP.

{signature}


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:13

Creepy

Tactical Espionage Splatterer

Hmm.. dan moet ik nu zeker iets gaan verzinnen omdat ik het als eerst heb geraden? Als iemand anders al iets heeft: ga je gang ;)
offtopic:
Voutloos: Ik krijg regelmatig te maken met mensen die niet in staat zijn om een HTTP request te maken vanuit code en dan maar direct vragen of ze niet een XML doc via SOAP kunnen sturen :/

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 00:02

Onbekend

...

Wat is dan het security probleem?

Met GET kan ik via de adresbalk variablen meegeven, en bij POST moet ik dat via een formulier op de website doen. Het enige nadeel (soms voordeel) is dat je de inhoud van een variable gemakkelijk kan zien via GET. Maar ze bieden beiden securityproblemen. Meer verschillen dan dat ken ik niet.

Speel ook Balls Connect en Repeat


  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 16-11 19:52

Gerco

Professional Newbie

@Onbekend: Zoals Voutloos al zegt: volgens RFC 2616 moet een GET request idempotent zijn. Dat wil zeggen dat hij geen veranderingen mag veroorzaken in de permanente staat van de applicatie en dat het dus geen kwaad mag kunnen wanneer die GET meerdere keren opgevraagd of van tevoren gecached wordt.

Dat probleem is pijnlijk duidelijk wanneer je sommige sites gebruikt met een zogenaamde internet versneller (plugin). Die laden de links op die pagina alvast in zodat je de volgende pagina sneller kan opvragen omdat je die al in de cache hebt staan. Wat nu als er op die pagina links staan naar "pagina.php?action=delete"?

Daarom moeten acties die iets veranderen in de database (of in meer algemene zin, de staat van de applicatie/website) altijd met een POST request gedaan worden. Voor meer informatie, zie RFC 2616, section 9.

Daarnaast worden de parameters bij een GET request opgeslagen in web server logs, proxy logs, firewall logs en wat er allemaal nog meer tussen zit voor je request bij de server is. Dat kan op zichzelf al een beveiligingsrisico zijn.

[ Voor 13% gewijzigd door Gerco op 21-05-2008 08:54 ]

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Niet zozeer een security probleem meer een usability probleem.
Elke fatsoenlijke browser gaat niet zomaar post-waardes reposten bij een F5 ( oftewel als het te lang duurt drukt iemand nog eens op F5 en dan heeft hij 2x gedoneerd )

Geen enkele website versneller die ik ken gaat post waardes ook prefetchen.

Iemand kan niet per ongeluk een bookmark aanmaken die elke keer weer een donatie doet.

Post waardes voor dingen die iets doen, Get waardes om iets op te halen.

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-11 14:08
Onbekend schreef op dinsdag 20 mei 2008 @ 23:10:
Da's snel! Hij was toch niet moeilijk hè? :P
Maar ik kom zoiets toch weleens vaker tegen. Gelukkig niet met geldbedragen. :)
Veel webshops zijn er vatbaar voor. Kun je een negatief aantal artikelen bestellen. De factuur ziet er vervolgens veelbelovend uit ;)

@.oisyn
Wat is er mis met is_int(), is_float() en/of is_numeric() ?

@Voutloos
Dat zijn ook de mensen die topics openen dat ze het stom vinden dat je in PHP geen headers meer kunt verzenden na je output, of dat je een ander frame niet van locatie kan veranderen met header("Location") :X

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Gerco schreef op woensdag 21 mei 2008 @ 08:43:
Wat nu als er op die pagina links staan naar "pagina.php?action=delete"?
Om het af te maken een voorbeeld voorkauwen:
Stel dat je op GoT deze donate actie via GET zou hebben. Dan hoef je enkel een dergelijke link als webicon op te geven en je krijgt bij elke pageview geld van degene die de pagina bekijkt *O*

Als je rekening houdt met idempotentie en daarom de keuze GET/POST maakt, zit je meestal ook meteen goed voor wat betreft deze aanvalmogelijkheid. :)
Gomez12 schreef op woensdag 21 mei 2008 @ 08:46:
Niet zozeer een security probleem meer een usability probleem.
Lees bovenstaand voorbeeld en durf dit dan nog eens te zeggen. >:) :>

[ Voor 17% gewijzigd door Voutloos op 21-05-2008 10:16 ]

{signature}


  • YopY
  • Registratie: September 2003
  • Laatst online: 06-11 13:47
Onbekend schreef op dinsdag 20 mei 2008 @ 23:03:
Laat ik er maar eens een stuk code posten. Voor het gemak weer in PHP. :)

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
<?php

// Als voorbeeld definiëer ik dit lokaal, maar zou uit een DB moeten komen o.i.d..
$ThisUserID = 3; // User ID van deze gebruiker.
$TargetUserID = 6; // User ID van de begunstigde. (Dit getal mag niet gelijk zijn aan $ThisUserID en moet natuurlijk een bestaande gebruiker zijn.
$AccountThisUser = 600; // Het bedrag wat deze gebruiker in bezit heeft.
$AccountTargetUser = 420; // Het bedrag wat de andere gebruiker in bezit heeft.

if ( isset($_GET["Donate"]) )
{   
    if ( is_numeric($_GET["Donate"]) )
    {
        if ( is_int( intval($_GET["Donate"]) ) )
        {
            $Donation = $_GET["Donate"];
            
            if ( $Donation <= $AccountThisUser )
            {
                $AccountThisUser = $AccountThisUser - $Donation;
                $AccountTargetUser = $AccountTargetUser + $Donation;
            }
            else
                die("You do not have enough money!");
        }
        else
            die("Error");
    }
    else
        die("Error");
}
else
    die("Error");

// En dit moet weer in de DB geschreven worden.
echo "Account this user: &euro; ".$AccountThisUser.",--<br>";
echo "Account target user: &euro; ".$AccountTargetUser.",--<br>";
Bbbbbaaaaahhhh, al die ifs zijn ten eerste redundant en ten tweede kunnen ze gecombineerd worden. Wat is er mis met

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

// Als voorbeeld definiëer ik dit lokaal, maar zou uit een DB moeten komen o.i.d..
$ThisUserID = 3; // User ID van deze gebruiker.
$TargetUserID = 6; // User ID van de begunstigde. (Dit getal mag niet gelijk zijn aan $ThisUserID en moet natuurlijk een bestaande gebruiker zijn.
$AccountThisUser = 600; // Het bedrag wat deze gebruiker in bezit heeft.
$AccountTargetUser = 420; // Het bedrag wat de andere gebruiker in bezit heeft.

$Donation = $_GET["Donate"];

if ( isset($Donation) && is_numeric($Donation) && is_int(intval($Donation)) && ( $Donation <= $AccountThisUser ))
{   
    $AccountThisUser = $AccountThisUser - $Donation;
    $AccountTargetUser = $AccountTargetUser + $Donation;
}
else
    die("Error");

// En dit moet weer in de DB geschreven worden.
echo "Account this user: &euro; ".$AccountThisUser.",--<br>";
echo "Account target user: &euro; ".$AccountTargetUser.",--<br>";


(bijvoorbeeld), en kunnen die driedubbele checks niet vervangen worden naar een enkele aanroep naar een of andere functie die alleen true geeft als de meegegeven waarde een int en niet null is? Maak desnoods een eigen functie oid.

Daar komt nog bij dat je op deze manier ook negatieve nummers mee kunt geven in je get, evenals de zooi die hierboven gepost is over posts gebruiken voor dit soort gegevens.

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Ik zou het ook niet meteen een 'security' probleem durven noemen, maar ik ben het wel met je eens dat GET uitsluitend voor idempotent operaties gebruikt mag worden.

Wat eerder een security probleem kan zijn, lijkt me, is dat er via GET operaties bepaalde items opgehaald worden. Stel bijvoorbeeld: edit.htm?id=12

De gebruiker krijgt dan de details van item met id 12 te zien. Hier kan de gebruiker naar believen wijzigingen in aanbrengen (vb: edit.htm?id=1) en op die manier informatie bekomen die hij eigenlijk niet mag zien. Het blijft uiteraard een idempotent operatie, maar introduceert wel een security probleem.

  • ChessSpider
  • Registratie: Mei 2006
  • Laatst online: 29-09 19:35
-FoX- schreef op woensdag 21 mei 2008 @ 11:14:
Ik zou het ook niet meteen een 'security' probleem durven noemen, maar ik ben het wel met je eens dat GET uitsluitend voor idempotent operaties gebruikt mag worden.

Wat eerder een security probleem kan zijn, lijkt me, is dat er via GET operaties bepaalde items opgehaald worden. Stel bijvoorbeeld: edit.htm?id=12

De gebruiker krijgt dan de details van item met id 12 te zien. Hier kan de gebruiker naar believen wijzigingen in aanbrengen (vb: edit.htm?id=1) en op die manier informatie bekomen die hij eigenlijk niet mag zien. Het blijft uiteraard een idempotent operatie, maar introduceert wel een security probleem.
Je snapt dat dit net zo goed geld als voor POST he? Je moet GET hetzelfde beschouwen als POST wat het je applicatie betreft. Cookie gegevens beveilig je toch ook goed?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:10

.oisyn

Moderator Devschuur®

Demotivational Speaker

frickY schreef op woensdag 21 mei 2008 @ 09:22:
Wat is er mis met is_int(), is_float() en/of is_numeric() ?
Wat er mis is met is_int() en is_float() mag je zelf opzoeken in de documentatie 8)7
is_numeric() is dan wel weer handig voor floats. Ik dacht eerlijk gezegd dat deze ook true returnde bij een string als "10 apen", maar dat blijkt (gelukkig) niet zo te zijn. Nou de ints nog, want ctype_digit() geeft weer false voor negatieve (of expliciet positieve) ints.
-FoX- schreef op woensdag 21 mei 2008 @ 11:14:
Wat eerder een security probleem kan zijn, lijkt me, is dat er via GET operaties bepaalde items opgehaald worden. Stel bijvoorbeeld: edit.htm?id=12

De gebruiker krijgt dan de details van item met id 12 te zien. Hier kan de gebruiker naar believen wijzigingen in aanbrengen (vb: edit.htm?id=1) en op die manier informatie bekomen die hij eigenlijk niet mag zien. Het blijft uiteraard een idempotent operatie, maar introduceert wel een security probleem.
Over het algemeen is er niets mis mee om daar een GET te gebruiken. Je moet in de applicatie sowieso een check doen of de huidige gebruiker wel bij dat id mag komen. Dus als hij het id wil veranderen naar een ander id waar hij ook toegang tot heeft is daar niets mis mee.

Een uitzondering is bijvoorbeeld als je een wiki pagina wilt editten en daardoor de pagina lockt. Maar dat impliceert dat het niet meer idempotent is en moet je dus sowieso een POST gaan gebruiken.

[ Voor 50% gewijzigd door .oisyn op 21-05-2008 11:21 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

ChessSpider schreef op woensdag 21 mei 2008 @ 11:16:
[...]
Je snapt dat dit net zo goed geld als voor POST he? Je moet GET hetzelfde beschouwen als POST wat het je applicatie betreft. Cookie gegevens beveilig je toch ook goed?
Inderdaad, op zich maakt het niet veel verschil al zal een simpele eindgebruiker eerder geneigd zijn om op die manier dingen aan je request te wijzigen dan een POST te spoofen. Uiteraard moet er nog altijd geverifieerd worden of deze user input toegelaten is op de server.

Wat ik dan soms ook nog wel eens tegen durf komen is dat ontwikkelaars dergelijke ID's gaan encoderen tot iets onleesbaars.. maar uiteindelijk blijf je dan nog altijd met hetzelfde probleem zitten.

  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 00:02

Onbekend

...

YopY schreef op woensdag 21 mei 2008 @ 11:13:
[...]


Bbbbbaaaaahhhh, al die ifs zijn ten eerste redundant en ten tweede kunnen ze gecombineerd worden. Wat is er mis met

[...]
Klopt helemaal. :)
Helaas programmeer ik op m'n werk ook andere programmeertalen waarbij de compiler de variabelen in een if-statement soms van plaats wisselt zodat controles in een andere volgorde langs komen dan je eigenlijk wil.

In de regel if ( isset($Donation) && is_numeric($Donation) && is_int(intval($Donation)) && ( $Donation <= $AccountThisUser ))
wordt dan bijvoorbeeld eerst van $Donation een nummeric getal gemaakt, en daarna gaat hij kijken of $Donation is geset.

Om verwarring en dit soort fouten te voorkomen werk ik daarom eigenlijk altijd met losse if-statements. :Y)


Zoals ik de reacties zo lees zit er, zoals ik al had verwacht, geen veiligheidsverschillen tussen POST en GET. Afhankelijk van de toepassing wordt voor een GET of juist voor een POST gekozen, en voor mijn codevoorbeeld had ik daarom een GET gekozen omdat je dan gemakkelijk het resultaat kan testen. :)

Speel ook Balls Connect en Repeat


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:10

.oisyn

Moderator Devschuur®

Demotivational Speaker

Onbekend schreef op woensdag 21 mei 2008 @ 23:09:
Helaas programmeer ik op m'n werk ook andere programmeertalen waarbij de compiler de variabelen in een if-statement soms van plaats wisselt zodat controles in een andere volgorde langs komen dan je eigenlijk wil.
Mijn god :X Welke programmeertaal is dat?

[ Voor 49% gewijzigd door .oisyn op 21-05-2008 23:48 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • AndriesLouw
  • Registratie: December 2005
  • Laatst online: 23:18
Voor id's gebruik ik (in PHP) altijd ctype_digit(), wat volgens mij echt garandeert dat je alleen maar numerieke tekens in je ID hebt.

Specificaties | AndriesLouw.nl


  • GrooV
  • Registratie: September 2004
  • Laatst online: 00:16
Waarom alles in PHP? :r :X

  • Patriot
  • Registratie: December 2004
  • Laatst online: 20:16

Patriot

Fulltime #whatpulsert

Omdat PHP zo is ontwikkeld dat het ontzettend veel toelaat, het is ontzettend makkelijk om er mee te werken. Het nadeel daarvan is dus dat er veel exploits mogelijk zijn.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:13

Creepy

Tactical Espionage Splatterer

Doe er wat aan zou ik zeggen ;) .oisyn heeft ook al een C++ voorbeeld gepost.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

code:
1
2
3
:start
echo %1
goto start


geen php ;)

En inderdaad interessant topic :)

[ Voor 35% gewijzigd door Guillome op 22-05-2008 13:42 ]

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:10

.oisyn

Moderator Devschuur®

Demotivational Speaker

Waar zit de kwestbaarheid, en wat is het doel van het script? Voor de goede orde, het gaat hier om normale applicaties die fouten in hun code hebben die uitgebuit kunnen worden door 'hackers' om zo dingen te doen die eigenlijk niet zouden mogen (zoals een systeem overnemen, gegevens opvragen die ze niet zouden mogen opvragen, etc.).

Jouw script doet niets anders dan in een oneindige loop dezelfde regel uitvoeren. Hoe kan dat uitgebuit worden?

[ Voor 84% gewijzigd door .oisyn op 22-05-2008 13:51 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Onbekend schreef op woensdag 21 mei 2008 @ 23:09:
[...]
is_int(intval($Donation))
Dit returned toch altijd true? wat de inhoud van $Donation ook is.
Onbekend schreef op woensdag 21 mei 2008 @ 23:09:
[...]
In de regel if ( isset($Donation) && is_numeric($Donation) && is_int(intval($Donation)) && ( $Donation <= $AccountThisUser ))
wordt dan bijvoorbeeld eerst van $Donation een nummeric getal gemaakt, en daarna gaat hij kijken of $Donation is geset.
Maar $Donation word toch helemaal geen numeric getal gemaakt? Ik zie nergens dat $Donation geset word en in de documentatie zie ik ook niet staan dat de functie iets aan de waarde veranderd die je meegeeft. Dus IMHO zou de volgorde van uitvoeren hier niet zoveel uitmoeten halen.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

.oisyn schreef op donderdag 22 mei 2008 @ 13:48:
Waar zit de kwestbaarheid, en wat is het doel van het script? Voor de goede orde, het gaat hier om normale applicaties die fouten in hun code hebben die uitgebuit kunnen worden door 'hackers' om zo dingen te doen die eigenlijk niet zouden mogen (zoals een systeem overnemen, gegevens opvragen die ze niet zouden mogen opvragen, etc.).

Jouw script doet niets anders dan in een oneindige loop dezelfde regel uitvoeren. Hoe kan dat uitgebuit worden?
zucht .... :z
@hydra: het was als grapje bedoeld op de post boven mij. Zal ik niet weer doen. Sorry, ga maar weer ontopic, das veel interessanter dan zo over een geintje tussendoor te vallen...

[ Voor 13% gewijzigd door Guillome op 22-05-2008 15:24 ]

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Euh? Geef anders antwoord op z'n vraag?

https://niels.nu


  • Patriot
  • Registratie: December 2004
  • Laatst online: 20:16

Patriot

Fulltime #whatpulsert

Guillome schreef op donderdag 22 mei 2008 @ 15:02:
[...]

zucht .... :z
@hydra: het was als grapje bedoeld op de post boven mij. Zal ik niet weer doen. Sorry, ga maar weer ontopic, das veel interessanter dan zo over een geintje tussendoor te vallen...
Waarom quote je .oisyn dan? Natuurlijk denkt iedereen dan dat het daar een reactie op is..

Ik snap overigens ook niet helemaal wat de exploit in dat script is. Overigens maakt het ook weinig uit, want ik denk dat hier wel wat dingen mogen komen te staan die in de praktijk ook voorkomen.

  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

:? :? eh juist ja :? ga aub door met het topic, je maakt van de mug alleen maar een grote vage olifant

[ Voor 8% gewijzigd door Guillome op 22-05-2008 16:30 ]

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Verwijderd

Cartman! schreef op zaterdag 17 mei 2008 @ 11:41:

PHP:
1
2
3
4
5
6
7
$strSql = '
    INSERT INTO
        video
    SET
        filename = "' . $strFilename . '",
        hash = "' . sha1(time()) . '"
    ';
Over het dubbele hashes, je kan natuurlijk het veld op PRIMARY zetten zodat er enkel unique strings in mogen staan. Het haalt de bug er niet 100% uit, maar het is al iets beter aangezien de dubbele string niet in de database komt.

  • TJHeuvel
  • Registratie: Mei 2008
  • Niet online
Cartman! schreef op dinsdag 20 mei 2008 @ 21:10:
Het is sowieso niet handig om in de rechtentabel de naam te gebruiken ipv. het userid, is dat wat je bedoeld?
Al ben ik het wel met je eens, maar waarom?
Waarom precies wil je een id gebruiken, ipv een naam?

Freelance Unity3D developer


  • Patriot
  • Registratie: December 2004
  • Laatst online: 20:16

Patriot

Fulltime #whatpulsert

CyCloneNL schreef op vrijdag 23 mei 2008 @ 10:11:
[...]


Al ben ik het wel met je eens, maar waarom?
Waarom precies wil je een id gebruiken, ipv een naam?
Naast dat het een gevoelskwestie is, scheelt het ruimte. Bovendien weet je zeker dat je geen rare dingen krijgt i.v.m. bepaalde encoding etc. van de naam.

EDIT: En wat dacht je als de naam veranderd? Dan moet je dat in alle tabellen gaan doen.

[ Voor 11% gewijzigd door Patriot op 23-05-2008 10:21 ]


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Plus dat een dergelijke synthetische key gewoon constant kan blijven, ook al wil jij je username veranderen en ga zo maar door met alle standaard datamodel argumenten.
Maar goed, dit is wel offtopic allemaal...
edit:
spuit 11 na bovenstaande edit :'( Maar dan nog zijn dit toch echt wel standaard puntjes uit datamodel 101)

[ Voor 21% gewijzigd door Voutloos op 23-05-2008 10:27 ]

{signature}


  • TJHeuvel
  • Registratie: Mei 2008
  • Niet online
Ok, thanks.

Zelf zou ik ook een ID gebruiken, maar alleen voor de 'gevoelskwestie'. Nu weet ik dus waarom :)

Freelance Unity3D developer


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:10

.oisyn

Moderator Devschuur®

Demotivational Speaker

En 't is gewoon sneller, een index van integers tov een index van varchars ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • TJHeuvel
  • Registratie: Mei 2008
  • Niet online
Ok, nog eentje, niet echt een kwetsbaarheid maar wel een fout.

Een nieuws systeem, waar de tekst na 100 karakters wordt afgekapt en er een 'Lees meer' link wordt gegeven.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
$maxLength = 100; //Maximum tekst length.

$result = (Haal data uit MYSQL database)

while($row = mysql_fetch_array($result))
{
   $titel = $row['titel'];
   $text = strlen($row['tekst']) > $maxLength ? $row['tekst'] : substr($row['tekst'],0,$maxLength) . "<a href='news.php?id=$row[id]'>Lees meer!</a>";

   echo "<h1>$titel</h1> 
            $text";
}

Freelance Unity3D developer


  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

De substring zal altijd in de fout gaan, aangezien de text in die case altijd kleiner zal zijn dan 100?

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 23:35

MueR

Admin Devschuur® & Discord

is niet lief

Hij kapt hard op 100 karakters, niet netjes einde woord etc, geen tags afsluitend. Alleen jammer dat ie daar niet komt, alleen wanneer de tekst niet groter is als $max, wat dus loos kapwerk is.


:w Voutloos, ik was nog aan het editen :P

[ Voor 50% gewijzigd door MueR op 29-05-2008 14:24 ]

Anyone who gets in between me and my morning coffee should be insecure.


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
offtopic:
Je kan voor PHP code [php][/php] tags gebruiken. ;)

En dit is wel een heel suf foutje. :P Je kan hier wellicht gewoon altijd substr() doen, lekker boeiend als je een handjevol calls hebt waarbij de tekst reeds binnen length viel, 't leest wel een stuk eenvoudiger. :)
MueR schreef op donderdag 29 mei 2008 @ 14:22:
Hij kapt hard op 100 karakters, niet netjes einde woord etc, geen tags afsluitend.
Zat ik eerst ook aan te denken, maar het is idd vooral verkeerd om. ;)
:w Voutloos, ik was nog aan het editen :P
Yeah right. :+ :w

[ Voor 37% gewijzigd door Voutloos op 29-05-2008 14:43 ]

{signature}


  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
Tenzij de titel en de tekst al escaped (htmlentities / htmlspecialchar) in de database staan heb je last van XSS.

  • Muthas
  • Registratie: December 2005
  • Niet online

Muthas

O+

Het is sowieso onzin om te escapen/XSS filteren bij het weergeven van data, imo moet je dat doen zodra je het in je de database zet.

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 11-11 10:24

Bosmonster

*zucht*

PrisonerOfPain schreef op donderdag 29 mei 2008 @ 14:23:
Tenzij de titel en de tekst al escaped (htmlentities / htmlspecialchar) in de database staan heb je last van XSS.
Maar dat ligt dan meer aan het feit dat je dat zo in de database hebt staan. Das al een WTF op zich.

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
Muthas schreef op donderdag 29 mei 2008 @ 14:26:
Het is sowieso onzin om te escapen/XSS filteren bij het weergeven van data, imo moet je dat doen zodra je het in je de database zet.
Párdon? De data in de database heeft níets te maken met de weergave van de betreffende content, escapen van de data met htmlentities ed. doe je gewoon in de view layer.

  • Muthas
  • Registratie: December 2005
  • Niet online

Muthas

O+

En dat je weet ik het hoeveel keer hetzelfde met je data doet terwijl je die data altijd ge-escaped nodig zal hebben maakt niet uit?

[ Voor 42% gewijzigd door Muthas op 29-05-2008 14:36 ]


  • TJHeuvel
  • Registratie: Mei 2008
  • Niet online
PrisonerOfPain schreef op donderdag 29 mei 2008 @ 14:23:
Tenzij de titel en de tekst al escaped (htmlentities / htmlspecialchar) in de database staan heb je last van XSS.
Hij is escaped enzo.

Freelance Unity3D developer


  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
Muthas schreef op donderdag 29 mei 2008 @ 14:33:
En dat je weet ik het hoeveel keer hetzelfde met je data doet terwijl je die data altijd ge-escaped nodig zal hebben maakt niet uit?
Dat is nogal een non-optimalisatie; zodra dit een bottleneck word doet de view layer z'n eigen caching maar. In een database wil je dit soort dingen gewoon niet hebben omdat op dat punt helemaal nog niet vast staat wat het output formaat gaat worden.

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Muthas schreef op donderdag 29 mei 2008 @ 14:33:
En dat je weet ik het hoeveel keer hetzelfde met je data doet terwijl je die data altijd ge-escaped nodig zal hebben maakt niet uit?
Escapen is niet generiek, maar doe je voor een bepaalde context. Pas als jij zeker weet welke context altijd gebruikt wordt kan dit een vd bewuste optimalisatie trucs zijn.
edit:
...waarbij het compleet cachen van grote blokken van je site idd krachtiger kan zijn. Maar wellicht ook lastiger. :P

[ Voor 12% gewijzigd door Voutloos op 29-05-2008 14:47 ]

{signature}


  • TJHeuvel
  • Registratie: Mei 2008
  • Niet online
In ieder geval, een fout is dat alle open HTML tags niet worden afgesloten.
Dus als er net een h1 tag geopend is, wordt de hele pagina dik gedrukt.

[ Voor 19% gewijzigd door TJHeuvel op 29-05-2008 17:23 ]

Freelance Unity3D developer

Pagina: 1 2 Laatste