Conas rialacha a scríobh do Checkmarx gan dul ar mire

Hey Habr!

Inár gcuid oibre, is minic a dhéileálann ár gcuideachta le huirlisí éagsúla anailíse cód statach (SAST). Amach as an mbosca oibríonn siad go léir meán. Ar ndóigh, braitheann sé go léir ar an tionscadal agus na teicneolaíochtaí a úsáidtear ann, chomh maith le cé chomh maith agus atá na teicneolaíochtaí seo clúdaithe ag na rialacha anailíse. I mo thuairimse, is é ceann de na critéir is tábhachtaí agus uirlis SAST á roghnú agat ná an cumas é a shaincheapadh de réir sonraí d'iarratais, eadhon, rialacha anailíse a scríobh agus a athrú nó, mar a thugtar orthu níos minice, Ceisteanna Saincheaptha.

Conas rialacha a scríobh do Checkmarx gan dul ar mire

Is minic a úsáidimid Checkmarx - anailísí cód an-suimiúil agus cumhachtach. San Airteagal seo labhróidh mé faoi mo thaithí ar rialacha anailíse a scríobh dó.

Tábla na nÁbhar

Iontráil

Ar dtús, ba mhaith liom ceann de na cúpla alt i Rúisis a mholadh faoi na gnéithe a bhaineann le ceisteanna a scríobh do Checkmarx. Foilsíodh é ar Habré ag deireadh na bliana 2019 faoin teideal: "Dia duit, Checkmarx!" Conas ceist SAST Checkmarx a scríobh agus leochaileachtaí iontacha a aimsiú.

Scrúdaíonn sé go mion conas na chéad cheisteanna a scríobh i CxQL (Teanga Iarratas Checkmarx) le haghaidh roinnt feidhmchlár tástála agus taispeánann sé na bunphrionsabail maidir le conas a oibríonn rialacha anailíse.

Ní dhéanfaidh mé athrá ar a bhfuil cur síos air, cé go mbeidh roinnt crosbhealaí fós i láthair. I m’alt déanfaidh mé iarracht cineál “bailiúchán oidis” a thiomsú, liosta de na réitigh ar fhadhbanna sonracha a tháinig orm le linn mo chuid oibre le Checkmarx. Bhí orm mo chuid smaointe a raiceáil thar go leor de na fadhbanna seo. Uaireanta ní raibh go leor faisnéise sa doiciméadú, agus uaireanta bhí sé deacair fiú a thuiscint conas a dhéanamh ar an méid a bhí ag teastáil. Tá súil agam nach mbeidh mo thaithí agus oícheanta gan chodladh in vain, agus sábhálfaidh an “bailiúchán oidis Saincheaptha” seo cúpla uair an chloig nó cúpla cealla nerve duit. Mar sin, déanaimis tosú!

Eolas ginearálta ar na rialacha

