Πώς να γράψετε κανόνες για το Checkmarx χωρίς να τρελαίνεστε

Γεια σου Χαμπρ!

Στην εργασία μας, η εταιρεία μας πολύ συχνά ασχολείται με διάφορα εργαλεία ανάλυσης στατικού κώδικα (SAST). Από το κουτί λειτουργούν όλοι κατά μέσο όρο. Φυσικά, όλα εξαρτώνται από το έργο και τις τεχνολογίες που χρησιμοποιούνται σε αυτό, καθώς και από το πόσο καλά αυτές οι τεχνολογίες καλύπτονται από τους κανόνες ανάλυσης. Κατά τη γνώμη μου, ένα από τα πιο σημαντικά κριτήρια κατά την επιλογή ενός εργαλείου SAST είναι η δυνατότητα προσαρμογής του στις ιδιαιτερότητες των εφαρμογών σας, δηλαδή, η εγγραφή και η αλλαγή κανόνων ανάλυσης ή, όπως αποκαλούνται πιο συχνά, Προσαρμοσμένα ερωτήματα.

Πώς να γράψετε κανόνες για το Checkmarx χωρίς να τρελαίνεστε

Τις περισσότερες φορές χρησιμοποιούμε το Checkmarx - έναν πολύ ενδιαφέρον και ισχυρό αναλυτή κώδικα. Σε αυτό το άρθρο θα μιλήσω για την εμπειρία μου από τη σύνταξη κανόνων ανάλυσης για αυτό.

πίνακας περιεχομένων

Είσοδος

Αρχικά, θα ήθελα να προτείνω ένα από τα λίγα άρθρα στα ρωσικά σχετικά με τις δυνατότητες σύνταξης ερωτημάτων για το Checkmarx. Δημοσιεύτηκε στο Habré στα τέλη του 2019 με τον τίτλο: "Γεια σου, Τσέκμαρξ!" Πώς να γράψετε ένα ερώτημα Checkmarx SAST και να βρείτε εντυπωσιακά τρωτά σημεία.

Εξετάζει λεπτομερώς πώς να γράψετε τα πρώτα ερωτήματα στη CxQL (Checkmarx Query Language) για κάποια δοκιμαστική εφαρμογή και δείχνει τις βασικές αρχές του τρόπου λειτουργίας των κανόνων ανάλυσης.

Δεν θα επαναλάβω αυτό που περιγράφεται σε αυτό, αν και κάποιες διασταυρώσεις θα εξακολουθήσουν να υπάρχουν. Στο άρθρο μου θα προσπαθήσω να συντάξω ένα είδος «συλλογής συνταγών», μια λίστα λύσεων σε συγκεκριμένα προβλήματα που αντιμετώπισα κατά τη διάρκεια της εργασίας μου με το Checkmarx. Έπρεπε να βάλω το μυαλό μου σε πολλά από αυτά τα προβλήματα. Μερικές φορές δεν υπήρχαν αρκετές πληροφορίες στην τεκμηρίωση και μερικές φορές ήταν ακόμη και δύσκολο να καταλάβουμε πώς να κάνουμε αυτό που απαιτείται. Ελπίζω η εμπειρία μου και οι άγρυπνες νύχτες μου να μην είναι μάταιες και αυτή η «συλλογή συνταγών προσαρμοσμένων ερωτημάτων» θα σας εξοικονομήσει μερικές ώρες ή μερικά νευρικά κύτταρα. Λοιπόν, ας ξεκινήσουμε!

Γενικές πληροφορίες για τους κανόνες

Αρχικά, ας δούμε μερικές βασικές έννοιες και τη διαδικασία εργασίας με τους κανόνες, για καλύτερη κατανόηση του τι θα συμβεί στη συνέχεια. Και επίσης επειδή η τεκμηρίωση δεν λέει τίποτα για αυτό ή είναι πολύ απλωμένη στη δομή, κάτι που δεν είναι πολύ βολικό.

  1. Οι κανόνες εφαρμόζονται κατά τη σάρωση ανάλογα με την προεπιλογή που έχει επιλεγεί κατά την έναρξη (ένα σύνολο ενεργών κανόνων). Μπορείτε να δημιουργήσετε έναν απεριόριστο αριθμό προεπιλογών και το πώς ακριβώς θα τις δομήσετε εξαρτάται από τις ιδιαιτερότητες της διαδικασίας σας. Μπορείτε να τα ομαδοποιήσετε ανά γλώσσα ή να επιλέξετε προεπιλογές για κάθε έργο. Ο αριθμός των ενεργών κανόνων επηρεάζει την ταχύτητα και την ακρίβεια της σάρωσης.

    Πώς να γράψετε κανόνες για το Checkmarx χωρίς να τρελαίνεστεΡύθμιση Preset στη διεπαφή Checkmarx

  2. Οι κανόνες επεξεργάζονται σε ένα ειδικό εργαλείο που ονομάζεται CxAuditor. Αυτή είναι μια εφαρμογή επιτραπέζιου υπολογιστή που συνδέεται με έναν διακομιστή που εκτελεί το Checkmarx. Αυτό το εργαλείο έχει δύο τρόπους λειτουργίας: επεξεργασία κανόνων και ανάλυση των αποτελεσμάτων μιας ήδη πραγματοποιηθείσας σάρωσης.

    Πώς να γράψετε κανόνες για το Checkmarx χωρίς να τρελαίνεστεΔιεπαφή CxAudit

  3. Οι κανόνες στο Checkmarx χωρίζονται ανά γλώσσα, δηλαδή κάθε γλώσσα έχει το δικό της σύνολο ερωτημάτων. Υπάρχουν επίσης ορισμένοι γενικοί κανόνες που ισχύουν ανεξαρτήτως γλώσσας, αυτοί είναι τα λεγόμενα βασικά ερωτήματα. Ως επί το πλείστον, τα βασικά ερωτήματα περιλαμβάνουν την αναζήτηση πληροφοριών που χρησιμοποιούν άλλοι κανόνες.

    Πώς να γράψετε κανόνες για το Checkmarx χωρίς να τρελαίνεστεΔιαίρεση κανόνων ανά γλώσσα

  4. Οι κανόνες είναι "Εκτελέσιμοι" και "Μη Εκτελέσιμοι" (Εκτελέστηκαν και δεν Εκτελέστηκαν). Δεν είναι το σωστό όνομα, κατά τη γνώμη μου, αλλά αυτό είναι. Η ουσία είναι ότι το αποτέλεσμα της εκτέλεσης κανόνων "Εκτέλεσιμων" θα εμφανίζεται στα αποτελέσματα σάρωσης στη διεπαφή χρήστη και οι κανόνες "Μη εκτελέσιμοι" χρειάζονται μόνο για τη χρήση των αποτελεσμάτων τους σε άλλα αιτήματα (στην ουσία, απλώς μια συνάρτηση).

    Πώς να γράψετε κανόνες για το Checkmarx χωρίς να τρελαίνεστεΠροσδιορισμός του τύπου κανόνα κατά τη δημιουργία

  5. Μπορείτε να δημιουργήσετε νέους κανόνες ή να συμπληρώσετε/ξαναγράψετε υπάρχοντες. Για να ξαναγράψετε έναν κανόνα, πρέπει να τον βρείτε στο δέντρο, να κάνετε δεξί κλικ και να επιλέξετε "Παράκαμψη" από το αναπτυσσόμενο μενού. Είναι σημαντικό να θυμάστε εδώ ότι οι νέοι κανόνες δεν περιλαμβάνονται αρχικά στις προεπιλογές και δεν είναι ενεργοί. Για να αρχίσετε να τα χρησιμοποιείτε, πρέπει να τα ενεργοποιήσετε στο μενού "Preset Manager" στο όργανο. Οι νέοι κανόνες διατηρούν τις ρυθμίσεις τους, δηλαδή εάν ο κανόνας ήταν ενεργός, θα παραμείνει έτσι και θα εφαρμοστεί αμέσως.

    Πώς να γράψετε κανόνες για το Checkmarx χωρίς να τρελαίνεστεΠαράδειγμα νέου κανόνα στη διεπαφή Preset Manager

  6. Κατά την εκτέλεση, δημιουργείται ένα «δέντρο» αιτημάτων, το οποίο εξαρτάται από το τι. Οι κανόνες που συλλέγουν πληροφορίες εκτελούνται πρώτοι και αυτοί που τις χρησιμοποιούν δεύτερο. Το αποτέλεσμα της εκτέλεσης αποθηκεύεται στην κρυφή μνήμη, επομένως εάν είναι δυνατή η χρήση των αποτελεσμάτων ενός υπάρχοντος κανόνα, τότε είναι καλύτερα να το κάνετε, αυτό θα μειώσει τον χρόνο σάρωσης.

  7. Οι κανόνες μπορούν να εφαρμοστούν σε διαφορετικά επίπεδα:

  • Για ολόκληρο το σύστημα - θα χρησιμοποιηθεί για οποιαδήποτε σάρωση οποιουδήποτε έργου

  • Σε επίπεδο ομάδας (Ομάδα) - θα χρησιμοποιηθεί μόνο για τη σάρωση έργων στην επιλεγμένη ομάδα.

  • Σε επίπεδο έργου - Θα εφαρμοστεί σε συγκεκριμένο έργο

    Πώς να γράψετε κανόνες για το Checkmarx χωρίς να τρελαίνεστεΚαθορισμός του επιπέδου στο οποίο θα εφαρμοστεί ο κανόνας

