Jinsi ya kuandika sheria za Checkmarx bila kuwa wazimu

Habari Habr!

Katika kazi yetu, kampuni yetu mara nyingi hushughulika na zana anuwai za uchambuzi wa nambari tuli (SAST). Nje ya boksi wote hufanya kazi kwa wastani. Bila shaka, yote inategemea mradi na teknolojia zinazotumiwa ndani yake, pamoja na jinsi teknolojia hizi zinavyofunikwa na sheria za uchambuzi. Kwa maoni yangu, mojawapo ya vigezo muhimu zaidi wakati wa kuchagua zana ya SAST ni uwezo wa kuibadilisha kulingana na maalum ya programu zako, yaani, kuandika na kubadilisha sheria za uchambuzi au, kama zinavyoitwa mara nyingi zaidi, Maswali Maalum.

Jinsi ya kuandika sheria za Checkmarx bila kuwa wazimu

Mara nyingi sisi hutumia Checkmarx - kichanganuzi cha msimbo cha kuvutia sana na chenye nguvu. Katika makala hii nitazungumzia uzoefu wangu wa kuandika sheria za uchambuzi kwa ajili yake.

Meza ya yaliyomo

Entry

Kuanza, ningependa kupendekeza moja ya makala chache katika Kirusi kuhusu vipengele vya kuandika maswali kwa Checkmarx. Ilichapishwa kwenye Habre mwishoni mwa 2019 chini ya kichwa: "Habari, Checkmarx!" Jinsi ya kuandika swali la Checkmarx SAST na kupata udhaifu mzuri.

Inachunguza kwa kina jinsi ya kuandika maswali ya kwanza katika CxQL (Lugha ya Maswali ya Checkmarx) kwa matumizi fulani ya jaribio na inaonyesha kanuni za msingi za jinsi sheria za uchanganuzi zinavyofanya kazi.

Sitarudia yale yaliyoelezwa ndani yake, ingawa baadhi ya makutano bado yatakuwepo. Katika makala yangu nitajaribu kukusanya aina ya "mkusanyiko wa mapishi", orodha ya ufumbuzi wa matatizo maalum ambayo nilikutana nayo wakati wa kazi yangu na Checkmarx. Ilinibidi kusumbua akili yangu juu ya mengi ya shida hizi. Wakati mwingine hapakuwa na taarifa za kutosha katika nyaraka, na wakati mwingine ilikuwa vigumu hata kuelewa jinsi ya kufanya kile kilichohitajika. Natumai uzoefu wangu na usiku wa kukosa usingizi hautakuwa bure, na "mkusanyiko huu wa mapishi ya Maswali Maalum" utakuokoa saa chache au seli kadhaa za neva. Kwa hiyo, hebu tuanze!

Maelezo ya jumla juu ya sheria

