Kumaha cara nyerat aturan pikeun Checkmarx tanpa gélo

Héy Habr!

Dina padamelan urang, perusahaan urang sering pisan ngurus sababaraha alat analisis kode statik (SAST). Out of the box aranjeunna sadayana dianggo rata. Tangtosna, éta sadayana gumantung kana proyék sareng téknologi anu dianggo di jerona, ogé kumaha ogé téknologi ieu katutupan ku aturan analisis. Dina pamanggih kuring, salah sahiji kritéria anu paling penting nalika milih alat SAST nyaéta kamampuan pikeun ngaropea kana spésifik aplikasi anjeun, nyaéta, nyerat sareng ngarobih aturan analisa atanapi, sabab langkung sering disebut, Custom Query.

Kumaha cara nyerat aturan pikeun Checkmarx tanpa gélo

Kami paling sering nganggo Checkmarx - analisa kode anu pikaresepeun sareng kuat. Dina artikel ieu kuring bakal ngobrol ngeunaan pangalaman kuring nulis aturan analisis pikeun eta.

daptar eusi

asup

Pikeun mimitian, abdi hoyong nyarankeun salah sahiji ti saeutik artikel dina basa Rusia ngeunaan fitur nulis queries pikeun Checkmarx. Ieu diterbitkeun dina Habré dina ahir 2019 dina judul: "Halo, Checkmarx!" Kumaha cara nyerat pamundut Checkmarx SAST sareng mendakan kerentanan anu saé.

Éta nalungtik sacara rinci kumaha cara nyerat patarosan anu munggaran dina CxQL (Checkmarx Query Language) pikeun sababaraha aplikasi tés sareng nunjukkeun prinsip dasar kumaha aturan analisis jalan.

Kuring moal ngulang naon anu dijelaskeun di dinya, sanaos sababaraha simpang masih bakal aya. Dina tulisan kuring kuring bakal nyobian nyusun jinis "kumpulan resep", daptar solusi pikeun masalah khusus anu kuring tepang nalika damel sareng Checkmarx. Kuring kungsi rak brains kuring leuwih loba masalah ieu. Kadang-kadang aya teu cukup informasi dina dokuméntasi, sarta kadangkala éta malah hésé ngarti kumaha carana ngalakukeun naon anu diperlukeun. Abdi ngarepkeun pangalaman kuring sareng wengi anu teu sare moal sia-sia, sareng ieu "kumpulan resep Custom Query" bakal nyalametkeun anjeun sababaraha jam atanapi sababaraha sél saraf. Janten, hayu urang mimitian!

Inpo umum ngeunaan aturan

