C++ Sicher programmieren



  • Die Programmiersprache ist nicht fuer Bugs verantwortlich sondern der Programmierer. Die Sprache kann nur unterstuetzend wirken. Deswegen gibt es keine C, C++ oder Java spezifischen Fehler.



  • Die formalen Fehler fallen weg, aber es kann immer noch inhaltliche Fehler geben. Andere Sprachen, wie Python, haben auch keine rohen pointer, alles in Objekten gekapselt, etc. aber trotzdem kann es Sicherheitslücken geben.



  • knivil schrieb:

    Deswegen gibt es keine C, C++ oder Java spezifischen Fehler.

    So ein Quatsch.



  • sry schrieb:

    So ein Quatsch.

    Dann erklär doch mal, warum das "So ein Quatsch" ist.
    Es einfach nur zu schreiben zeugt nicht von Kompetenz, du musst solche Aussagen auch belegen. (Beispiele?)



  • schau mal wieviel UB es in C++ vs. Java gibt.



  • Tolles Argument. Du hast UB nicht verstanden. Schaue doch mal an wievielen Stellen die Wurzelfunktion undefiniert ist. Und wieviel Funktionen in der Mathematik nur partiell definiert sind. Warum soll etwas sinnfreies definiert werden?



  • knivil schrieb:

    Tolles Argument. Du hast UB nicht verstanden. Schaue doch mal an wievielen Stellen die Wurzelfunktion undefiniert ist. Und wieviel Funktionen in der Mathematik nur partiell definiert sind.

    Du hast UB nicht verstanden. Mathematik != Programmieren. 🙄
    Fast jedes UB ist ein Sicherheitsrisiko (z.B. Zugriff außerhalb von Array/Speichergrenzen).
    http://en.wikipedia.org/wiki/Undefined_behavior



  • Fast jedes UB ist ein Sicherheitsrisiko (z.B. Zugriff außerhalb von Array/Speichergrenzen).

    Kommen wir zum Thema zurueck: Und das ist jetzt C++ spezifisch? 🙂

    Und btw. Zugriff auf Arrays oder Tupels kann auch mathematisch ausgedrueckt werden, nennt sich Projektion in der Informatik.



  • Nein, da hast du Unrecht. Knivil hat schon einen guten Vergleich gebracht.

    Der Standard sagt zu manchen Dingen(die entweder fehlerbehaftet sind oder sehr leicht Fehelr erzeugen), dass das verhalten undefiniert ist. D.h. es kann passieren was will. Die Compilerhersteller können da reagieren wie sie wollen. Um es mal sinngemäß zu rezitieren:

    Und UB kann eben zu Sicherheitslöchern führen, aber nichts zwangsweise:

    void f(int, int);
    void g(int i, int* v)
    {
        i = v[i++]; // the behavior is undefined
        i = 7, i++, i++; // i becomes 9
        i = i++ + 1; // the behavior is undefined
        i = i + 1; // the value of i is incremented
        f(i = -1, i = -1); // the behavior is undefined
    }
    

    (§1.9.15)



  • Der Punkt ist: Programme mit undefiniertem Verhalten sind wie falsche Beweise. Der Fehler liegt beim Schreiber und nicht in der verwendeten Sprache. Sie sind einfach falsch. Und ich kann mindestens genausoviele falsche Programme in Java schreiben, wie in C++. Trotzdem halte ich eine Diskussion ueber falsche Programme fuer reichlich sinnlos.



  • knivil schrieb:

    Der Punkt ist

    Der wirkliche Punkt ist: In C++ ist es viel einfacher, falsche Programme zu schreiben. Klar kannst du sagen, der Fehler liegt beim Programmierer, aber da in der Realität die wenigsten Leute gut C++ können, ist Java im Bezug auf Sicherheit geeigneter.



  • knivil schrieb:

    Der Punkt ist: Programme mit undefiniertem Verhalten sind wie falsche Beweise. Der Fehler liegt beim Schreiber und nicht in der verwendeten Sprache. Sie sind einfach falsch. Und ich kann mindestens genausoviele falsche Programme in Java schreiben, wie in C++.

    Das ist eine dumme Milchmädchenrechnung. Laut deiner Logik ist es genauso sicher in einem Auto ohne Airbag und Sicherheitsgurt zu fahren wie in einem Auto mit Airbag und Sicherheitsgurt zu fahren, weil es 1000 andere Möglichkeiten zum sterben gibt.

    Aber was soll in einem C++ Forum auch anderes rauskommen, als das C++ super Sicher ist.



  • Jain, klar C++ ist in der Hinsicht schwerer. Aber im Umkehrschlsus dafür dann doch sicherer, wenn die Programme sicher geschrieben sind.

    In Java ist dann nochmal alles von der JVM und der Version und und und abhängig.
    Guckt man sich irgendwelche News-Ticker an, kommt alle Naselang mal "Java Sicherheitsloch entdeckt/gefixt". Andererseits kommt eher weniger sowas wie "C Runtime Environment ist fehlerhaft".

    In C/C++ passiert nur das, was du willst. Und das hat seine Vor- und Nachteile.



  • [quote="sry"]

    knivil schrieb:

    Aber was soll in einem C++ Forum auch anderes rauskommen, als das C++ super Sicher ist.

    Und Java soll sicherer sein? Ich möchte in keinem Auto/Flugzeug/Atomkraftwerk, Aufzug sitzen in dem statt einer Notfallreaktion erst noch schnell eine Garbage-Collection gemacht werden muss 😃

    Bei irgendwelchen Internetprogrämmchen ist so etwas egal.
    In sicherheitskritischen Systemen finden die Spielzeugsprachen Java und C# nicht statt.



  • Nicht alles, was hinkt, ist auch ein Vergleich.

    Und mir geht es eher hierdrum:

    sry schrieb:

    knivil schrieb:

    Deswegen gibt es keine C, C++ oder Java spezifischen Fehler.

    So ein Quatsch.



  • Officer schrieb:

    Was kann man in einem C++ Programm noch falsch machen, wenn man modernes C++ verwendet, damit man eine Sicherheitslücke in seinem Programm(Server/Forensoftware) hat? Wenn man std::vector und std::string statt normaler Arrays verwendet und keine Pointeroperationen macht und immer Smartpointer/RAII verwendet, kann man dann noch viel falsch machen?

    Wenn du schlaue Zeiger mit rohen Zeigern mischt (was durchaus sinnvoll sein kann), könntest du versehentlich ein Objekt zu früh löschen. Das muss man vom Design her auch schon ausschließen können. Beispielsweise könnte man einen bidirektional-verdrahteten binären Suchbaum so bauen:

    struct node
    {
       node* parent;
       unique_ptr<node> left, right;
       …
    };
    

    oder auch so:

    struct node {
       node *parent, *left, *right;
       …
    };
    
    class tree
    {
    public:
       …
    private:
       boost::ptr_vector<node> nodes_;
       node *root;
       …
    };
    

    Hauptsache, der/die Besitzer stirbt/sterben als letzte(r), die noch einen Zeiger auf so ein node-Objekt haben.

    Und sonst gibt's ja noch so einiges mit UB. Die ganzen Überprüfungen, die in anderen Sprachen garantiert werden, gibt's in C++ nicht. Du kannst natürlich auch mit Iteratoren noch Blödsinn machen. Mit einem Vektor-Iterator kannst du ggf über das Ende hinauslaufen etc. Die Debug-Modi mit ihren Extre-Checks (safe iterators etc) helfen während der Entwicklung. Im Release-Modus fährst du dann ohne Stützräder.



  • Klar, sowas wie Codeinjection geht ja immer noch.

    Kleine Aufgabe dazu:
    C++:

    int main()
    {
        cout << "Gib einen Befehl ein: ";
        string command;
        getline(cin, command);
     
        return system(command.c_str());
    }
    

    Ist dieses Programm sicher?
    Was ist damit alles möglich?
    Wo sind Fehler?
    Gibt es Programmierer-Bugs?

    Was kann den hier passieren außer dass man bei einer gewissen Größe (2^16 Zeichen?) die Kommandozeile zum Überlauf bringen würde?



  • Du kannst JEDEN befehl in das Programm einspeisen und somit mit dem Rechner machen was du willst.

    Stell dir mal vor du bist der (böse) User, sitzt an dem Rechner, aber hast keine Adminrechte, kannst demnach nichts kaputtmachen (nehmen wir mal an). Jeetzt startet das Programm aber im Adminmodus (weil es diese Rechte an anderer Stelle braucht und auch so eignerichtet ist, ok) und du bekommst somit als eigentlich nicht berechtigter User die volle Kontrolle über den Rechner und kannst ihn kaputtmachen.

    Der Fehler liegt erstens darin system zu nutzen 😃 🤡 und zweitens darin, eigegebene Daten ohne Prüfung weiter zu geben und darauf aufzubauen.

    Nächstes Beispiel:

    int main()
    {
        char buf[100];
        cin.getline(buf, 100);
    
        return 0;
    }
    

    Was ist damit?
    Was kann passieren?
    Wo liegt der Fehler?



  • Das ist aber grenzwertig ob das überhaupt ein Fehler ist. Jeden Befehl mit Adminrechten ausführen zu können kann auch ein Feature sein, man denke an ein Programm für Remote-Login, wo der Nutzer womöglich sogar ein Admin ist.
    Ich will auch mal ein Programm in den Raum werfen: format. Formatiert einen Datenträger. Ist das Programm gefährlich? Nützlich? Das hat mit C++ und allgemein Programmierung überhaupt nichts mehr zu tun.



  • Aber sowas sind Sicherheitslücken.

    Wenn hier einer von den Webprogrammierern ist, die können da auch en Lied von singen. So SQL-Injections und sowas...

    Letztlich gehört das aber alles zum sauberen Programmieren und Software-Designen dazu.


Anmelden zum Antworten