Kwanza, hebu tuangalie dhana chache za msingi na mchakato wa kufanya kazi na sheria, kwa ufahamu bora wa nini kitatokea baadaye. Na pia kwa sababu nyaraka hazisemi chochote kuhusu hili au zinaenea sana katika muundo, ambayo haifai sana.

  1. Sheria zinatumika wakati wa skanning kulingana na mpangilio uliochaguliwa mwanzoni (seti ya sheria zinazofanya kazi). Unaweza kuunda idadi isiyo na kikomo ya mipangilio ya awali, na hasa jinsi ya kuunda inategemea maalum ya mchakato wako. Unaweza kuziweka katika vikundi kulingana na lugha au uchague mipangilio ya awali kwa kila mradi. Idadi ya sheria zinazotumika huathiri kasi na usahihi wa skanning.

    Jinsi ya kuandika sheria za Checkmarx bila kuwa wazimuKuweka Preset katika kiolesura cha Checkmarx

  2. Sheria zimehaririwa katika zana maalum inayoitwa CxAuditor. Hii ni programu ya kompyuta ya mezani inayounganishwa na seva inayoendesha Checkmarx. Chombo hiki kina njia mbili za uendeshaji: sheria za kuhariri na kuchambua matokeo ya skanati iliyofanywa tayari.

    Jinsi ya kuandika sheria za Checkmarx bila kuwa wazimuKiolesura cha CxAudit

  3. Sheria katika Checkmarx zimegawanywa kwa lugha, yaani, kila lugha ina seti yake ya maswali. Pia kuna baadhi ya sheria za jumla zinazotumika bila kujali lugha, hizi ni zinazoitwa maswali ya msingi. Kwa sehemu kubwa, maswali ya msingi yanahusisha kutafuta taarifa ambayo sheria zingine hutumia.

    Jinsi ya kuandika sheria za Checkmarx bila kuwa wazimuKugawanya kanuni kwa lugha

  4. Sheria ni "Inaweza Kutekelezeka" na "Isiyotekelezeka" (Imetekelezwa na Haijatekelezwa). Sio jina sahihi kabisa, kwa maoni yangu, lakini ndivyo ilivyo. Jambo la msingi ni kwamba matokeo ya kutekeleza sheria za "Kutekelezeka" yataonyeshwa kwenye matokeo ya skanisho kwenye UI, na sheria za "Zisizoweza Kutekelezwa" zinahitajika tu kutumia matokeo yao katika maombi mengine (kimsingi, kazi tu).

    Jinsi ya kuandika sheria za Checkmarx bila kuwa wazimuKuamua aina ya sheria wakati wa kuunda

  5. Unaweza kuunda sheria mpya au kuongeza/kuandika upya zilizopo. Ili kuandika upya sheria, unahitaji kuipata kwenye mti, bonyeza-click na uchague "Batilisha" kutoka kwenye orodha ya kushuka. Ni muhimu kukumbuka hapa kwamba sheria mpya hazijumuishwa katika mipangilio ya awali na hazifanyi kazi. Ili kuanza kuzitumia unahitaji kuziamsha kwenye menyu ya "Meneja wa Kuweka" kwenye chombo. Sheria zilizoandikwa upya huhifadhi mipangilio yao, yaani, ikiwa sheria ilikuwa hai, itabaki hivyo na itatumika mara moja.

    Jinsi ya kuandika sheria za Checkmarx bila kuwa wazimuMfano wa sheria mpya katika kiolesura cha Kidhibiti kilichowekwa

  6. Wakati wa utekelezaji, "mti" wa maombi hujengwa, ambayo inategemea nini. Sheria zinazokusanya habari zinatekelezwa kwanza, na wale wanaozitumia mara ya pili. Matokeo ya utekelezaji ni cached, hivyo ikiwa inawezekana kutumia matokeo ya utawala uliopo, basi ni bora kufanya hivyo, hii itapunguza muda wa skanning.

  7. Sheria zinaweza kutumika katika viwango tofauti:

  • Kwa mfumo mzima - itatumika kwa skanning yoyote ya mradi wowote

  • Katika kiwango cha timu (Timu) - itatumika kuchanganua miradi katika timu iliyochaguliwa pekee.

  • Katika kiwango cha mradi - Itatumika katika mradi maalum

    Jinsi ya kuandika sheria za Checkmarx bila kuwa wazimuKuamua kiwango ambacho sheria itatumika

"Kamusi" kwa Kompyuta

Na nitaanza na mambo machache yaliyonisababishia maswali, na pia nitaonyesha mbinu kadhaa ambazo zitarahisisha maisha kwa kiasi kikubwa.

Operesheni zilizo na orodha

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

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

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

Vitu vyote vilivyopatikana

Ndani ya lugha iliyochanganuliwa, unaweza kupata orodha ya vipengele vyote ambavyo Checkmarx imetambua (mifuatano, vitendaji, darasa, mbinu, n.k.). Hii ni baadhi ya nafasi ya vitu vinavyoweza kupatikana kupitia All. Hiyo ni, kutafuta kitu kilicho na jina maalum searchMe, unaweza kutafuta, kwa mfano, kwa jina katika vitu vyote vilivyopatikana:

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

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