"Λεξικό" για αρχάριους

Και θα ξεκινήσω με μερικά πράγματα που μου προκάλεσαν ερωτήσεις και θα δείξω επίσης μια σειρά από τεχνικές που θα απλοποιήσουν σημαντικά τη ζωή.

Λειτουργίες με λίστες

- вычитание одного из другого (list2 - list1)
* пересечение списков (list1 * list2)
+ сложение списков (list1 + list2)

& (логическое И) - объединяет списки по совпадению (list1 & list2), аналогично пересечению (list1 * list2)
| (логическое ИЛИ) - объединяет списки по широкому поиску (list1 | list2)

Со списками не работает:  ^  &&  ||  %  / 

Όλα τα αντικείμενα που βρέθηκαν

Μέσα στη σαρωμένη γλώσσα, μπορείτε να λάβετε μια λίστα με όλα τα στοιχεία που έχει εντοπίσει το Checkmarx (συμβολοσειρές, συναρτήσεις, κλάσεις, μεθόδους κ.λπ.). Αυτός είναι ένας χώρος αντικειμένων που είναι προσβάσιμος μέσω All. Δηλαδή να αναζητήσετε ένα αντικείμενο με συγκεκριμένο όνομα searchMe, μπορείτε να αναζητήσετε, για παράδειγμα, με όνομα σε όλα τα αντικείμενα που βρέθηκαν:

// Такой запрос выдаст все элементы
result = All;

// Такой запрос выдаст все элементы, в имени которых присутствует “searchMe“
result = All.FindByName("searchMe");

Ωστόσο, εάν χρειάζεται να κάνετε αναζήτηση σε άλλη γλώσσα που για κάποιο λόγο δεν συμπεριλήφθηκε στη σάρωση (για παράδειγμα, groovy σε ένα έργο Android), μπορείτε να επεκτείνετε τον χώρο των αντικειμένων μας μέσω μιας μεταβλητής:

result = AllMembers.All.FindByName("searchMe");

Λειτουργίες για ανάλυση ροής

Αυτές οι συναρτήσεις χρησιμοποιούνται σε πολλούς κανόνες και εδώ είναι ένα μικρό φύλλο εξαπάτησης του τι σημαίνουν:

// Какие данные second влияют на first.
// Другими словами - ТО (second) что влияет на  МЕНЯ (first).
result = first.DataInfluencedBy(second);

// Какие данные first влияют на second.
// Другими словами - Я (first) влияю на ТО (second).
result = first.DataInfluencingOn(second);

Λήψη ονόματος/διαδρομής αρχείου

Υπάρχουν πολλά χαρακτηριστικά που μπορούν να ληφθούν από τα αποτελέσματα ενός ερωτήματος (το όνομα του αρχείου στο οποίο βρέθηκε η καταχώρηση, συμβολοσειρά κ.λπ.), αλλά η τεκμηρίωση δεν αναφέρει πώς να τα αποκτήσετε και να τα χρησιμοποιήσετε. Έτσι, για να το κάνετε αυτό, πρέπει να αποκτήσετε πρόσβαση στην ιδιότητα LinePragma και τα αντικείμενα που χρειαζόμαστε θα βρίσκονται μέσα σε αυτήν:

// Для примера найдем все методы
CxList methods = Find_Methods();

// В методах найдем по имени метод scope
CxList scope = methods.FindByName("scope");

// Таким образом можо получить путь к файлу
string current_filename = scope.GetFirstGraph().LinePragma.FileName;

// А вот таким - строку, где нашлось срабатывание
int current_line = scope.GetFirstGraph().LinePragma.Line;

// Эти параметры можно использовать по разному
// Например получить все объекты в файле
CxList inFile = All.FindByFileName(current_filename);

// Или найти что происходит в конкретной строке
CxList inLine = inFile.FindByPosition(current_line);

Αξίζει να το έχετε υπόψη σας FileName περιέχει στην πραγματικότητα τη διαδρομή προς το αρχείο, αφού χρησιμοποιήσαμε τη μέθοδο GetFirstGraph.

Αποτέλεσμα εκτέλεσης