Ar dtús, déanaimis féachaint ar roinnt bunchoincheapa agus ar an bpróiseas a bhaineann le bheith ag obair leis na rialacha, chun tuiscint níos fearr a fháil ar cad a tharlóidh ina dhiaidh sin. Agus freisin toisc nach bhfuil an doiciméadú a rá rud ar bith faoi seo nó go bhfuil an-leathadh amach sa struchtúr, nach bhfuil an-áisiúil.

  1. Cuirtear na rialacha i bhfeidhm le linn scanadh ag brath ar an réamhshocrú a roghnaíodh ag an tús (sraith de rialacha gníomhacha). Is féidir leat líon neamhtheoranta réamhshocruithe a chruthú, agus braitheann an chaoi ar cheart iad a struchtúrú ar shonraí do phróisis. Is féidir leat iad a ghrúpáil de réir teanga nó réamhshocruithe a roghnú do gach tionscadal. Bíonn tionchar ag líon na rialacha gníomhacha ar luas agus cruinneas an scanadh.

    Conas rialacha a scríobh do Checkmarx gan dul ar mireSocrú Réamhshocraithe sa chomhéadan Checkmarx

  2. Cuirtear na rialacha in eagar in uirlis speisialta ar a dtugtar CxAuditor. Feidhmchlár deisce é seo a nascann le freastalaí a ritheann Checkmarx. Tá dhá mhodh oibríochta ag an uirlis seo: eagarthóireacht a dhéanamh ar rialacha agus anailís a dhéanamh ar thorthaí scanadh atá déanta cheana féin.

    Conas rialacha a scríobh do Checkmarx gan dul ar mireComhéadan CxIniúchadh

  3. Roinntear rialacha i Checkmarx de réir teanga, is é sin, tá a sraith fiosrúchán féin ag gach teanga. Tá roinnt rialacha ginearálta ann freisin a bhfuil feidhm acu beag beann ar theanga, is iad seo na ceisteanna bunúsacha mar a thugtar orthu. Den chuid is mó, baineann ceisteanna bunúsacha le cuardach a dhéanamh ar fhaisnéis a úsáideann rialacha eile.

    Conas rialacha a scríobh do Checkmarx gan dul ar mireRialacha a roinnt de réir teanga

  4. Tá na rialacha “Infheidhmithe” agus “Neamh-Inrite” (Forghníomhaithe agus Neamhfhorghníomhaithe). Níl an t-ainm ceart go leor, i mo thuairim, ach sin mar atá sé. Is é an bun líne ná go dtaispeánfar toradh rialacha “Inrite” a fhorghníomhú i dtorthaí an scanadh san Chomhéadain, agus níl gá le rialacha “Neamh-Inrite” ach amháin chun a dtorthaí a úsáid in iarratais eile (go bunúsach, níl ann ach feidhm).

    Conas rialacha a scríobh do Checkmarx gan dul ar mireCinneadh an cineál riail nuair a chruthú

  5. Is féidir leat rialacha nua a chruthú nó na cinn atá ann cheana a fhorlíonadh/a athscríobh. Chun riail a athscríobh, ní mór duit é a fháil sa chrann, deaschliceáil agus roghnaigh "Sáraigh" ón roghchlár anuas. Tá sé tábhachtach a mheabhrú anseo nach bhfuil na rialacha nua san áireamh ar dtús leis na réamhshocruithe agus nach bhfuil siad gníomhach. Chun iad a úsáid ní mór duit iad a ghníomhachtú sa roghchlár “Bainisteoir Réamhshocraithe” san ionstraim. Coinníonn rialacha athscríofa a gcuid socruithe, is é sin, dá mbeadh an riail gníomhach, fanfaidh sé amhlaidh agus cuirfear i bhfeidhm láithreach é.

    Conas rialacha a scríobh do Checkmarx gan dul ar mireSampla de riail nua sa chomhéadan Bainisteoir Réamhshocraithe

  6. Le linn an fhorghníomhaithe, tógtar “crann” d'iarratais, a bhraitheann ar cad é. Déantar na rialacha a bhailíonn faisnéis a fhorghníomhú ar dtús, agus na daoine a úsáideann í sa dara háit. Tá an toradh forghníomhaithe i dtaisce, mar sin má tá sé indéanta torthaí riail atá ann cheana féin a úsáid, ansin is fearr é sin a dhéanamh, laghdóidh sé seo an t-am scanadh.

  7. Is féidir rialacha a chur i bhfeidhm ar leibhéil éagsúla:

  • Chun an córas ar fad - a úsáid le haghaidh aon scanadh ar aon tionscadal

  • Ag an leibhéal foirne (Foireann) - a úsáid ach amháin chun tionscadail a scanadh ar an bhfoireann roghnaithe.

  • Ag an leibhéal tionscadail - An mbeidh a chur i bhfeidhm i dtionscadal ar leith

    Conas rialacha a scríobh do Checkmarx gan dul ar mireAn leibhéal ag a gcuirfear an riail i bhfeidhm a chinneadh

"Foclóir" do thosaitheoirí

Agus tosóidh mé le cúpla rud a chuir ceisteanna orm, agus taispeánfaidh mé freisin roinnt teicnící a shimpleoidh an saol go suntasach.

Oibríochtaí le liostaí

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

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

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

Gach earra aimsithe

Laistigh den teanga scanta, is féidir leat liosta a fháil de na heilimintí go léir atá aitheanta ag Checkmarx (teaghráin, feidhmeanna, ranganna, modhanna, etc.). Seo roinnt spáis de rudaí ar féidir rochtain a fháil orthu All. Is é sin, cuardach a dhéanamh ar rud a bhfuil ainm sonrach air searchMe, is féidir leat cuardach a dhéanamh, mar shampla, de réir ainm thar gach réad aimsithe:

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

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