Lakini, ikiwa unahitaji kutafuta katika lugha nyingine ambayo kwa sababu fulani haikujumuishwa kwenye skanisho (kwa mfano, groovy katika mradi wa Android), unaweza kupanua nafasi yetu ya kitu kupitia kibadilishaji:

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

Kazi za uchanganuzi wa mtiririko

Kazi hizi hutumiwa katika sheria nyingi na hapa kuna karatasi ndogo ya kudanganya ya wanachomaanisha:

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

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

Kupata jina la faili/njia

Kuna sifa kadhaa ambazo zinaweza kupatikana kutokana na matokeo ya swala (jina la faili ambalo kuingia kulipatikana, kamba, nk), lakini nyaraka hazisemi jinsi ya kuzipata na kuzitumia. Kwa hivyo, ili kufanya hivyo, unahitaji kupata mali ya LinePragma na vitu tunavyohitaji vitakuwa ndani yake:

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

Inafaa kukumbuka hilo FileName ina kweli njia ya faili, kwani tulitumia njia GetFirstGraph.

Matokeo ya utekelezaji

Kuna tofauti maalum ndani ya CxQL result, ambayo inarudisha matokeo ya kutekeleza sheria yako iliyoandikwa. Imeanzishwa mara moja na unaweza kuandika matokeo ya kati ndani yake, kuyabadilisha na kuyaboresha unapofanya kazi. Lakini, ikiwa hakuna mgawo wa kutofautisha au kazi hii ndani ya sheria return- matokeo ya utekelezaji yatakuwa sifuri kila wakati.

Hoja ifuatayo haitaturudishia chochote kama matokeo ya utekelezaji na itakuwa tupu kila wakati:

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

Lakini, tukiwa tumepeana matokeo ya utekelezaji kwa matokeo ya kutofautisha ya kichawi, tutaona simu hii inarudi kwetu nini:

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

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

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

Kutumia matokeo ya sheria zingine

Sheria katika Checkmarx zinaweza kuitwa kufanana na kazi katika lugha ya kawaida ya programu. Wakati wa kuandika sheria, unaweza kutumia matokeo ya maswali mengine. Kwa mfano, hakuna haja ya kutafuta simu zote za njia kwenye nambari kila wakati, piga tu sheria inayotaka:

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

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

Njia hii inakuwezesha kufupisha msimbo na kupunguza kwa kiasi kikubwa muda wa utekelezaji wa sheria.

Kutatua tatizo

Kuweka magogo

Wakati wa kufanya kazi na chombo, wakati mwingine haiwezekani kuandika mara moja swali linalohitajika na unapaswa kujaribu, kujaribu chaguo tofauti. Kwa kesi kama hiyo, chombo hutoa ukataji miti, ambayo huitwa kama ifuatavyo:

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

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

Lakini inafaa kukumbuka kuwa njia hii inakubali tu kama pembejeo kamba, kwa hivyo haitawezekana kuonyesha orodha kamili ya vitu vilivyopatikana kama matokeo ya operesheni ya kwanza. Chaguo la pili, ambalo linatumika kwa utatuzi, ni kugawa utofauti wa uchawi mara kwa mara result matokeo ya swala na uone kitakachotokea. Njia hii sio rahisi sana; unahitaji kuwa na uhakika kuwa hakuna ubatilishaji au shughuli na hii kwenye nambari baada ya result au toa maoni yako kwa nambari iliyo hapa chini. Au unaweza, kama mimi, kusahau kuondoa simu kadhaa kama hizo kutoka kwa sheria iliyotengenezwa tayari na ushangae kwa nini hakuna kitu kinachofanya kazi.

Njia rahisi zaidi ni kupiga simu njia return na parameter inayohitajika. Katika kesi hii, utekelezaji wa sheria utaisha na tutaweza kuona kilichotokea kama matokeo ya kile tulichoandika:

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

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

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

Tatizo la kuingia