Kahiji, hayu urang nempo sababaraha konsép dasar jeung prosés gawé bareng aturan, pikeun pamahaman hadé naon anu bakal kajadian salajengna. Sareng ogé kusabab dokuméntasi henteu nyarios nanaon ngeunaan ieu atanapi sumebar pisan dina strukturna, anu henteu pikaresepeun pisan.

  1. Aturan diterapkeun nalika nyeken gumantung kana prasetél anu dipilih di mimiti (sakumpulan aturan aktip). Anjeun tiasa nyiptakeun jumlah prasetél anu henteu terbatas, sareng kumaha cara nyusunna gumantung kana spésifik prosés anjeun. Anjeun tiasa ngagolongkeun aranjeunna dumasar kana basa atanapi milih prasetél pikeun unggal proyék. Jumlah aturan aktip mangaruhan laju sarta akurasi scanning.

    Kumaha cara nyerat aturan pikeun Checkmarx tanpa géloNyetél Prasetél dina panganteur Checkmarx

  2. Aturan diédit dina alat khusus anu disebut CxAuditor. Ieu mangrupikeun aplikasi desktop anu nyambung ka server anu ngajalankeun Checkmarx. Alat ieu ngagaduhan dua modeu operasi: aturan ngédit sareng nganalisa hasil scan anu parantos dilakukeun.

    Kumaha cara nyerat aturan pikeun Checkmarx tanpa gélopanganteur CxAudit

  3. Aturan dina Checkmarx dibagi ku basa, nyaéta, unggal basa gaduh set patarosan sorangan. Aya ogé sababaraha aturan umum anu lumaku paduli basa, ieu nu disebut queries dasar. Kanggo sabagéan ageung, patarosan dasar ngalibatkeun milarian inpormasi anu dianggo ku aturan anu sanés.

    Kumaha cara nyerat aturan pikeun Checkmarx tanpa géloNgabagi aturan ku basa

  4. Aturan anu "Executable" jeung "Non-Executable" (dieksekusi jeung Teu dieksekusi). Teu rada ngaran bener, dina pamanggih kuring, tapi éta naon éta. Intina nyaéta yén hasil ngalaksanakeun aturan "Executable" bakal ditingalikeun dina hasil scan dina UI, sareng aturan "Non-Executable" ngan ukur diperyogikeun pikeun ngagunakeun hasil dina pamundut anu sanés (dina dasarna, ngan ukur fungsi).

    Kumaha cara nyerat aturan pikeun Checkmarx tanpa géloNangtukeun jinis aturan nalika nyiptakeun

  5. Anjeun tiasa nyieun aturan anyar atawa suplement / nulis balik nu geus aya. Pikeun nulis ulang aturan, anjeun kedah mendakanana dina tangkal, klik-katuhu sareng pilih "Override" tina menu turun-handap. Penting pikeun émut di dieu yén aturan énggal henteu mimitina kalebet dina prasetél sareng henteu aktip. Pikeun ngamimitian nganggo éta, anjeun kedah ngaktipkeunana dina ménu "Preset Manager" dina alat. Aturan ditulis ulang nahan setélanna, nyaéta, upami aturan éta aktip, éta bakal tetep kitu sareng bakal langsung diterapkeun.

    Kumaha cara nyerat aturan pikeun Checkmarx tanpa géloConto aturan anyar dina panganteur Preset Manager

  6. Salila palaksanaan, hiji "tangkal" requests diwangun, nu gumantung kana naon. Aturan anu ngumpulkeun inpormasi dieksekusi heula, sareng anu nganggo kadua. Hasil palaksanaan di-cache, janten upami anjeun tiasa nganggo hasil tina aturan anu tos aya, maka langkung saé pikeun ngalakukeunana, ieu bakal ngirangan waktos scanning.

  7. Aturan tiasa diterapkeun dina tingkat anu béda:

  • Pikeun sakabéh sistem - bakal dipaké pikeun sagala scanning proyék nanaon

  • Di tingkat tim (Tim) - ngan bakal dipaké pikeun nyeken proyék di tim dipilih.

  • Dina tingkat proyék - Bakal dilarapkeun dina proyék husus

    Kumaha cara nyerat aturan pikeun Checkmarx tanpa géloNangtukeun tingkat dimana aturan bakal diterapkeun

"Kamus" pikeun beginners

Sareng kuring bakal ngamimitian ku sababaraha hal anu nyababkeun kuring patarosan, sareng kuring ogé bakal nunjukkeun sababaraha téknik anu bakal nyederhanakeun kahirupan sacara signifikan.

Operasi kalawan daptar

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

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

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

Sadaya barang kapanggih

Dina basa anu discan, anjeun tiasa nampi daptar sadaya unsur anu diidentifikasi ku Checkmarx (string, fungsi, kelas, metode, jsb.). Ieu sababaraha spasi objék nu bisa diakses ngaliwatan All. Nyaéta, pikeun milarian obyék anu gaduh nami khusus searchMe, anjeun tiasa milarian, contona, ku nami dina sadaya objék anu kapendak:

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

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

Tapi, upami anjeun kedah milarian dina basa sanés anu kusabab sababaraha alesan henteu kalebet dina scan (contona, groovy dina proyék Android), anjeun tiasa ngalegaan rohangan objék kami ngalangkungan variabel:

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

Fungsi pikeun analisis Aliran

Pungsi ieu dianggo dina seueur aturan sareng ieu mangrupikeun lambaran curang sakedik naon hartosna:

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

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

Kéngingkeun nami file / jalur

Aya sababaraha atribut anu tiasa didapet tina hasil query (nami file nu entri ieu kapanggih, string, jeung sajabana), tapi dokuméntasi teu nyebutkeun kumaha carana ménta sarta ngagunakeun éta. Janten, pikeun ngalakukeun ieu, anjeun kedah ngaksés harta LinePragma sareng objék anu urang peryogikeun bakal aya di jerona:

// Для примера найдем все методы
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);

Éta patut tetep dina pikiran éta FileName ngandung sabenerna jalur ka file, saprak urang dipake metoda GetFirstGraph.

Hasil palaksanaan

Aya variabel husus di jero CxQL result, nu mulih hasil tina executing aturan ditulis anjeun. Éta diinisialisasi langsung sareng anjeun tiasa nyerat hasil panengah kana éta, ngarobih sareng ngamurnikeunana nalika anjeun damel. Tapi, upami teu aya tugas pikeun variabel ieu atanapi fungsi dina aturan return- hasil palaksanaan bakal salawasna enol.