Ach, más gá duit cuardach a dhéanamh i dteanga eile nach raibh san áireamh sa scanadh ar chúis éigin (mar shampla, groovy i dtionscadal Android), is féidir leat ár spás oibiachta a leathnú trí athróg:

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

Feidhmeanna le haghaidh anailís sreafa

Baintear úsáid as na feidhmeanna seo i go leor rialacha agus anseo tá bileog bheag cheat ar a bhfuil i gceist leo:

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

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

Ainm comhaid / cosán a fháil

Tá roinnt tréithe ann ar féidir a fháil ó thorthaí fiosrúcháin (ainm an chomhaid ina bhfuarthas an iontráil, teaghrán, etc.), ach ní deir an doiciméadú conas iad a fháil agus a úsáid. Mar sin, chun é seo a dhéanamh, ní mór duit rochtain a fháil ar an maoin LinePragma agus beidh na rudaí a theastaíonn uainn suite taobh istigh de:

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

Is fiú a choinneáil i gcuimhne go bhfuil FileName ina bhfuil iarbhír an cosán go dtí an comhad, ó úsáid againn ar an modh GetFirstGraph.

Toradh forghníomhaithe

Tá athróg speisialta taobh istigh de CxQL result, a thugann ar ais an toradh ar fhorghníomhú do riail scríofa. Cuirtear tús leis láithreach agus is féidir leat torthaí idirmheánacha a scríobh isteach ann, iad a athrú agus a scagadh de réir mar a oibríonn tú. Ach, mura sanntar an athróg nó an fheidhm seo laistigh den riail return— ní bheidh an toradh forghníomhaithe i gcónaí.

Ní chuirfidh an cheist seo a leanas aon rud ar ais chugainn mar thoradh ar fhorghníomhú agus beidh sé folamh i gcónaí:

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

Ach, tar éis an toradh forghníomhaithe a shannadh don toradh athróg draíochta, feicfimid cad a thugann an glao seo ar ais chugainn:

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

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

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

Ag baint úsáide as torthaí rialacha eile

Is féidir rialacha i Checkmarx a chur ar aon dul le feidhmeanna i dteanga ríomhchlárúcháin rialta. Agus riail á scríobh agat, b’fhéidir go mbainfeá úsáid as torthaí ceisteanna eile. Mar shampla, ní gá cuardach a dhéanamh ar gach modh glaonna sa chód gach uair, ach glaoch ar an riail atá ag teastáil:

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

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

Ligeann an cur chuige seo duit an cód a ghiorrú agus an t-am forghníomhaithe riail a laghdú go suntasach.

Fadhbanna a réiteach

Logáil

Nuair a bhíonn tú ag obair leis an uirlis, uaireanta ní féidir an cheist atá ag teastáil a scríobh láithreach agus caithfidh tú triail a bhaint as roghanna éagsúla. I gcás den sórt sin, soláthraíonn an uirlis logáil, ar a dtugtar mar seo a leanas:

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

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

Ach is fiú cuimhneamh nach nglacann an modh seo ach mar ionchur sreangán, mar sin ní bheidh sé indéanta liosta iomlán de na heilimintí aimsithe a thaispeáint mar thoradh ar an gcéad oibríocht. Is é an dara rogha, a úsáidtear le haghaidh dífhabhtaithe, ná sannadh d’athróg draíochta ó am go chéile result toradh na ceiste agus féach cad a tharlaíonn. Níl an cur chuige seo an-áisiúil; ní mór duit a bheith cinnte nach bhfuil aon sáruithe ná oibríochtaí leis seo sa chód ina dhiaidh sin result nó go simplí trácht ar an gcód thíos. Nó is féidir leat, cosúil liomsa, dearmad a dhéanamh ar roinnt glaonna den sórt sin a bhaint de riail réamhdhéanta agus smaoineamh ar an bhfáth nach n-oibríonn aon rud.

Bealach níos áisiúla ná an modh a ghlaoch return leis an bparaiméadar riachtanach. Sa chás seo, cuirfear deireadh le forghníomhú na rialach agus beimid in ann a fheiceáil cad a tharla mar thoradh ar an méid a scríobh muid:

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

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

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

Fadhb logáil isteach