Kuna hali wakati huwezi kufikia zana ya CxAudit (ambayo hutumiwa kuandika sheria). Kunaweza kuwa na sababu nyingi za hii, ikiwa ni pamoja na kuacha kufanya kazi, sasisho za ghafla za Windows, BSOD na hali zingine zisizotarajiwa ambazo ziko nje ya uwezo wetu. Katika kesi hii, wakati mwingine kuna kikao ambacho hakijakamilika kwenye hifadhidata, ambayo inakuzuia kuingia tena. Ili kurekebisha, unahitaji kuendesha maswali kadhaa:

Kwa Checkmarx kabla ya 8.6:

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

Kwa Checkmarx baada ya 8.6:

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

Sheria za uandishi

Sasa tunafika kwenye sehemu ya kuvutia zaidi. Unapoanza kuandika sheria katika CxQL, unachokosa mara nyingi sio nyaraka nyingi kama baadhi ya mifano hai ya kutatua matatizo fulani na kuelezea mchakato wa jinsi hoja hufanya kazi kwa ujumla.

Nitajaribu kurahisisha maisha kidogo kwa wale wanaoanza kuzama katika lugha ya maswali na kutoa mifano kadhaa ya kutumia Maswali Maalum ili kutatua matatizo fulani. Baadhi yao ni ya jumla kabisa na yanaweza kutumika katika kampuni yako kivitendo bila mabadiliko, mengine ni mahususi zaidi, lakini yanaweza pia kutumiwa kwa kubadilisha msimbo ili kuendana na maelezo mahususi ya programu zako.

Kwa hivyo, hapa kuna shida ambazo tumekutana nazo mara nyingi:

Kazi: Kuna Mitiririko kadhaa katika matokeo ya utekelezaji wa sheria na mmoja wao ni kiota cha mwingine, lazima uache mmoja wao.

ufumbuzi: Hakika, wakati mwingine Checkmarx huonyesha mtiririko kadhaa wa data ambao unaweza kuingiliana na kuwa toleo fupi la wengine. Kuna njia maalum kwa kesi kama hizo PunguzaMtiririko. Kulingana na parameta, itachagua Mtiririko mfupi au mrefu zaidi:

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

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

Kazi: Panua orodha ya data nyeti ambayo zana hujibu

ufumbuzi: Checkmarx ina sheria za msingi, ambazo matokeo yake hutumiwa na maswali mengine mengi. Kwa kuongezea baadhi ya sheria hizi kwa data mahususi kwa programu yako, unaweza kuboresha matokeo yako mara moja. Ifuatayo ni sheria ya mfano ili uanze:

Orodha_ya_faragha_ya_uvunjaji_wa_jumla

Hebu tuongeze vigeu kadhaa vinavyotumika katika programu yetu kuhifadhi taarifa nyeti:

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

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

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

Kazi: Panua orodha ya vigeu kwa kutumia manenosiri

ufumbuzi: Ningependekeza mara moja uzingatie sheria ya msingi ya kufafanua manenosiri katika msimbo na kuongeza orodha ya majina tofauti ambayo hutumiwa sana katika kampuni yako.

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

Kazi: Ongeza mifumo iliyotumika ambayo haitumiki na Checkmarx

ufumbuzi: Hoja zote katika Checkmarx zimegawanywa kwa lugha, kwa hivyo unahitaji kuongeza sheria kwa kila lugha. Ifuatayo ni baadhi ya mifano ya sheria hizo.

Ikiwa maktaba zitatumika zinazosaidia au kubadilisha utendakazi wa kawaida, zinaweza kuongezwa kwa urahisi kwa kanuni ya msingi. Kisha kila mtu anayeitumia atajifunza mara moja kuhusu utangulizi mpya. Kwa mfano, maktaba za kuingia kwenye Android ni Timber na Loggi. Katika mfuko wa msingi, hakuna sheria za kutambua simu zisizo za mfumo, hivyo ikiwa nenosiri au kitambulisho cha kikao kinaingia kwenye logi, hatuwezi kujua kuhusu hilo. Wacha tujaribu kuongeza ufafanuzi wa njia kama hizo kwa sheria za Checkmarx.