Paménta di handap ieu moal ngabalikeun nanaon ka urang salaku hasil tina palaksanaan sareng bakal salawasna kosong:

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

Tapi, sanggeus ditugaskeun hasil palaksanaan kana hasil variabel magic, urang bakal ningali naon panggero ieu balik ka kami:

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

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

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

Ngagunakeun hasil tina aturan séjén

Aturan dina Checkmarx bisa disebut analog jeung fungsi dina basa programming biasa. Nalika nulis aturan, anjeun tiasa nganggo hasil tina patarosan anu sanés. Salaku conto, teu kedah milarian sadaya metode nelepon dina kode unggal waktos, ngan ukur nelepon aturan anu dipikahoyong:

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

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

Pendekatan ieu ngamungkinkeun anjeun pikeun pondok kode sareng sacara signifikan ngirangan waktos palaksanaan aturan.

Ngarengsekeun masalah

logging

Nalika damel sareng alat, sakapeung teu mungkin langsung nyerat pamundut anu dipikahoyong sareng anjeun kedah ékspérimén, nyobian pilihan anu béda. Pikeun kasus sapertos kitu, alatna nyayogikeun logging, anu disebut kieu:

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

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

Tapi kedah émut yén metode ieu ngan ukur nampi salaku input tali, ku kituna moal mungkin pikeun nembongkeun daptar lengkep unsur kapanggih salaku hasil tina operasi munggaran. Pilihan kadua, nu dipaké pikeun debugging, nyaéta pikeun nangtukeun kana variabel magic ti jaman ka jaman result hasil tina query tur tingal kumaha kajadian. Pendekatan ieu henteu merenah pisan; anjeun kedah pastikeun yén teu aya overrides atanapi operasi sareng ieu dina kode saatos result atawa ngan saukur mairan kodeu di handap. Atanapi anjeun tiasa, sapertos kuring, hilap ngahapus sababaraha telepon sapertos kitu tina aturan anu siap-siap sareng heran naha teu aya anu tiasa dianggo.

Cara anu langkung merenah nyaéta nyauran metodeu return kalawan parameter diperlukeun. Dina hal ieu, palaksanaan aturan bakal mungkas sareng urang bakal tiasa ningali naon anu lumangsung salaku hasil tina naon anu urang tulis:

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

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

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

Masalah login

Aya kaayaan nalika anjeun teu tiasa ngaksés alat CxAudit (anu dianggo pikeun nyerat aturan). Aya seueur alesan pikeun ieu, kalebet kacilakaan, apdet Windows ngadadak, BSOD sareng kaayaan anu teu disangka-sangka anu di luar kendali urang. Dina hal ieu, sakapeung aya sési anu teu réngsé dina pangkalan data, anu nyegah anjeun asup deui. Pikeun ngalereskeunana, anjeun kedah ngajalankeun sababaraha patarosan:

Pikeun Checkmarx sateuacan 8.6:

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

Pikeun Checkmarx saatos 8.6:

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

Aturan nulis

Ayeuna urang meunang ka bagian paling metot. Lamun anjeun mimiti nulis aturan di CxQL, naon mindeng kakurangan teu jadi loba dokuméntasi sakumaha sababaraha conto hirup ngarengsekeun masalah nu tangtu sarta ngajelaskeun prosés kumaha queries jalan sacara umum.

Kuring bakal coba nyieun hirup saeutik gampang pikeun maranéhanana anu dimimitian teuleum kana basa query tur masihan sababaraha conto ngagunakeun Custom Queries pikeun ngajawab masalah nu tangtu. Sababaraha di antarana cukup umum sareng tiasa dianggo di perusahaan anjeun sacara praktis tanpa parobihan, anu sanésna langkung spésifik, tapi ogé tiasa dianggo ku cara ngarobah kodeu pikeun nyocogkeun ka spésifik aplikasi anjeun.

Janten, ieu mangrupikeun masalah anu paling sering urang hadapi:

Tugas: Aya sababaraha Aliran dina hasil ngalaksanakeun aturan sareng salah sahijina nyaéta nyarang anu sanés, anjeun kedah ngantunkeun salah sahijina.

solusi: Mémang, sakapeung Checkmarx nunjukkeun sababaraha aliran data anu tiasa tumpang tindih sareng janten vérsi singgetan batur. Aya metodeu khusus pikeun kasus sapertos kitu NguranganFlow. Gumantung kana parameter, éta bakal milih Aliran pondok atanapi pangpanjangna:

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

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