Υπάρχει μια ειδική μεταβλητή μέσα στο CxQL result, το οποίο επιστρέφει το αποτέλεσμα της εκτέλεσης του γραπτού κανόνα σας. Αρχικοποιείται αμέσως και μπορείτε να γράψετε ενδιάμεσα αποτελέσματα σε αυτό, αλλάζοντας και βελτιώνοντάς τα καθώς εργάζεστε. Αλλά, εάν δεν υπάρχει ανάθεση σε αυτήν τη μεταβλητή ή συνάρτηση μέσα στον κανόνα return— το αποτέλεσμα εκτέλεσης θα είναι πάντα μηδέν.

Το ακόλουθο ερώτημα δεν θα μας επιστρέψει τίποτα ως αποτέλεσμα της εκτέλεσης και θα είναι πάντα κενό:

// Находим элементы foo
CxList libraries = All.FindByName("foo");

Αλλά, έχοντας αντιστοιχίσει το αποτέλεσμα εκτέλεσης στο αποτέλεσμα της μαγικής μεταβλητής, θα δούμε τι μας επιστρέφει αυτή η κλήση:

// Находим элементы foo
CxList libraries = All.FindByName("foo");

// Выводим, как результат выполнения правила
result = libraries

// Или еще короче
result = All.FindByName("foo");

Χρησιμοποιώντας τα αποτελέσματα άλλων κανόνων

Οι κανόνες στο Checkmarx μπορούν να ονομαστούν ανάλογοι με τις συναρτήσεις σε μια κανονική γλώσσα προγραμματισμού. Όταν γράφετε έναν κανόνα, μπορείτε να χρησιμοποιήσετε τα αποτελέσματα άλλων ερωτημάτων. Για παράδειγμα, δεν χρειάζεται να κάνετε αναζήτηση για όλες τις κλήσεις μεθόδου στον κώδικα κάθε φορά, απλώς καλέστε τον επιθυμητό κανόνα:

// Получаем результат выполнения другого правила
CxList methods = Find_Methods();

// Ищем внутри метод foo. 
// Второй параметр false означает, что ищем без чувствительности к регистру
result = methods.FindByShortName("foo", false);

Αυτή η προσέγγιση σάς επιτρέπει να συντομεύσετε τον κώδικα και να μειώσετε σημαντικά τον χρόνο εκτέλεσης του κανόνα.

Λύση προβλημάτων

Ξύλευση

Όταν εργάζεστε με το εργαλείο, μερικές φορές δεν είναι δυνατό να γράψετε αμέσως το επιθυμητό ερώτημα και πρέπει να πειραματιστείτε, δοκιμάζοντας διαφορετικές επιλογές. Για μια τέτοια περίπτωση, το εργαλείο παρέχει καταγραφή, η οποία ονομάζεται ως εξής:

// Находим что-то
CxList toLog = All.FindByShortName("log");

// Формируем строку и отправляем в лог
cxLog.WriteDebugMessage (“number of DOM elements =” + All.Count);

Αλλά αξίζει να θυμόμαστε ότι αυτή η μέθοδος δέχεται μόνο ως είσοδο σειρά, επομένως δεν θα είναι δυνατή η εμφάνιση μιας πλήρους λίστας των στοιχείων που βρέθηκαν ως αποτέλεσμα της πρώτης λειτουργίας. Η δεύτερη επιλογή, η οποία χρησιμοποιείται για τον εντοπισμό σφαλμάτων, είναι η ανάθεση σε μια μαγική μεταβλητή από καιρό σε καιρό result το αποτέλεσμα του ερωτήματος και δείτε τι συμβαίνει. Αυτή η προσέγγιση δεν είναι πολύ βολική· πρέπει να βεβαιωθείτε ότι δεν υπάρχουν παρακάμψεις ή λειτουργίες με αυτό στον κώδικα μετά result ή απλά σχολιάστε τον παρακάτω κώδικα. Ή μπορείτε, όπως εγώ, να ξεχάσετε να αφαιρέσετε πολλές τέτοιες κλήσεις από έναν έτοιμο κανόνα και να αναρωτηθείτε γιατί τίποτα δεν λειτουργεί.

Ένας πιο βολικός τρόπος είναι να καλέσετε τη μέθοδο return με την απαιτούμενη παράμετρο. Σε αυτήν την περίπτωση, η εκτέλεση του κανόνα θα τελειώσει και θα μπορούμε να δούμε τι συνέβη ως αποτέλεσμα αυτού που γράψαμε:

// Находим что-то
CxList toLog = All.FindByShortName("log");

// Выводим результат выполнения
return toLog

//Все, что написано дальше не будет выполнено
result = All.DataInfluencedBy(toLog)

Πρόβλημα σύνδεσης

Υπάρχουν περιπτώσεις όπου δεν μπορείτε να αποκτήσετε πρόσβαση στο εργαλείο CxAudit (το οποίο χρησιμοποιείται για τη σύνταξη κανόνων). Μπορεί να υπάρχουν πολλοί λόγοι για αυτό, συμπεριλαμβανομένων σφαλμάτων, ξαφνικών ενημερώσεων των Windows, BSOD και άλλων απρόβλεπτων καταστάσεων που είναι πέρα ​​από τον έλεγχό μας. Σε αυτήν την περίπτωση, μερικές φορές υπάρχει μια ημιτελής συνεδρία στη βάση δεδομένων, η οποία σας εμποδίζει να συνδεθείτε ξανά. Για να το διορθώσετε, πρέπει να εκτελέσετε πολλά ερωτήματα:

Για το Checkmarx πριν από το 8.6:

// Проверяем, что есть залогиненые пользователи, выполнив запрос в БД
SELECT COUNT(*) FROM [CxDB].[dbo].LoggedinUser WHERE [ClientType] = 6;
 
// Если что-то есть, а на самом деле даже если и нет, попробовать выполнить запрос
DELETE FROM [CxDB].[dbo].LoggedinUser WHERE [ClientType] = 6;

Για το Checkmarx μετά το 8.6:

// Проверяем, что есть залогиненые пользователи, выполнив запрос в БД
SELECT COUNT(*) FROM LoggedinUser WHERE (ClientType = 'Audit');
 
// Если что-то есть, а на самом деле даже если и нет, попробовать выполнить запрос
DELETE FROM [CxDB].[dbo].LoggedinUser WHERE (ClientType = 'Audit');

Κανόνες γραφής

Τώρα φτάνουμε στο πιο ενδιαφέρον κομμάτι. Όταν ξεκινάτε να γράφετε κανόνες στο CxQL, αυτό που σας λείπει συχνά δεν είναι τόσο πολλή τεκμηρίωση όσο μερικά ζωντανά παραδείγματα επίλυσης ορισμένων προβλημάτων και περιγραφής της διαδικασίας λειτουργίας ερωτήματος γενικά.