Mfano wa msimbo wa majaribio unaotumia maktaba ya Timber kwa ukataji miti:

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

Na hapa kuna mfano wa ombi la Checkmarx, ambalo litakuruhusu kuongeza ufafanuzi wa kupiga simu kwa njia za Timber kama sehemu ya kutoka kwa data kutoka kwa programu:

FindAndroidOutputs

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

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

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

Na unaweza pia kuongeza kwa sheria ya jirani, lakini hii inahusiana moja kwa moja na kuingia kwenye Android:

FindAndroidLog_Outputs

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

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

Pia, ikiwa programu za Android zinatumia Msimamizi wa Kazi kwa kazi ya asynchronous, ni wazo nzuri kuwajulisha Checkmarx juu ya hili kwa kuongeza njia ya kupata data kutoka kwa kazi hiyo. getInputData:

TafutaAndroidRead

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

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

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

Kazi: Inatafuta data nyeti katika plist ya miradi ya iOS

ufumbuzi: iOS mara nyingi hutumia faili maalum zilizo na kiendelezi cha .plist ili kuhifadhi vigezo na thamani mbalimbali. Kuhifadhi nywila, ishara, funguo na data nyingine nyeti katika faili hizi haipendekezi, kwani zinaweza kutolewa kutoka kwa kifaa bila matatizo yoyote.

Faili za Plist zina vipengele ambavyo havionekani kwa macho, lakini ni muhimu kwa Checkmarx. Hebu tuandike sheria ambayo itatafuta data tunayohitaji na kutuambia ikiwa nywila au ishara zimetajwa mahali fulani.

Mfano wa faili kama hiyo, ambayo ina ishara ya mawasiliano na huduma ya nyuma:

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

Na sheria ya Checkmarx, ambayo ina nuances kadhaa ambayo inapaswa kuzingatiwa wakati wa kuandika:

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

Kazi: Kupata Habari katika XML

ufumbuzi: Checkmarx ina vitendaji rahisi sana vya kufanya kazi na XML na kutafuta maadili, vitambulisho, sifa na zaidi. Lakini, kwa bahati mbaya, kulikuwa na hitilafu katika nyaraka kutokana na ambayo hakuna mfano mmoja unaofanya kazi. Licha ya ukweli kwamba kasoro hii imeondolewa katika toleo la hivi karibuni la nyaraka, kuwa makini ikiwa unatumia matoleo ya awali ya nyaraka.

Hapa kuna mfano usio sahihi kutoka kwa nyaraka:

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

Kama matokeo ya jaribio la utekelezaji, tutapokea hitilafu ambayo All hakuna njia kama hiyo ... Na hii ni kweli, kwa kuwa kuna nafasi maalum, tofauti ya kitu cha kutumia kazi za kufanya kazi na XML - cxXPath. Hivi ndivyo swali sahihi linavyoonekana kupata mpangilio kwenye Android unaoruhusu matumizi ya trafiki ya HTTP:

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

Wacha tuangalie kwa undani zaidi, kwani syntax ya kazi zote ni sawa, baada ya kufikiria moja, basi unahitaji tu kuchagua unayohitaji. Kwa hivyo, mlolongo kulingana na vigezo:

  • "*.xml"- mask ya faili za kutafutwa

  • 8 - kitambulisho cha lugha ambayo sheria inatumika

  • "cleartextTrafficPermitted"- jina la sifa katika xml

  • "true" - thamani ya sifa hii

  • false - matumizi ya usemi wa kawaida wakati wa kutafuta

  • true — ina maana kwamba utafutaji utafanywa kupuuza kesi, yaani, kesi-isiyojali

Kama mfano, tulitumia sheria inayobainisha kuwa si sahihi, kwa mtazamo wa usalama, mipangilio ya muunganisho wa mtandao kwenye Android ambayo inaruhusu mawasiliano na seva kupitia itifaki ya HTTP. Mfano wa mpangilio ulio na sifa cleartextTrafficPermitted yenye maana 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>