Bíonn cásanna ann nuair nach féidir leat rochtain a fháil ar an uirlis CxAudit (a úsáidtear chun rialacha a scríobh). Is féidir go leor cúiseanna a bheith leis seo, lena n-áirítear tuairteanna, nuashonruithe tobanna Windows, BSOD agus cásanna eile gan choinne nach bhfuil aon smacht againn orthu. Sa chás seo, uaireanta tá seisiún neamhchríochnaithe sa bhunachar sonraí, rud a chuireann cosc ​​​​ort logáil isteach arís. Chun é a dheisiú, ní mór duit roinnt ceisteanna a rith:

Le haghaidh Checkmarx roimh 8.6:

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

Le haghaidh Checkmarx tar éis 8.6:

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

Rialacha a scríobh

Anois a fháil againn go dtí an chuid is suimiúla. Nuair a thosaíonn tú ag scríobh rialacha i CxQL, ní hé an rud a bhíonn in easnamh ort go minic ná an oiread sin doiciméadachta agus roinnt samplaí beo d’fhadhbanna áirithe a réiteach agus cur síos ar an bpróiseas fiosrúcháin go ginearálta.

Déanfaidh mé iarracht an saol a dhéanamh beagán níos éasca dóibh siúd atá ag tosú ag tumadh isteach i dteanga na gceisteanna agus tabharfaidh mé roinnt samplaí de Cheisteanna Saincheaptha a úsáid chun fadhbanna áirithe a réiteach. Tá cuid acu sách ginearálta agus is féidir iad a úsáid i do chuideachta go praiticiúil gan athruithe, tá cuid eile níos sainiúla, ach is féidir iad a úsáid freisin tríd an gcód a athrú chun freastal ar shaintréithe d'fheidhmchláir.

Mar sin, seo iad na fadhbanna is minicí a bhí againn:

Tasc: Tá roinnt Sreabhadh i dtorthaí an riail a fhorghníomhú agus tá ceann acu ina neadú ar cheann eile, ní mór duit ceann acu a fhágáil.

réiteach: Go deimhin, uaireanta léiríonn Checkmarx roinnt sreafaí sonraí a d’fhéadfadh forluí a dhéanamh agus a bheith ina leagan giorraithe de chinn eile. Tá modh speisialta ann do chásanna den sórt sin Laghdú ar Shreabhadh. Ag brath ar an bparaiméadar, roghnóidh sé an Sreabhadh is giorra nó is faide:

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

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

Tasc: Leathnaigh liosta na sonraí íogaire a n-imoibríonn an uirlis leo

réiteach: Tá bunrialacha ag Checkmarx, agus baineann go leor ceisteanna eile úsáid as na torthaí. Trí chuid de na rialacha seo a fhorlíonadh le sonraí a bhaineann go sonrach le d’iarratas, is féidir leat do thorthaí scanadh a fheabhsú láithreach. Seo thíos sampla de riail chun tú a chur ar bun:

Liosta_sárú_príobháideachais ghinearálta

Cuirimis roinnt athróg leis a úsáidtear inár bhfeidhmchlár chun faisnéis íogair a stóráil:

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

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

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

Tasc: Leathnaigh liosta na n-athróg le pasfhocail

réiteach: Ba mhaith liom a mholadh láithreach aird a thabhairt ar an riail bhunúsach chun pasfhocail a shainiú i gcód agus liosta d'ainmneacha athraitheacha a úsáidtear go coitianta i do chuideachta a chur leis.

Pasfhocal_príobháideachta_liosta_sárú

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

Tasc: Cuir creataí úsáidte leis nach dtacaíonn Checkmarx leo

réiteach: Roinntear gach ceist i Checkmarx de réir teanga, mar sin ní mór duit rialacha a chur leis do gach teanga. Seo thíos roinnt samplaí de rialacha den sórt sin.

Má úsáidtear leabharlanna a chomhlánaíonn nó a athsholáthar feidhmiúlacht chaighdeánach, is furasta iad a chur leis an riail bhunúsach. Ansin foghlaimeoidh gach duine a úsáideann é láithreach faoi na réamhrá nua. Mar shampla, is iad Adhmad agus Loggi na leabharlanna chun logáil isteach ar Android. Sa bhunphacáiste, níl aon rialacha ann chun glaonna neamhchórais a shainaithint, mar sin má théann pasfhocal nó aitheantóir seisiúin isteach sa logáil, ní bheidh a fhios againn faoi. Déanaimis iarracht sainmhínithe ar mhodhanna den sórt sin a chur le rialacha Checkmarx.