Θα προσπαθήσω να κάνω τη ζωή λίγο πιο εύκολη για όσους αρχίζουν να βυθίζονται στη γλώσσα ερωτημάτων και θα δώσω πολλά παραδείγματα χρήσης προσαρμοσμένων ερωτημάτων για την επίλυση ορισμένων προβλημάτων. Μερικά από αυτά είναι αρκετά γενικά και μπορούν να χρησιμοποιηθούν στην εταιρεία σας πρακτικά χωρίς αλλαγές, άλλα είναι πιο συγκεκριμένα, αλλά μπορούν επίσης να χρησιμοποιηθούν αλλάζοντας τον κώδικα ώστε να ταιριάζει στις ιδιαιτερότητες των εφαρμογών σας.

Λοιπόν, εδώ είναι τα προβλήματα που αντιμετωπίζουμε πιο συχνά:

Εργασία: Υπάρχουν πολλές Ροές στα αποτελέσματα της εκτέλεσης του κανόνα και το ένα από αυτά είναι φωλιά ενός άλλου, πρέπει να αφήσετε ένα από αυτά.

λύση: Πράγματι, μερικές φορές το Checkmarx εμφανίζει πολλές ροές δεδομένων που μπορεί να επικαλύπτονται και να είναι μια συντομευμένη έκδοση άλλων. Υπάρχει ειδική μέθοδος για τέτοιες περιπτώσεις ReduceFlow. Ανάλογα με την παράμετρο, θα επιλέξει τη συντομότερη ή τη μεγαλύτερη ροή:

// Оставить только длинные Flow
result = result.ReduceFlow(CxList.ReduceFlowType.ReduceSmallFlow);

// Оставить только короткие Flow
result = result.ReduceFlow(CxList.ReduceFlowType.ReduceBigFlow);

Εργασία: Αναπτύξτε τη λίστα των ευαίσθητων δεδομένων στα οποία αντιδρά το εργαλείο

λύση: Το Checkmarx έχει βασικούς κανόνες, τα αποτελέσματα των οποίων χρησιμοποιούνται από πολλά άλλα ερωτήματα. Συμπληρώνοντας ορισμένους από αυτούς τους κανόνες με δεδομένα ειδικά για την εφαρμογή σας, μπορείτε να βελτιώσετε αμέσως τα αποτελέσματα σάρωσης. Ακολουθεί ένα παράδειγμα κανόνα για να ξεκινήσετε:

General_privacy_violation_list

Ας προσθέσουμε πολλές μεταβλητές που χρησιμοποιούνται στην εφαρμογή μας για την αποθήκευση ευαίσθητων πληροφοριών:

// Получаем результат выполнения базового правила
result = base.General_privacy_violation_list();

// Ищем элементы, которые попадают под простые регулярные выражения. Можно дополнить характерными для вас паттернами.
CxList personalList = All.FindByShortNames(new List<string> {
	"*securityToken*", "*sessionId*"}, false);

// Добавляем к конечному результату
result.Add(personalList);

Εργασία: Αναπτύξτε τη λίστα μεταβλητών με κωδικούς πρόσβασης

λύση: Θα συνιστούσα να δώσετε αμέσως προσοχή στον βασικό κανόνα για τον ορισμό κωδικών πρόσβασης σε κώδικα και να προσθέσετε σε αυτόν μια λίστα με ονόματα μεταβλητών που χρησιμοποιούνται συνήθως στην εταιρεία σας.

Password_privacy_violation_list

CxList allStrings = All.FindByType("String"); 
allStrings.Add(All.FindByType(typeof(StringLiteral))); 
allStrings.Add(Find_UnknownReference());
allStrings.Add(All.FindByType(typeof (Declarator)));
allStrings.Add(All.FindByType(typeof (MemberAccess)));
allStrings.Add(All.FindByType(typeof(EnumMemberDecl))); 
allStrings.Add(Find_Methods().FindByShortName("get*"));

// Дополняем дефолтный список переменных
List < string > pswdIncludeList = new List<string>{"*password*", "*psw", "psw*", "pwd*", "*pwd", "*authKey*", "pass*", "cipher*", "*cipher", "pass", "adgangskode", "benutzerkennwort", "chiffre", "clave", "codewort", "contrasena", "contrasenya", "geheimcode", "geslo", "heslo", "jelszo", "kennwort", "losenord", "losung", "losungswort", "lozinka", "modpas", "motdepasse", "parol", "parola", "parole", "pasahitza", "pasfhocal", "passe", "passord", "passwort", "pasvorto", "paswoord", "salasana", "schluessel", "schluesselwort", "senha", "sifre", "wachtwoord", "wagwoord", "watchword", "zugangswort", "PAROLACHIAVE", "PAROLA CHIAVE", "PAROLECHIAVI", "PAROLE CHIAVI", "paroladordine", "verschluesselt", "sisma",
                "pincode",
								"pin"};
								
List < string > pswdExcludeList = new List<string>{"*pass", "*passable*", "*passage*", "*passenger*", "*passer*", "*passing*", "*passion*", "*passive*", "*passover*", "*passport*", "*passed*", "*compass*", "*bypass*", "pass-through", "passthru", "passthrough", "passbytes", "passcount", "passratio"};

CxList tempResult = allStrings.FindByShortNames(pswdIncludeList, false);
CxList toRemove = tempResult.FindByShortNames(pswdExcludeList, false);
tempResult -= toRemove;
tempResult.Add(allStrings.FindByShortName("pass", false));

foreach (CxList r in tempResult)
{
	CSharpGraph g = r.data.GetByIndex(0) as CSharpGraph;
	if(g != null && g.ShortName != null && g.ShortName.Length < 50)
	{
		result.Add(r);
	}
}

Εργασία: Προσθέστε χρησιμοποιημένα πλαίσια που δεν υποστηρίζονται από το Checkmarx

λύση: Όλα τα ερωτήματα στο Checkmarx χωρίζονται ανά γλώσσα, επομένως πρέπει να προσθέσετε κανόνες για κάθε γλώσσα. Παρακάτω είναι μερικά παραδείγματα τέτοιων κανόνων.

Εάν χρησιμοποιούνται βιβλιοθήκες που συμπληρώνουν ή αντικαθιστούν την τυπική λειτουργικότητα, μπορούν εύκολα να προστεθούν στον βασικό κανόνα. Στη συνέχεια, όλοι όσοι το χρησιμοποιούν θα μάθουν αμέσως για τις νέες εισαγωγές. Για παράδειγμα, οι βιβλιοθήκες για τη σύνδεση στο Android είναι η Timber και η Loggi. Στο βασικό πακέτο, δεν υπάρχουν κανόνες για τον εντοπισμό κλήσεων εκτός συστήματος, επομένως εάν εισέλθει ένας κωδικός πρόσβασης ή ένα αναγνωριστικό περιόδου σύνδεσης στο αρχείο καταγραφής, δεν θα το γνωρίζουμε. Ας προσπαθήσουμε να προσθέσουμε ορισμούς τέτοιων μεθόδων στους κανόνες του Checkmarx.