Tugas: Kembangkeun daptar data sénsitip anu diréaksikeun ku alat

solusi: Checkmarx gaduh aturan dasar, anu hasilna dianggo ku seueur patarosan anu sanés. Ku nambihan sababaraha aturan ieu sareng data khusus pikeun aplikasi anjeun, anjeun tiasa langsung ningkatkeun hasil scan anjeun. Di handap ieu conto aturan pikeun ngamimitian anjeun:

General_privacy_violation_list

Hayu urang tambahkeun sababaraha variabel anu dianggo dina aplikasi urang pikeun nyimpen inpormasi sénsitip:

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

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

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

Tugas: Kembangkeun daptar variabel sareng kecap akses

solusi: Abdi nyarankeun langsung nengetan aturan dasar pikeun nangtukeun kecap akses dina kode sareng nambihan kana daptar nami variabel anu biasa dianggo di perusahaan anjeun.

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);
	}
}

Tugas: Tambahkeun kerangka dipaké nu teu dirojong ku Checkmarx

solusi: Sadaya patarosan dina Checkmarx dibagi ku basa, janten anjeun kedah nambihan aturan pikeun unggal basa. Ieu di handap aya sababaraha conto aturan sapertos kitu.

Upami perpustakaan dianggo anu ngalengkepan atanapi ngagentos fungsionalitas standar, aranjeunna tiasa gampang ditambah kana aturan dasar. Teras sadayana anu nganggo éta bakal langsung diajar ngeunaan perkenalan énggal. Salaku conto, perpustakaan pikeun log in Android nyaéta Timber sareng Loggi. Dina pakét dasar, teu aya aturan pikeun ngaidentipikasi sauran non-sistem, janten upami kecap konci atanapi identifier sési asup kana log, urang moal terang ngeunaan éta. Hayu urang cobaan pikeun nambahkeun definisi métode sapertos kana aturan Checkmarx.

Conto kode tés anu ngagunakeun perpustakaan Timber pikeun logging:

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");
    }
}

Sareng ieu mangrupikeun conto pamundut pikeun Checkmarx, anu bakal ngamungkinkeun anjeun pikeun nambihan definisi nelepon metode Timber salaku titik kaluar pikeun data tina aplikasi:

Panggihan AndroidOutputs

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

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

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

Sareng anjeun ogé tiasa nambihan kana aturan tatangga, tapi ieu langsung aya hubunganana sareng log in Android:

FindAndroidLog_Outputs

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

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

Ogé, upami aplikasi Android nganggo WorkManager pikeun pagawéan asinkron, éta hadé pikeun nginpokeun deui ka Checkmarx ngeunaan ieu ku cara nambahkeun métode pikeun meunangkeun data tina tugas. getInputData:

Panggihan AndroidRead

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

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

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

Tugas: Milarian data sénsitip dina plist pikeun proyék ios

solusi: ios mindeng ngagunakeun file husus kalawan extension .plist pikeun nyimpen rupa variabel sarta nilai. Nyimpen kecap akses, token, konci sareng data sénsitip anu sanés dina file ieu henteu disarankeun, sabab tiasa diekstrak tina alat tanpa aya masalah.

File Plist gaduh fitur anu henteu atra ku mata taranjang, tapi penting pikeun Checkmarx. Hayu urang nyerat aturan anu bakal milarian data anu urang peryogikeun sareng wartosan kami upami kecap konci atanapi token disebatkeun dimana waé.

Conto file sapertos kitu, anu ngandung token pikeun komunikasi sareng jasa backend:

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

Sareng aturan pikeun Checkmarx, anu ngagaduhan sababaraha nuansa anu kedah diperhatoskeun nalika nyerat:

// Используем результат выполнения правила по поиску файлов 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);

Tugas: Milarian inpormasi dina XML

solusi: Checkmarx ngagaduhan fungsi anu saé pikeun damel sareng XML sareng milarian nilai, tag, atribut sareng seueur deui. Tapi, hanjakalna, aya kasalahan dina dokuméntasi alatan nu teu hiji conto tunggal jalan. Najan kanyataan yén cacad ieu geus ngaleungitkeun dina versi panganyarna tina dokuméntasi, ati lamun make versi saméméhna tina dokumén.

Ieu conto anu salah tina dokuméntasi:

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