Sampla de chóid tástála a úsáideann an leabharlann Adhmaid le logáil:

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

Agus seo sampla d’iarratas ar Checkmarx, a ligfidh duit sainmhíniú a chur leis ar ghlaoch ar mhodhanna adhmaid mar phointe scoir le haghaidh sonraí ón bhfeidhmchlár:

FindAndroidAschuir

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

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

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

Agus is féidir leat cur leis an riail chomharsanacht freisin, ach baineann an ceann seo go díreach le logáil Android:

FindAndroidLog_Aschuir

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

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

Chomh maith leis sin, má úsáideann iarratais Android Bainisteoir Oibre maidir le hobair asincrónach, is smaoineamh maith é seo a chur in iúl do Checkmarx freisin trí mhodh a chur leis chun sonraí a fháil ón tasc getInputData:

FindAndroidRead

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

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

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

Tasc: Cuardach le haghaidh sonraí íogaire i plist do thionscadail iOS

réiteach: Is minic a úsáideann iOS comhaid speisialta leis an síneadh .plist chun athróga agus luachanna éagsúla a stóráil. Ní mholtar pasfhocail, comharthaí, eochracha agus sonraí íogaire eile a stóráil sna comhaid seo, mar is féidir iad a bhaint as an bhfeiste gan aon fhadhbanna.

Tá gnéithe ag comhaid plist nach léir don tsúil nocht, ach atá tábhachtach do Checkmarx. Scríobhfaimid riail a chuardóidh na sonraí a theastaíonn uainn agus a inseoidh dúinn an bhfuil pasfhocail nó comharthaí luaite áit éigin.

Sampla de chomhad den sórt sin, ina bhfuil comhartha cumarsáide leis an tseirbhís inneall:

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

Agus riail le haghaidh Checkmarx, a bhfuil roinnt nuances ann ba chóir a chur san áireamh agus tú ag scríobh:

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

Tasc: Ag lorg faisnéise in XML

réiteach: Tá feidhmeanna an-áisiúil ag Checkmarx chun oibriú le XML agus chun luachanna, clibeanna, tréithe agus go leor eile a chuardach. Ach, ar an drochuair, bhí earráid sa doiciméadú agus ní oibríonn sampla amháin dá bharr. In ainneoin go bhfuil deireadh curtha leis an locht seo sa leagan is déanaí den doiciméadú, bí cúramach má úsáideann tú leaganacha níos luaithe de dhoiciméid.

Seo sampla mícheart ón doiciméadú:

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

Mar thoradh ar an iarracht forghníomhaithe, gheobhaidh muid earráid a All níl a leithéid de mhodh ann... Agus tá sé seo fíor, ós rud é go bhfuil spás oibiachta ar leith ann chun feidhmeanna a úsáid chun oibriú le XML - cxXPath. Seo an chuma atá ar an gceist cheart chun socrú a aimsiú in Android a cheadaíonn úsáid tráchta HTTP:

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

Breathnaímid air go mion, ós rud é go bhfuil comhréir na bhfeidhmeanna go léir cosúil, tar éis duit ceann a dhéanamh amach, ní mór duit ach an ceann atá uait a roghnú. Mar sin, go seicheamhach de réir na bparaiméadar:

  • "*.xml"— masc comhaid le cuardach

  • 8 — id na teanga a gcuirtear an riail i bhfeidhm ina leith

  • "cleartextTrafficPermitted"— ainm tréithe in xml

  • "true" — luach an tréith seo

  • false — slonn rialta a úsáid agus tú ag cuardach

  • true — ciallaíonn sé go ndéanfar an cuardach gan aird a thabhairt ar chás, is é sin, cás-neamhíogair

Mar shampla, d’úsáideamar riail a shainaithníonn socruithe nasc líonra mícheart, ó thaobh slándála de, in Android a cheadaíonn cumarsáid leis an bhfreastalaí tríd an bprótacal HTTP. Sampla de shocrú ina bhfuil tréith cleartextTrafficPermitted le brí 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>