Δοκιμαστικό παράδειγμα κώδικα που χρησιμοποιεί τη βιβλιοθήκη Timber για την καταγραφή:

package com.death.timberdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import timber.log.Timber;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Timber.e("Error Message");
        Timber.d("Debug Message");

        Timber.tag("Some Different tag").e("And error message");
    }
}

Και εδώ είναι ένα παράδειγμα ενός αιτήματος για το Checkmarx, το οποίο θα σας επιτρέψει να προσθέσετε έναν ορισμό των μεθόδων κλήσης Timber ως σημείο εξόδου για δεδομένα από την εφαρμογή:

FindAndroidOutputs

// Получаем результат выполнения базового правила
result = base.Find_Android_Outputs();

// Дополняем вызовами, которые приходят из библиотеки Timber
CxList timber = All.FindByExactMemberAccess("Timber.*") +
    All.FindByShortName("Timber").GetMembersOfTarget();

// Добавляем к конечному результату
result.Add(timber);

Και μπορείτε επίσης να προσθέσετε στον γειτονικό κανόνα, αλλά αυτός σχετίζεται άμεσα με τη σύνδεση στο Android:

FindAndroidLog_Outputs

// Получаем результат выполнения базового правила
result = base.Find_Android_Log_Outputs();

// Дополняем вызовами, которые приходят из библиотеки Timber
result.Add(
  All.FindByExactMemberAccess("Timber.*") +
  All.FindByShortName("Timber").GetMembersOfTarget()
);

Επίσης, εάν χρησιμοποιούν εφαρμογές Android WorkManager για ασύγχρονη εργασία, είναι καλή ιδέα να ενημερώσετε επιπλέον τον Checkmarx σχετικά με αυτό προσθέτοντας μια μέθοδο για τη λήψη δεδομένων από την εργασία getInputData:

FindAndroidRead

// Получаем результат выполнения базового правила
result = base.Find_Android_Read();

// Дополняем вызовом функции getInputData, которая используется в WorkManager
CxList getInputData = All.FindByShortName("getInputData");

// Добавляем к конечному результату
result.Add(getInputData.GetMembersOfTarget());

Εργασία: Αναζήτηση ευαίσθητων δεδομένων στο plist για έργα iOS

λύση: Το iOS χρησιμοποιεί συχνά ειδικά αρχεία με την επέκταση .plist για την αποθήκευση διαφόρων μεταβλητών και τιμών. Η αποθήκευση κωδικών πρόσβασης, διακριτικών, κλειδιών και άλλων ευαίσθητων δεδομένων σε αυτά τα αρχεία δεν συνιστάται, καθώς μπορούν να εξαχθούν από τη συσκευή χωρίς κανένα πρόβλημα.

Τα αρχεία Plist έχουν χαρακτηριστικά που δεν είναι εμφανή με γυμνό μάτι, αλλά είναι σημαντικά για το Checkmarx. Ας γράψουμε έναν κανόνα που θα αναζητά τα δεδομένα που χρειαζόμαστε και θα μας λέει αν αναφέρονται κάπου κωδικοί πρόσβασης ή διακριτικά.

Ένα παράδειγμα τέτοιου αρχείου, το οποίο περιέχει ένα διακριτικό για επικοινωνία με την υπηρεσία υποστήριξης:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>DeviceDictionary</key>
	<dict>
		<key>phone</key>
		<string>iPhone 6s</string>
	</dict>
	<key>privatekey</key>
	<string>MIICXAIBAAKBgQCqGKukO1De7zhZj6+</string>
</dict>
</plist>

Και ένας κανόνας για το Checkmarx, ο οποίος έχει πολλές αποχρώσεις που πρέπει να ληφθούν υπόψη κατά τη σύνταξη:

// Используем результат выполнения правила по поиску файлов plist, чтобы уменьшить время работы правила и 
CxList plist = Find_Plist_Elements();

// Инициализируем новую переменную
CxList dictionarySettings = All.NewCxList();

// Теперь добавим поиск всех интересующих нас значений. В дальнейшем можно расширять этот список.
// Для поиска значений, как ни странно, используется FindByMemberAccess - поиск обращений к методам. Второй параметр внутри функции, false, означает, что поиск нечувствителен к регистру
dictionarySettings.Add(plist.FindByMemberAccess("privatekey", false));
dictionarySettings.Add(plist.FindByMemberAccess("privatetoken", false));

// Для корректного поиска из-за особенностей структуры plist - нужно искать по типу "If statement"
CxList ifStatements = plist.FindByType(typeof(IfStmt));

// Добавляем в результат, перед этим получив родительский узел - для правильного отображения
result = dictionarySettings.FindByFathers(ifStatements);

Εργασία: Εύρεση πληροφοριών σε XML

λύση: Το Checkmarx έχει πολύ βολικές λειτουργίες για εργασία με XML και αναζήτηση τιμών, ετικετών, χαρακτηριστικών και άλλων. Αλλά, δυστυχώς, υπήρξε ένα σφάλμα στην τεκμηρίωση λόγω του οποίου δεν λειτουργεί ούτε ένα παράδειγμα. Παρά το γεγονός ότι αυτό το ελάττωμα έχει εξαλειφθεί στην τελευταία έκδοση της τεκμηρίωσης, να είστε προσεκτικοί εάν χρησιμοποιείτε προηγούμενες εκδόσεις εγγράφων.

Ακολουθεί ένα εσφαλμένο παράδειγμα από την τεκμηρίωση:

// Код работать не будет
result = All.FindXmlAttributesByNameAndValue("*.app", 8, “id”, "error- section", false, true);

Ως αποτέλεσμα της προσπάθειας εκτέλεσης, θα λάβουμε ένα σφάλμα που All δεν υπάρχει τέτοια μέθοδος... Και αυτό είναι αλήθεια, αφού υπάρχει ένας ειδικός, ξεχωριστός χώρος αντικειμένων για τη χρήση συναρτήσεων για εργασία με XML - cxXPath. Έτσι φαίνεται το σωστό ερώτημα για να βρείτε μια ρύθμιση στο Android που επιτρέπει τη χρήση της επισκεψιμότητας HTTP:

// Правильный вариант с использованием cxXPath
result = cxXPath.FindXmlAttributesByNameAndValue("*.xml", 8, "cleartextTrafficPermitted", "true", false, true);