Salaku hasil tina usaha palaksanaan, urang bakal nampa kasalahan éta All teu aya metodeu sapertos kitu ... Sareng ieu leres, sabab aya rohangan obyék khusus anu misah pikeun ngagunakeun fungsi pikeun damel sareng XML - cxXPath. Ieu mangrupikeun patarosan anu leres pikeun milarian setélan dina Android anu ngamungkinkeun panggunaan lalu lintas HTTP:

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

Hayu urang nempo eta dina leuwih jéntré saeutik, sabab sintaksis pikeun sakabéh fungsi nu sarupa, sanggeus anjeun geus ilahar kaluar hiji, mangka anjeun ngan kudu milih hiji nu peryogi. Ku kituna, sequentially nurutkeun parameter:

  • "*.xml"- topéng file pikeun milarian

  • 8 - id basa pikeun aturan nu dilarapkeun

  • "cleartextTrafficPermitted"- ngaran atribut dina xml

  • "true" - nilai atribut ieu

  • false - ngagunakeun ekspresi biasa nalika milarian

  • true — hartina panéangan bakal dilaksanakeun teu malire kasus, nyaeta, case-insensitive

Salaku conto, kami nganggo aturan anu ngidentipikasi lepat, tina sudut pandang kaamanan, setélan sambungan jaringan dina Android anu ngamungkinkeun komunikasi sareng server liwat protokol HTTP. Conto setting anu ngandung atribut cleartextTrafficPermitted kalawan harti 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>

Tugas: Ngawatesan hasil ku ngaran file / jalur

solusi: Dina salah sahiji proyék badag patali ngembangkeun hiji aplikasi mobile pikeun Android, urang encountered positip palsu tina aturan nu nangtukeun setelan obfuscation. Kanyataanna nyaéta aturan kaluar tina kotak milarian dina file build.gradle setelan anu tanggung jawab pikeun nerapkeun aturan obfuscation pikeun versi sékrési aplikasi.

Tapi dina proyék ageung kadang aya file anak build.gradle, nu nujul ka perpustakaan kaasup dina proyék. Fiturna nyaéta sanajan file ieu henteu nunjukkeun kabutuhan obfuscation, setélan file assembly indungna bakal diterapkeun nalika kompilasi.

Ku kituna, tugasna pikeun neukteuk off pemicu dina file anak milik perpustakaan. Éta bisa dicirikeun ku ayana garis apply 'com.android.library'.

Conto kode tina file build.gradle, nu nangtukeun kabutuhan obfuscation:

apply plugin: 'com.android.application'

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

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

dependencies {
  ...
}

file conto build.gradle pikeun perpustakaan kaasup dina proyék nu teu boga setelan ieu:

apply plugin: 'android-library'

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

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

Jeung aturan pikeun 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);
		}
	}
}

Pendekatan ieu tiasa rada universal sareng mangpaat henteu ngan ukur pikeun aplikasi Android, tapi ogé pikeun kasus-kasus sanés nalika anjeun kedah nangtoskeun naha hasil tina file khusus.

Tugas: Tambihkeun dukungan pikeun perpustakaan pihak katilu upami sintaksis henteu dirojong sapinuhna

solusi: Jumlah rupa-rupa kerangka anu dianggo dina prosés nulis kode ngan saukur kaluar tina grafik. Tangtosna, Checkmarx henteu salawasna terang ngeunaan ayana, sareng tugas urang nyaéta ngajar éta ngartos yén metode anu tangtu khususna pikeun kerangka ieu. Kadang-kadang ieu nyusahkeun ku kanyataan yén frameworks nganggo nami fungsi anu umum pisan sareng mustahil pikeun sacara jelas nangtukeun hubungan telepon khusus ka perpustakaan khusus.

Kasusahna nyaéta sintaksis pustaka sapertos kitu henteu leres-leres dipikanyaho sareng anjeun kedah ékspérimén pikeun ngahindarkeun seueur positip palsu. Aya sababaraha pilihan pikeun ningkatkeun akurasi scanning sareng ngabéréskeun masalah:

  • Pilihan kahiji, urang nyaho pasti yén perpustakaan dipaké dina proyék husus sarta bisa nerapkeun aturan di tingkat tim. Tapi upami tim mutuskeun nyandak pendekatan anu béda atanapi nganggo sababaraha perpustakaan dimana nami fungsi tumpang tindih, urang tiasa nampi gambar anu henteu pikaresepeun tina seueur positip palsu.

  • Pilihan kadua nyaéta milarian file anu perpustakaan jelas diimpor. Kalayan pendekatan ieu, urang tiasa mastikeun yén perpustakaan anu urang peryogikeun leres-leres dianggo dina file ieu.

  • Sareng pilihan katilu nyaéta ngagunakeun dua pendekatan di luhur babarengan.