Tasc: Teorainn na torthaí de réir ainm comhaid/conair

réiteach: I gceann de na tionscadail mhóra a bhaineann le feidhmchlár soghluaiste a fhorbairt le haghaidh Android, thángamar ar rudaí bréagacha dearfacha den riail a chinneann an socrú fuascailte. Is é an bhfíric go bhfuil an riail amach as an bhosca cuardaigh sa chomhad build.gradle suíomh atá freagrach as rialacha um obfuscation a chur i bhfeidhm don leagan den fheidhmchlár a scaoileadh.

Ach i dtionscadail mhóra uaireanta tá comhaid leanaí build.gradle, a thagraíonn do na leabharlanna atá sa tionscadal. Is é an rud is suntasaí ná fiú mura dtugann na comhaid seo le fios go bhfuil gá le doiléire, cuirfear socruithe an chomhaid tionóil tuismitheora i bhfeidhm le linn an tiomsaithe.

Mar sin, is é an tasc atá ann ná truicear i gcomhaid leanaí a bhaineann le leabharlanna a ghearradh amach. Is féidir iad a aithint trí láithreacht na líne apply 'com.android.library'.

Sampla cód as comhad build.gradle, a chinneann an gá atá le obfuscation:

apply plugin: 'com.android.application'

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

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

dependencies {
  ...
}

Comhad samplach build.gradle do leabharlann atá san áireamh sa tionscadal nach bhfuil an socrú seo aici:

apply plugin: 'android-library'

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

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

Agus an riail le haghaidh 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);
		}
	}
}

Is féidir an cur chuige seo a bheith go leor uilíoch agus úsáideach, ní hamháin le haghaidh feidhmchláir Android, ach freisin i gcásanna eile nuair is gá duit a chinneadh an mbaineann toradh le comhad ar leith.

Tasc: Cuir tacaíocht leis do leabharlann tríú páirtí mura bhfuil an chomhréir lántacaithe

réiteach: Tá líon na gcreatanna éagsúla a úsáidtear i bpróiseas scríofa an chóid go simplí as na cairteacha. Ar ndóigh, ní bhíonn a fhios ag Checkmarx i gcónaí faoina bhfuil ann, agus is é an tasc atá againn ná é a mhúineadh chun a thuiscint go mbaineann modhanna áirithe leis an gcreat seo go sonrach. Uaireanta bíonn sé seo casta ag an bhfíric go n-úsáideann creataí ainmneacha feidhmeanna atá an-choitianta agus nach féidir a chinneadh gan athbhrí an gaol atá ag glaoch ar leith le leabharlann ar leith.

Is é an deacracht nach n-aithnítear comhréir na leabharlanna sin i gceart i gcónaí agus ní mór duit triail a bhaint as chun líon mór dearfacha bréagacha a sheachaint. Tá roinnt roghanna ann chun cruinneas scanadh a fheabhsú agus an fhadhb a réiteach:

  • An chéad rogha, tá a fhios againn go cinnte go n-úsáidtear an leabharlann i dtionscadal ar leith agus is féidir leis an riail a chur i bhfeidhm ag leibhéal na foirne. Ach má chinneann an fhoireann cur chuige difriúil a ghlacadh nó má úsáideann siad roinnt leabharlanna ina bhfuil forluí ar ainmneacha feidhmeanna, is féidir linn pictiúr nach bhfuil an-taitneamhach a fháil ar an iliomad dearfach bréagach.

  • Is é an dara rogha cuardach a dhéanamh ar chomhaid ina bhfuil an leabharlann iompórtáilte go soiléir. Leis an gcur chuige seo, is féidir linn a bheith cinnte go n-úsáidtear go beacht an leabharlann a theastaíonn uainn sa chomhad seo.

  • Agus is é an tríú rogha ná an dá chur chuige thuas a úsáid le chéile.

Mar shampla, déanaimis féachaint ar leabharlann atá ar eolas go maith i gciorcail chaol slick don teanga ríomhchlárúcháin Scala, eadhon, an fheidhmiúlacht Splicing Luachanna Liteartha. Go ginearálta, chun paraiméadair a chur ar aghaidh chuig ceist SQL, ní mór duit an t-oibreoir a úsáid $, a ionadaíonn sonraí i bhfiosrúchán SQL réamhfhoirmithe. Is é sin, go deimhin, is analóg díreach é den Ráiteas Ullmhaithe i Java. Ach, más gá duit ceist SQL a thógáil go dinimiciúil, mar shampla, más gá duit ainmneacha táblaí a phasáil, is féidir leat an t-oibreoir a úsáid #$, a ionadóidh na sonraí go díreach isteach sa cheist (beagnach cosúil le comhchatún teaghrán).