Ας το δούμε λίγο πιο αναλυτικά, αφού η σύνταξη για όλες τις συναρτήσεις είναι παρόμοια, αφού καταλάβετε μία, τότε απλά πρέπει να επιλέξετε αυτήν που χρειάζεστε. Έτσι, διαδοχικά σύμφωνα με τις παραμέτρους:

  • "*.xml"— μάσκα αρχείων προς αναζήτηση

  • 8 — αναγνωριστικό της γλώσσας για την οποία εφαρμόζεται ο κανόνας

  • "cleartextTrafficPermitted"— όνομα χαρακτηριστικού σε xml

  • "true" — την τιμή αυτού του χαρακτηριστικού

  • false — χρήση κανονικής έκφρασης κατά την αναζήτηση

  • true — σημαίνει ότι η αναζήτηση θα πραγματοποιηθεί αγνοώντας πεζά και πεζά, δηλαδή χωρίς διάκριση πεζών-κεφαλαίων

Για παράδειγμα, χρησιμοποιήσαμε έναν κανόνα που προσδιορίζει εσφαλμένες, από άποψη ασφάλειας, ρυθμίσεις σύνδεσης δικτύου στο Android που επιτρέπουν την επικοινωνία με τον διακομιστή μέσω του πρωτοκόλλου HTTP. Παράδειγμα ρύθμισης που περιέχει ένα χαρακτηριστικό cleartextTrafficPermitted με το νόημα true:

<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">example.com</domain>
        <trust-anchors>
            <certificates src="@raw/my_ca"/>
        </trust-anchors>
        <domain-config cleartextTrafficPermitted="true">
            <domain includeSubdomains="true">secure.example.com</domain>
        </domain-config>
    </domain-config>
</network-security-config>

Εργασία: Περιορίστε τα αποτελέσματα κατά όνομα/διαδρομή αρχείου

λύση: Σε ένα από τα μεγάλα έργα που σχετίζονται με την ανάπτυξη μιας εφαρμογής για κινητά για Android, συναντήσαμε ψευδώς θετικά στοιχεία του κανόνα που καθορίζει τη ρύθμιση της συσκότισης. Το γεγονός είναι ότι ο κανόνας εκτός πλαισίου αναζητά στο αρχείο build.gradle μια ρύθμιση υπεύθυνη για την εφαρμογή κανόνων συσκότισης για την έκδοση έκδοσης της εφαρμογής.

Αλλά σε μεγάλα έργα μερικές φορές υπάρχουν παιδικά αρχεία build.gradle, που αναφέρονται στις βιβλιοθήκες που περιλαμβάνονται στο έργο. Η ιδιαιτερότητα είναι ότι ακόμη και αν αυτά τα αρχεία δεν υποδεικνύουν την ανάγκη για συσκότιση, οι ρυθμίσεις του αρχείου γονικής συγκρότησης θα εφαρμοστούν κατά τη μεταγλώττιση.

Έτσι, το καθήκον είναι να αποκοπούν οι ενεργοποιητές σε θυγατρικά αρχεία που ανήκουν σε βιβλιοθήκες. Μπορούν να αναγνωριστούν από την παρουσία της γραμμής apply 'com.android.library'.

Παράδειγμα κώδικα από αρχείο build.gradle, το οποίο καθορίζει την ανάγκη για συσκότιση:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.2"
    defaultConfig {
        ...
    }

    buildTypes {
        release {
            minifyEnabled true
            ...
        }
    }
}

dependencies {
  ...
}

Παράδειγμα αρχείου build.gradle για μια βιβλιοθήκη που περιλαμβάνεται στο έργο που δεν έχει αυτήν τη ρύθμιση:

apply plugin: 'android-library'

dependencies {
  compile 'com.android.support:support-v4:18.0.+'
}

android {
  compileSdkVersion 14
  buildToolsVersion '17.0.0'
  ...
}

Και ο κανόνας για το Checkmarx:

ProGuardObfuscationNotInUse

// Поиск метода release среди всех методов в Gradle файлах
CxList releaseMethod = Find_Gradle_Method("release");

// Все объекты из файлов build.gradle
CxList gradleBuildObjects = Find_Gradle_Build_Objects();

// Поиск того, что находится внутри метода "release" среди всех объектов из файлов build.gradle
CxList methodInvokesUnderRelease = gradleBuildObjects.FindByType(typeof(MethodInvokeExpr)).GetByAncs(releaseMethod);

// Ищем внутри gradle-файлов строку "com.android.library" - это значит, что данный файл относится к библиотеке и его необходимо исключить из правила
CxList android_library = gradleBuildObjects.FindByName("com.android.library");

// Инициализация пустого массива
List<string> libraries_path = new List<string> {};

// Проходим через все найденные "дочерние" файлы
foreach(CxList library in android_library)
{
    // Получаем путь к каждому файлу
	string file_name_library = library.GetFirstGraph().LinePragma.FileName;
    
    // Добавляем его в наш массив
	libraries_path.Add(file_name_library);
}

// Ищем все вызовы включения обфускации в релизных настройках
CxList minifyEnabled = methodInvokesUnderRelease.FindByShortName("minifyEnabled");

// Получаем параметры этих вызовов
CxList minifyValue = gradleBuildObjects.GetParameters(minifyEnabled, 0);

// Ищем среди них включенные
CxList minifyValueTrue = minifyValue.FindByShortName("true");

// Немного магии, если не нашли стандартным способом :D
if (minifyValueTrue.Count == 0) {
	minifyValue = minifyValue.FindByAbstractValue(abstractValue => abstractValue is TrueAbstractValue);
} else {
    // А если всё-таки нашли, то предыдущий результат и оставляем
	minifyValue = minifyValueTrue;	
}

// Если не нашлось таких методов
if (minifyValue.Count == 0)
{
    // Для более корректного отображения места срабатывания в файле ищем или buildTypes или android
	CxList tempResult = All.NewCxList();
	CxList buildTypes = Find_Gradle_Method("buildTypes");
	if (buildTypes.Count > 0) {
		tempResult = buildTypes;
	} else {
		tempResult = Find_Gradle_Method("android");
	}
	
	// Для каждого из найденных мест срабатывания проходим и определяем, дочерний или основной файлы сборки
	foreach(CxList res in tempResult)
	{
        // Определяем, в каком файле был найден buildType или android методы
		string file_name_result = res.GetFirstGraph().LinePragma.FileName;
        
        // Если такого файла нет в нашем списке "дочерних" файлов - значит это основной файл и его можно добавить в результат
		if (libraries_path.Contains(file_name_result) == false){
			result.Add(res);
		}
	}
}

Αυτή η προσέγγιση μπορεί να είναι αρκετά καθολική και χρήσιμη όχι μόνο για εφαρμογές Android, αλλά και για άλλες περιπτώσεις που πρέπει να προσδιορίσετε εάν ένα αποτέλεσμα ανήκει σε ένα συγκεκριμένο αρχείο.

Εργασία: Προσθέστε υποστήριξη για βιβλιοθήκη τρίτου μέρους εάν η σύνταξη δεν υποστηρίζεται πλήρως