Salaku conto, hayu urang nempo perpustakaan well-dipikawanoh di kalangan sempit lunyu pikeun basa programming Scala, nyaéta, fungsionalitas Splicing Nilai Literal. Sacara umum, pikeun ngirimkeun parameter kana pamundut SQL, anjeun kedah nganggo operator $, nu substitutes data kana query SQL preformed. Nyaéta, kanyataanna, éta analog langsung tina Pernyataan Disusun di Jawa. Tapi, upami anjeun kedah dinamis ngawangun query SQL, contona, upami anjeun kedah ngalangkungan nami méja, anjeun tiasa nganggo operator. #$, nu bakal langsung ngagantikeun data kana query (ampir kawas concatenation string).

Kode sampel:

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

Checkmarx henteu acan terang kumaha ngadeteksi panggunaan Splicing Literal Values ​​sareng operator skip #$, ku kituna hayu urang coba ngajarkeun eta pikeun ngaidentipikasi poténsi injections SQL jeung nyorot tempat katuhu dina kode:

// Находим все импорты
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));
}

Tugas: Milarian fungsi anu rentan anu dianggo dina perpustakaan Open-Source

solusi: Seueur perusahaan nganggo alat ngawaskeun Open-Source (prakték OSA) pikeun ngadeteksi pamakean versi perpustakaan anu rentan dina aplikasi anu dikembangkeun. Kadang-kadang teu mungkin pikeun ngapdet perpustakaan sapertos kana versi anu aman. Dina sababaraha kasus aya watesan fungsi, di batur teu aya versi aman pisan. Dina hal ieu, kombinasi prakték SAST sareng OSA bakal ngabantosan pikeun nangtukeun yén fungsi anu nyababkeun eksploitasi kerentanan henteu dianggo dina kode.

Tapi kadang, utamana lamun tempo JavaScript, ieu bisa jadi teu tugas lengkep trivial. Di handap ieu mangrupikeun solusi, panginten henteu idéal, tapi tetep jalan, nganggo conto kerentanan dina komponén lodash dina métode template и *set.

Conto tés kode anu berpotensi rentan dina file 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!'

Sareng nalika nyambungkeun langsung dina 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>

Kami milarian sadaya metode anu rentan, anu didaptarkeun dina kerentanan:

// Ищем все строки: в которых встречается строка 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));

Tugas: Milarian sertipikat anu dipasang dina aplikasi

solusi: Teu ilahar pikeun aplikasi, utamana mobile, ngagunakeun sertipikat atawa konci pikeun ngakses rupa server atawa pariksa SSL-Pinning. Tina sudut pandang kaamanan, nyimpen hal-hal sapertos kitu dina kode sanés prakték pangsaéna. Hayu urang cobian nyerat aturan anu bakal milarian file anu sami dina gudang:

// Найдем все сертификаты по маске файла
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;

Tugas: Pananjung tokens compromised dina aplikasi

solusi: Ieu sering diperlukeun pikeun nyabut tokens compromised atawa informasi penting lianna nu aya dina kode. Tangtosna, nyimpen éta di jero kode sumber sanés mangrupikeun ide anu saé, tapi kaayaanna béda-béda. Hatur nuhun kana patarosan CxQL, mendakan hal-hal sapertos kieu cukup gampang:

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

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

kacindekan

Kuring ngarepkeun tulisan ieu bakal mangpaat pikeun anu ngamimitian kenalan sareng alat Checkmarx. Panginten anu parantos lami nyerat aturan sorangan ogé bakal mendakan anu mangpaat dina pituduh ieu.

Hanjakalna, ayeuna aya kakurangan sumberdaya dimana ideu-ideu anyar tiasa dicandak nalika ngembangkeun aturan pikeun Checkmarx. Éta sababna urang nyiptakeun gudang on Github, dimana urang bakal masangkeun karya urang ku kituna dulur anu ngagunakeun CxQL bisa manggihan hal mangpaat dina eta, sarta ogé boga kasempetan pikeun babagi karya maranéhanana jeung masarakat. Repository aya dina prosés ngeusian sareng nyusun eusi, janten kontributor wilujeng sumping!

Hatur nuhun kanggo nengetan!

sumber: www.habr.com

Tambahkeun komentar