Kazi: Punguza matokeo kwa jina/njia ya faili

ufumbuzi: Katika mojawapo ya miradi mikubwa inayohusiana na uundaji wa programu ya simu ya mkononi ya Android, tulikumbana na mambo chanya ya uwongo ya sheria inayobainisha mpangilio wa kufifisha. Ukweli ni kwamba sheria ya nje ya sanduku hutafuta kwenye faili build.gradle mpangilio unaowajibika kwa kutumia sheria za udhalilishaji kwa toleo la toleo la programu.

Lakini katika miradi mikubwa wakati mwingine kuna faili za watoto build.gradle, ambayo inarejelea maktaba zilizojumuishwa katika mradi huo. Upekee ni kwamba hata ikiwa faili hizi hazionyeshi hitaji la kufichuliwa, mipangilio ya faili ya kusanyiko la mzazi itatumika wakati wa ujumuishaji.

Kwa hivyo, kazi ni kukata vichochezi katika faili za watoto ambazo ni za maktaba. Wanaweza kutambuliwa kwa uwepo wa mstari apply 'com.android.library'.

Nambari ya mfano kutoka kwa faili build.gradle, ambayo huamua hitaji la kufifia:

apply plugin: 'com.android.application'

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

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

dependencies {
  ...
}

Mfano wa faili build.gradle kwa maktaba iliyojumuishwa katika mradi ambao hauna mpangilio huu:

apply plugin: 'android-library'

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

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

Na sheria ya 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);
		}
	}
}

Njia hii inaweza kuwa ya ulimwengu wote na muhimu sio tu kwa programu za Android, lakini pia kwa kesi zingine wakati unahitaji kuamua ikiwa matokeo ni ya faili maalum.

Kazi: Ongeza usaidizi kwa maktaba ya watu wengine ikiwa sintaksia haitumiki kikamilifu

ufumbuzi: Idadi ya mifumo mbalimbali ambayo hutumiwa katika mchakato wa kuandika msimbo iko nje ya chati. Kwa kweli, Checkmarx haijui kila wakati juu ya uwepo wao, na kazi yetu ni kuifundisha kuelewa kuwa njia fulani ni za mfumo huu. Wakati mwingine hii ni ngumu na ukweli kwamba mifumo hutumia majina ya kazi ambayo ni ya kawaida sana na haiwezekani kuamua bila shaka uhusiano wa wito fulani kwa maktaba maalum.

Ugumu ni kwamba syntax ya maktaba kama haya haitambuliwi kila wakati kwa usahihi na lazima ujaribu ili kuzuia kupata idadi kubwa ya chanya za uwongo. Kuna chaguzi kadhaa za kuboresha usahihi wa skanning na kutatua shida:

  • Chaguo la kwanza, tunajua kwa hakika kwamba maktaba hutumiwa katika mradi maalum na inaweza kutumia sheria katika ngazi ya timu. Lakini ikiwa timu itaamua kuchukua mbinu tofauti au kutumia maktaba kadhaa ambamo majina ya utendaji hupishana, tunaweza kupata picha isiyopendeza ya maoni mengi ya uwongo.

  • Chaguo la pili ni kutafuta faili ambazo maktaba imeingizwa wazi. Kwa mbinu hii, tunaweza kuwa na uhakika kwamba maktaba tunayohitaji inatumiwa hasa katika faili hii.

  • Na chaguo la tatu ni kutumia njia mbili hapo juu pamoja.

Kwa mfano, hebu tuangalie maktaba inayojulikana katika miduara nyembamba mjanja kwa lugha ya programu ya Scala, yaani, utendaji Kuchanganya Maadili Halisi. Kwa ujumla, ili kupitisha vigezo kwa swali la SQL, lazima utumie operator $, ambayo hubadilisha data katika hoja iliyorekebishwa ya SQL. Hiyo ni, kwa kweli, ni analog ya moja kwa moja ya Taarifa Iliyotayarishwa katika Java. Lakini, ikiwa unahitaji kuunda hoja ya SQL kwa nguvu, kwa mfano, ikiwa unahitaji kupitisha majina ya jedwali, unaweza kutumia opereta. #$, ambayo itabadilisha data moja kwa moja kwenye hoja (karibu kama uunganishaji wa kamba).

Msimbo wa sampuli:

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

Checkmarx bado haijui jinsi ya kugundua utumiaji wa Maadili halisi na ruka waendeshaji. #$, kwa hivyo hebu tujaribu kuifundisha kutambua sindano zinazowezekana za SQL na kuangazia maeneo sahihi katika msimbo:

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

Kazi: Tafuta vitendakazi vilivyotumika katika mazingira magumu katika maktaba za Chanzo Huria

ufumbuzi: Kampuni nyingi hutumia zana za ufuatiliaji wa Chanzo Huria (mazoezi ya OSA) ili kugundua utumizi wa matoleo hatarishi ya maktaba katika programu zilizotengenezwa. Wakati mwingine haiwezekani kusasisha maktaba kama hiyo kwa toleo salama. Katika baadhi ya matukio kuna mapungufu ya kazi, kwa wengine hakuna toleo salama kabisa. Katika kesi hii, mchanganyiko wa mazoezi ya SAST na OSA itasaidia kubainisha kuwa kazi zinazosababisha unyonyaji wa mazingira magumu hazitumiki katika kanuni.

Lakini wakati mwingine, haswa wakati wa kuzingatia JavaScript, hii inaweza kuwa sio kazi ndogo kabisa. Chini ni suluhisho, labda sio bora, lakini hata hivyo inafanya kazi, kwa kutumia mfano wa udhaifu katika sehemu. lodash katika mbinu template и *set.

Mifano ya majaribio ya msimbo unaoweza kuathirika katika faili ya 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!'

Na wakati wa kuunganisha moja kwa moja kwenye 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>

Tunatafuta mbinu zetu zote zilizo hatarini, ambazo zimeorodheshwa katika udhaifu:

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

Kazi: Inatafuta vyeti vilivyopachikwa kwenye programu

ufumbuzi: Ni kawaida kwa programu, hasa za simu, kutumia vyeti au funguo kufikia seva mbalimbali au kuthibitisha SSL-Pinning. Kwa mtazamo wa usalama, kuhifadhi vitu kama hivyo kwa nambari sio mazoezi bora. Wacha tujaribu kuandika sheria ambayo itatafuta faili zinazofanana kwenye hazina:

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

Kazi: Kupata tokeni zilizoathiriwa katika programu

ufumbuzi: Mara nyingi ni muhimu kubatilisha tokeni zilizoathiriwa au taarifa nyingine muhimu ambayo iko kwenye msimbo. Kwa kweli, kuzihifadhi ndani ya nambari ya chanzo sio wazo nzuri, lakini hali hutofautiana. Shukrani kwa maswali ya CxQL, kupata vitu kama hivi ni rahisi sana:

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

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

Hitimisho

Natumai kuwa nakala hii itakuwa muhimu kwa wale wanaoanza kufahamiana na zana ya Checkmarx. Labda wale ambao wamekuwa wakiandika sheria zao kwa muda mrefu pia watapata kitu muhimu katika mwongozo huu.

Kwa bahati mbaya, kwa sasa kuna ukosefu wa nyenzo ambapo mawazo mapya yanaweza kupatikana wakati wa kuunda sheria za Checkmarx. Ndio maana tumeunda hazina kwenye Github, ambapo tutachapisha kazi yetu ili kila mtu anayetumia CxQL apate kitu muhimu ndani yake, na pia apate fursa ya kushiriki kazi zao na jamii. Hifadhi iko katika mchakato wa kujaza na kuunda yaliyomo, kwa hivyo wachangiaji wanakaribishwa!

Asante!

Chanzo: mapenzi.com

Kuongeza maoni