λύση: Ο αριθμός των διαφόρων πλαισίων που χρησιμοποιούνται στη διαδικασία σύνταξης κώδικα είναι απλώς εκτός γραφημάτων. Φυσικά, ο Checkmarx δεν γνωρίζει πάντα για την ύπαρξή τους και καθήκον μας είναι να του μάθουμε να κατανοεί ότι ορισμένες μέθοδοι ανήκουν ειδικά σε αυτό το πλαίσιο. Μερικές φορές αυτό περιπλέκεται από το γεγονός ότι τα πλαίσια χρησιμοποιούν ονόματα συναρτήσεων που είναι πολύ κοινά και είναι αδύνατο να προσδιοριστεί με σαφήνεια η σχέση μιας συγκεκριμένης κλήσης με μια συγκεκριμένη βιβλιοθήκη.

Η δυσκολία είναι ότι η σύνταξη τέτοιων βιβλιοθηκών δεν αναγνωρίζεται πάντα σωστά και πρέπει να πειραματιστείτε για να αποφύγετε να λάβετε μεγάλο αριθμό ψευδώς θετικών. Υπάρχουν πολλές επιλογές για τη βελτίωση της ακρίβειας σάρωσης και την επίλυση του προβλήματος:

  • Η πρώτη επιλογή, γνωρίζουμε με βεβαιότητα ότι η βιβλιοθήκη χρησιμοποιείται σε ένα συγκεκριμένο έργο και μπορεί να εφαρμόσει τον κανόνα σε επίπεδο ομάδας. Αλλά εάν η ομάδα αποφασίσει να ακολουθήσει μια διαφορετική προσέγγιση ή χρησιμοποιήσει πολλές βιβλιοθήκες στις οποίες τα ονόματα των συναρτήσεων επικαλύπτονται, μπορούμε να έχουμε μια όχι πολύ ευχάριστη εικόνα πολλών ψευδών θετικών στοιχείων

  • Η δεύτερη επιλογή είναι να αναζητήσετε αρχεία στα οποία η βιβλιοθήκη έχει σαφώς εισαχθεί. Με αυτήν την προσέγγιση, μπορούμε να είμαστε σίγουροι ότι η βιβλιοθήκη που χρειαζόμαστε χρησιμοποιείται ακριβώς σε αυτό το αρχείο.

  • Και η τρίτη επιλογή είναι να χρησιμοποιήσετε τις δύο παραπάνω προσεγγίσεις μαζί.

Για παράδειγμα, ας δούμε μια βιβλιοθήκη πολύ γνωστή σε στενούς κύκλους λείος για τη γλώσσα προγραμματισμού Scala, δηλαδή τη λειτουργικότητα Συναρμολόγηση κυριολεκτικών τιμών. Γενικά, για να μεταβιβάσετε παραμέτρους σε ένα ερώτημα SQL, πρέπει να χρησιμοποιήσετε τον τελεστή $, το οποίο αντικαθιστά τα δεδομένα σε ένα προσχηματισμένο ερώτημα SQL. Αυτό είναι, στην πραγματικότητα, ένα άμεσο ανάλογο του Prepared Statement σε Java. Αλλά, εάν χρειάζεται να δημιουργήσετε δυναμικά ένα ερώτημα SQL, για παράδειγμα, εάν πρέπει να μεταβιβάσετε ονόματα πινάκων, μπορείτε να χρησιμοποιήσετε τον τελεστή #$, το οποίο θα αντικαταστήσει απευθείας τα δεδομένα στο ερώτημα (σχεδόν σαν συνένωση συμβολοσειρών).

Παράδειγμα κώδικα:

// В общем случае - значения, контролируемые пользователем
val table = "coffees"
sql"select * from #$table where name = $name".as[Coffee].headOption

Ο Checkmarx δεν γνωρίζει ακόμη πώς να ανιχνεύσει τη χρήση του Splicing Literal Values ​​και παρακάμπτει τους τελεστές #$, οπότε ας προσπαθήσουμε να το διδάξουμε να αναγνωρίζει πιθανές ενέσεις SQL και να επισημαίνει τα σωστά σημεία στον κώδικα:

// Находим все импорты
CxList imports = All.FindByType(typeof(Import));

// Ищем по имени, есть ли в импортах slick
CxList slick = imports.FindByShortName("slick");

// Некоторый флаг, определяющий, что импорт библиотеки в коде присутствует
// Для более точного определения - можно применить подход с именем файла
bool not_empty_list = false;
foreach (CxList r in slick)
{
    // Если встретили импорт, считаем, что slick используется
	not_empty_list = true;
}

if (not_empty_list) {
    // Ищем вызовы, в которые передается SQL-строка
	CxList sql = All.FindByShortName("sql");
	sql.Add(All.FindByShortName("sqlu"));
	
	// Определяем данные, которые попадают в эти вызовы
	CxList data_sql = All.DataInfluencingOn(sql);
	
	// Так как синтакис не поддерживается, можно применить подход с регулярными выражениями
	// RegExp стоит использовать крайне осторожно и не применять его на большом количестве данных, так как это может сильно повлиять на производительность
	CxList find_possible_inj = data_sql.FindByRegex(@"#$", true, true, true);

    // Избавляемся от лишних срабатываний, если они есть и выводим в результат
	result = find_possible_inj.FindByType(typeof(BinaryExpr));
}

Εργασία: Αναζήτηση για χρησιμοποιημένες ευπαθείς συναρτήσεις σε βιβλιοθήκες ανοιχτού κώδικα

λύση: Πολλές εταιρείες χρησιμοποιούν εργαλεία παρακολούθησης ανοιχτού κώδικα (πρακτική OSA) για να ανιχνεύσουν τη χρήση ευάλωτων εκδόσεων βιβλιοθηκών σε ανεπτυγμένες εφαρμογές. Μερικές φορές δεν είναι δυνατή η ενημέρωση μιας τέτοιας βιβλιοθήκης σε ασφαλή έκδοση. Σε ορισμένες περιπτώσεις υπάρχουν λειτουργικοί περιορισμοί, σε άλλες δεν υπάρχει καθόλου ασφαλής έκδοση. Σε αυτήν την περίπτωση, ένας συνδυασμός πρακτικών SAST και OSA θα βοηθήσει να καθοριστεί ότι οι λειτουργίες που οδηγούν στην εκμετάλλευση της ευπάθειας δεν χρησιμοποιούνται στον κώδικα.

Αλλά μερικές φορές, ειδικά όταν εξετάζετε το JavaScript, αυτό μπορεί να μην είναι μια εντελώς ασήμαντη εργασία. Παρακάτω είναι μια λύση, ίσως όχι ιδανική, αλλά εντούτοις λειτουργική, χρησιμοποιώντας το παράδειγμα των τρωτών σημείων στο στοιχείο lodash σε μεθόδους template и *set.

Παραδείγματα δοκιμής δυνητικά ευάλωτου κώδικα σε αρχείο JS:

/**
 * Template example
 */