Cód primer:

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

Níl a fhios ag Checkmarx go fóill conas úsáid oibreoirí Splicing Literal Values ​​agus scipeanna a bhrath #$, mar sin déanaimis iarracht é a mhúineadh chun instealltaí SQL féideartha a aithint agus na háiteanna cearta sa chód a aibhsiú:

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

Tasc: Cuardaigh feidhmeanna leochaileacha úsáidte i leabharlanna Foinse Oscailte

réiteach: Úsáideann go leor cuideachtaí uirlisí monatóireachta Foinse Oscailte (cleachtas OSA) chun úsáid leaganacha leochaileacha de leabharlanna a bhrath i bhfeidhmchláir fhorbartha. Uaireanta ní féidir leabharlann den sórt sin a nuashonrú go leagan slán. I gcásanna áirithe tá teorainneacha feidhmiúla, i gcásanna eile níl aon leagan sábháilte ar chor ar bith. Sa chás seo, cabhróidh meascán de chleachtais SAST agus OSA lena chinneadh nach n-úsáidtear na feidhmeanna as a n-eascraíonn saothrú na leochaileachta sa chód.

Ach uaireanta, go háirithe nuair a bhíonn JavaScript á bhreithniú, b'fhéidir nach tasc iomlán fánach é seo. Anseo thíos tá réiteach, b'fhéidir nach bhfuil idéalach, ach mar sin féin ag obair, ag baint úsáide as an sampla de leochaileachtaí sa chomhpháirt lodash ar mhodhanna template и *set.

Samplaí de chód tástála a d’fhéadfadh a bheith leochaileach i gcomhad 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!'

Agus nuair a nascadh go díreach i 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>

Táimid ag lorg ár modhanna leochaileacha go léir, atá liostaithe i leochaileachtaí:

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

Tasc: Ag cuardach teastais leabaithe san fheidhmchlár

réiteach: Níl sé neamhchoitianta d’fheidhmchláir, go háirithe cinn shoghluaiste, teastais nó eochracha a úsáid chun teacht ar fhreastalaithe éagsúla nó SSL-Pinning a fhíorú. Ó thaobh na slándála de, ní hé an cleachtas is fearr é rudaí den sórt sin a stóráil i gcód. Déanaimis iarracht riail a scríobh a chuardóidh comhaid chomhchosúla sa stór:

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

Tasc: Comharthaí comhréiteach a aimsiú san fheidhmchlár

réiteach: Is minic is gá comharthaí comhréitigh nó faisnéis thábhachtach eile atá sa chód a chúlghairm. Ar ndóigh, ní smaoineamh maith é iad a stóráil taobh istigh den chód foinse, ach athraíonn cásanna. A bhuí le ceisteanna CxQL, tá sé éasca go leor rudaí mar seo a aimsiú:

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

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

Conclúid

Tá súil agam go mbeidh an t-alt seo úsáideach dóibh siúd atá ag tosú ar a aithne leis an uirlis Checkmarx. B'fhéidir go bhfaighidh siad siúd atá ag scríobh a rialacha féin le fada an lá rud éigin úsáideach sa treoir seo freisin.

Ar an drochuair, tá easpa acmhainne ann faoi láthair ina bhféadfaí smaointe nua a bhailiú le linn na rialacha a fhorbairt le haghaidh Checkmarx. Sin an fáth a chruthaigh muid stór ar Github, áit a ndéanfaimid ár gcuid oibre a phostáil ionas go mbeidh gach duine a úsáideann CxQL in ann rud éigin úsáideach a fháil ann, agus go mbeidh deis acu freisin a gcuid oibre a roinnt leis an bpobal. Tá an stór i mbun ábhar a líonadh agus a struchtúrú, mar sin tá fáilte roimh rannpháirtithe!

Go raibh maith agat as bhur n-aire!

Foinse: will.com

Add a comment