'use strict';
var _ = require("./node_modules/lodash.js");


// Use the "interpolate" delimiter to create a compiled template.
var compiled = _.template('hello <%= js %>!');
console.log(compiled({ 'js': 'lodash' }));
// => 'hello lodash!'

// Use the internal `print` function in "evaluate" delimiters.

var compiled = _.template('<% print("hello " + js); %>!');
console.log(compiled({ 'js': 'lodash' }));
// => 'hello lodash!'

Και όταν συνδέεστε απευθείας σε html:

<!DOCTYPE html>
<html>
<head>
    <title>Lodash Tutorial</title>
    <script src="./node_modules/lodash.js"></script>
    <script type="text/javascript">
  // Lodash chunking array
        nums = [1, 2, 3, 4, 5, 6, 7, 8, 9];

        let c1 = _.template('<% print("hello " + js); %>!');
        console.log(c1);

        let c2 = _.template('<% print("hello " + js); %>!');
        console.log(c2);
    </script>
</head>
<body></body>
</html>

Αναζητούμε όλες τις ευάλωτες μεθόδους μας, οι οποίες αναφέρονται στις ευπάθειες:

// Ищем все строки: в которых встречается строка lodash (предполагаем, что это объявление импорта библиотеки
CxList lodash_strings = Find_String_Literal().FindByShortName("*lodash*");

// Ищем все данные: которые взаимодействуют с этими строками
CxList data_on_lodash = All.InfluencedBy(lodash_strings);


// Задаем список уязвимых методов
List<string> vulnerable_methods = new List<string> {"template", "*set"};

// Ищем все наши уязвимые методы, которые перечисленны в уязвимостях и отфильтровываем их только там, где они вызывались
CxList vulnerableMethods = All.FindByShortNames(vulnerable_methods).FindByType(typeof(MethodInvokeExpr));

//Находим все данные: которые взаимодействуют с данными методами
CxList vulnFlow = All.InfluencedBy(vulnerableMethods);

// Если есть пересечение по этим данным - кладем в результат
result = vulnFlow * data_on_lodash;

// Формируем список путей по которым мы уже прошли, чтобы фильтровать в дальнейшем дубли
List<string> lodash_result_path = new List<string> {};

foreach(CxList lodash_result in result)
{
    // Очередной раз получаем пути к файлам
	string file_name = lodash_result.GetFirstGraph().LinePragma.FileName;
	lodash_result_path.Add(file_name);
}

// Дальше идет часть относящаяся к html файлам, так как в них мы не можем проследить откуда именно идет вызов
// Формируем массив путей файлов, чтобы быть уверенными, что срабатывания уязвимых методов были именно в тех файлах, в которых объявлен lodash
List<string> lodash_path = new List<string> {};
foreach(CxList string_lodash in lodash_strings)
{
	string file_name = string_lodash.GetFirstGraph().LinePragma.FileName;
	lodash_path.Add(file_name);
}

// Перебираем все уязвимые методы и убеждаемся, что они вызваны в тех же файлах, что и объявление/включение lodash
foreach(CxList method in vulnerableMethods)
{
	string file_name_method = method.GetFirstGraph().LinePragma.FileName;
	if (lodash_path.Contains(file_name_method) == true && lodash_result_path.Contains(file_name_method) == false){
		result.Add(method);
	}
}

// Убираем все UknownReferences и оставляем самый "длинный" из путей, если такие встречаются
result = result.ReduceFlow(CxList.ReduceFlowType.ReduceSmallFlow) - result.FindByType(typeof(UnknownReference));

Εργασία: Αναζήτηση πιστοποιητικών που είναι ενσωματωμένα στην εφαρμογή

λύση: Δεν είναι ασυνήθιστο για εφαρμογές, ειδικά για φορητές συσκευές, να χρησιμοποιούν πιστοποιητικά ή κλειδιά για πρόσβαση σε διάφορους διακομιστές ή επαλήθευση SSL-Pinning. Από την άποψη της ασφάλειας, η αποθήκευση τέτοιων πραγμάτων σε κώδικα δεν είναι η καλύτερη πρακτική. Ας προσπαθήσουμε να γράψουμε έναν κανόνα που θα αναζητά παρόμοια αρχεία στο αποθετήριο:

// Найдем все сертификаты по маске файла
CxList find_certs = All.FindByShortNames(new List<string> {"*.der", "*.cer", "*.pem", "*.key"}, false);

// Проверим, где в приложении они используются
CxList data_used_certs = All.DataInfluencedBy(find_certs);

// И для мобильных приложений - можем поискать методы, где вызывается чтение сертификатов
// Для других платформ и приложений могут быть различные методы
CxList methods = All.FindByMemberAccess("*.getAssets");

// Пересечение множеств даст нам результат по использованию локальных сертификатов в приложении
result = methods * data_used_certs;

Εργασία: Εύρεση παραβιασμένων διακριτικών στην εφαρμογή

λύση: Συχνά είναι απαραίτητο να ανακαλέσετε τα παραβιασμένα διακριτικά ή άλλες σημαντικές πληροφορίες που υπάρχουν στον κώδικα. Φυσικά, η αποθήκευσή τους μέσα στον πηγαίο κώδικα δεν είναι καλή ιδέα, αλλά οι καταστάσεις ποικίλλουν. Χάρη στα ερωτήματα CxQL, η εύρεση τέτοιων πραγμάτων είναι αρκετά εύκολη:

// Получаем все строки, которые содержатся в коде
CxList strings = base.Find_Strings();

// Ищем среди всех строк нужное нам значение. В примере токен в виде строки "qwerty12345"
result = strings.FindByShortName("qwerty12345");

Συμπέρασμα

Ελπίζω ότι αυτό το άρθρο θα είναι χρήσιμο σε όσους ξεκινούν τη γνωριμία τους με το εργαλείο Checkmarx. Ίσως όσοι γράφουν τους δικούς τους κανόνες εδώ και πολύ καιρό να βρουν κάτι χρήσιμο σε αυτόν τον οδηγό.

Δυστυχώς, επί του παρόντος υπάρχει έλλειψη πόρων όπου θα μπορούσαν να συγκεντρωθούν νέες ιδέες κατά την ανάπτυξη κανόνων για το Checkmarx. Γι' αυτό δημιουργήσαμε αποθετήριο στο Github, όπου θα δημοσιεύσουμε την εργασία μας, ώστε όλοι όσοι χρησιμοποιούν CxQL να μπορούν να βρουν κάτι χρήσιμο σε αυτήν, αλλά και να έχουν την ευκαιρία να μοιραστούν τη δουλειά τους με την κοινότητα. Το αποθετήριο βρίσκεται σε διαδικασία πλήρωσης και δομής περιεχομένου, επομένως οι συνεισφέροντες είναι ευπρόσδεκτοι!

Спасибо за внимание!

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο