Sut i ysgrifennu rheolau ar gyfer Checkmarx heb fynd yn wallgof

Hei Habr!

Yn ein gwaith, mae ein cwmni'n aml iawn yn delio ag amrywiol offer dadansoddi cod statig (SAST). Allan o'r bocs maent i gyd yn gweithio ar gyfartaledd. Wrth gwrs, mae'r cyfan yn dibynnu ar y prosiect a'r technolegau a ddefnyddir ynddo, yn ogystal â pha mor dda y mae'r technolegau hyn yn dod o dan y rheolau dadansoddi. Yn fy marn i, un o'r meini prawf pwysicaf wrth ddewis teclyn SAST yw'r gallu i'w addasu i fanylion eich cymwysiadau, sef, ysgrifennu a newid rheolau dadansoddi neu, fel y'u gelwir yn amlach, Custom Queries.

Sut i ysgrifennu rheolau ar gyfer Checkmarx heb fynd yn wallgof

Rydym yn defnyddio Checkmarx amlaf - dadansoddwr cod diddorol a phwerus iawn. Yn yr erthygl hon byddaf yn siarad am fy mhrofiad o ysgrifennu rheolau dadansoddi ar ei gyfer.

Tabl cynnwys

Mynediad

I ddechrau, hoffwn argymell un o'r ychydig erthyglau yn Rwsieg am nodweddion ysgrifennu ymholiadau ar gyfer Checkmarx. Fe'i cyhoeddwyd ar Habré ddiwedd 2019 o dan y teitl: "Helo, Checkmarx!" Sut i ysgrifennu ymholiad SAST Checkmarx a dod o hyd i wendidau cŵl.

Mae'n archwilio'n fanwl sut i ysgrifennu'r ymholiadau cyntaf yn CxQL (Iaith Ymholiad Checkmarx) ar gyfer rhai cymwysiadau prawf ac yn dangos egwyddorion sylfaenol sut mae rheolau dadansoddi yn gweithio.

Nid ailadroddaf yr hyn a ddisgrifir ynddo, er y bydd rhai croestoriadau yn dal i fod yn bresennol. Yn fy erthygl byddaf yn ceisio llunio math o “gasgliad o ryseitiau”, sef rhestr o atebion i broblemau penodol y deuthum ar eu traws yn ystod fy ngwaith gyda Checkmarx. Roedd yn rhaid i mi dynnu fy ymennydd dros lawer o'r problemau hyn. Weithiau nid oedd digon o wybodaeth yn y ddogfennaeth, ac weithiau roedd hyd yn oed yn anodd deall sut i wneud yr hyn oedd ei angen. Gobeithio na fydd fy mhrofiad a nosweithiau digwsg yn ofer, a bydd y “casgliad hwn o ryseitiau Custom Queries” yn arbed ychydig oriau neu gwpl o gelloedd nerfol i chi. Felly, gadewch i ni ddechrau!

Gwybodaeth gyffredinol am y rheolau

Yn gyntaf, gadewch i ni edrych ar ychydig o gysyniadau sylfaenol a'r broses o weithio gyda'r rheolau, i gael gwell dealltwriaeth o'r hyn a fydd yn digwydd nesaf. A hefyd oherwydd nad yw'r ddogfennaeth yn dweud unrhyw beth am hyn neu'n wasgaredig iawn yn y strwythur, nad yw'n gyfleus iawn.

  1. Mae'r rheolau yn cael eu cymhwyso yn ystod sganio yn dibynnu ar y rhagosodiad a ddewiswyd ar y dechrau (set o reolau gweithredol). Gallwch greu nifer anghyfyngedig o ragosodiadau, ac mae sut yn union i'w strwythuro yn dibynnu ar fanylion eich proses. Gallwch eu grwpio yn ôl iaith neu ddewis rhagosodiadau ar gyfer pob prosiect. Mae nifer y rheolau gweithredol yn effeithio ar gyflymder a chywirdeb sganio.

    Sut i ysgrifennu rheolau ar gyfer Checkmarx heb fynd yn wallgofSefydlu Rhagosodiad yn y rhyngwyneb Checkmarx

  2. Mae'r rheolau'n cael eu golygu mewn teclyn arbennig o'r enw CxAuditor. Mae hwn yn gymhwysiad bwrdd gwaith sy'n cysylltu â gweinydd sy'n rhedeg Checkmarx. Mae gan yr offeryn hwn ddau ddull gweithredu: golygu rheolau a dadansoddi canlyniadau sgan sydd eisoes wedi'i berfformio.

    Sut i ysgrifennu rheolau ar gyfer Checkmarx heb fynd yn wallgofrhyngwyneb CxArchwilio

  3. Rhennir rheolau yn Checkmarx yn ôl iaith, hynny yw, mae gan bob iaith ei set ei hun o ymholiadau. Mae yna hefyd rai rheolau cyffredinol sy'n berthnasol waeth beth fo'r iaith, sef yr hyn a elwir yn ymholiadau sylfaenol. Ar y cyfan, mae ymholiadau sylfaenol yn ymwneud â chwilio am wybodaeth y mae rheolau eraill yn ei defnyddio.

    Sut i ysgrifennu rheolau ar gyfer Checkmarx heb fynd yn wallgofRhannu rheolau yn ôl iaith

  4. Mae'r rheolau yn “Gweithrediadadwy” ac “Anweithredol” (Wedi'u Gweithredu a Heb ei Weithredu). Ddim cweit yr enw cywir, yn fy marn i, ond dyna beth ydyw. Y gwir amdani yw y bydd canlyniad gweithredu rheolau “Gweithredadwy” yn cael ei arddangos yn y canlyniadau sgan yn yr UI, ac mae angen rheolau “Anweithredol” dim ond i ddefnyddio eu canlyniadau mewn ceisiadau eraill (yn y bôn, dim ond swyddogaeth).

    Sut i ysgrifennu rheolau ar gyfer Checkmarx heb fynd yn wallgofPenderfynu ar y math o reol wrth greu

  5. Gallwch greu rheolau newydd neu ychwanegu at/ailysgrifennu rhai sy'n bodoli eisoes. Er mwyn ailysgrifennu rheol, mae angen i chi ddod o hyd iddi yn y goeden, de-gliciwch a dewis "Diystyru" o'r gwymplen. Mae'n bwysig cofio yma nad yw'r rheolau newydd wedi'u cynnwys yn y rhagosodiadau i ddechrau ac nad ydynt yn weithredol. I ddechrau eu defnyddio mae angen i chi eu actifadu yn y ddewislen "Rheolwr Rhagosodedig" yn yr offeryn. Mae rheolau a ailysgrifennwyd yn cadw eu gosodiadau, hynny yw, os oedd y rheol yn weithredol, bydd yn parhau felly a bydd yn cael ei chymhwyso ar unwaith.

    Sut i ysgrifennu rheolau ar gyfer Checkmarx heb fynd yn wallgofEnghraifft o reol newydd yn y rhyngwyneb Rheolwr Rhagosodedig

  6. Yn ystod y gweithredu, mae “coeden” o geisiadau yn cael ei hadeiladu, sy'n dibynnu ar beth. Gweithredir y rheolau sy'n casglu gwybodaeth yn gyntaf, a'r rhai sy'n ei defnyddio yn ail. Mae'r canlyniad gweithredu wedi'i storio, felly os yw'n bosibl defnyddio canlyniadau rheol bresennol, yna mae'n well gwneud hynny, bydd hyn yn lleihau'r amser sganio.

  7. Gellir cymhwyso rheolau ar wahanol lefelau:

  • Ar gyfer y system gyfan - yn cael ei ddefnyddio ar gyfer unrhyw sganio o unrhyw brosiect

  • Ar lefel tîm (Tîm) - yn cael ei ddefnyddio i sganio prosiectau yn y tîm a ddewiswyd yn unig.

  • Ar y lefel prosiect - A fydd yn cael ei gymhwyso mewn prosiect penodol

    Sut i ysgrifennu rheolau ar gyfer Checkmarx heb fynd yn wallgofPennu ar ba lefel y bydd y rheol yn cael ei chymhwyso

“Geiriadur” i ddechreuwyr

A byddaf yn dechrau gydag ychydig o bethau a achosodd gwestiynau i mi, a byddaf hefyd yn dangos nifer o dechnegau a fydd yn symleiddio bywyd yn sylweddol.

Gweithrediadau gyda rhestrau

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

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

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

Pob eitem a ddarganfuwyd

O fewn yr iaith wedi'i sganio, gallwch gael rhestr o'r holl elfennau y mae Checkmarx wedi'u nodi (llinynnau, swyddogaethau, dosbarthiadau, dulliau, ac ati). Dyma rywfaint o ofod o wrthrychau y gellir mynd atynt All. Hynny yw, i chwilio am wrthrych ag enw penodol searchMe, gallwch chwilio, er enghraifft, yn ôl enw ar draws yr holl wrthrychau a ddarganfuwyd:

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

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

Ond, os oes angen i chi chwilio mewn iaith arall na chafodd ei chynnwys yn y sgan am ryw reswm (er enghraifft, grwfi mewn prosiect Android), gallwch ehangu ein gofod gwrthrych trwy newidyn:

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

Swyddogaethau ar gyfer dadansoddi llif

Defnyddir y swyddogaethau hyn mewn llawer o reolau a dyma ychydig o daflen twyllo o'r hyn y maent yn ei olygu:

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

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

Cael enw ffeil/llwybr

Mae yna nifer o briodweddau y gellir eu cael o ganlyniadau ymholiad (enw'r ffeil y daethpwyd o hyd i'r cofnod ynddi, llinyn, ac ati), ond nid yw'r ddogfennaeth yn dweud sut i'w cael a'u defnyddio. Felly, er mwyn gwneud hyn, mae angen i chi gael mynediad i'r eiddo LinePragma a bydd y gwrthrychau sydd eu hangen arnom wedi'u lleoli y tu mewn iddo:

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

Mae'n werth cadw hynny mewn cof FileName yn cynnwys y llwybr i'r ffeil mewn gwirionedd, ers i ni ddefnyddio'r dull GetFirstGraph.

Canlyniad gweithredu

Mae newidyn arbennig y tu mewn i CxQL result, sy'n dychwelyd canlyniad gweithredu eich rheol ysgrifenedig. Caiff ei gychwyn ar unwaith a gallwch ysgrifennu canlyniadau canolradd iddo, gan eu newid a'u mireinio wrth i chi weithio. Ond, os nad oes unrhyw aseiniad i'r newidyn neu'r swyddogaeth hon y tu mewn i'r rheol return— bydd y canlyniad dienyddio bob amser yn sero.

Ni fydd yr ymholiad canlynol yn dychwelyd unrhyw beth i ni o ganlyniad i gyflawni a bydd bob amser yn wag:

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

Ond, ar ôl neilltuo'r canlyniad gweithredu i'r canlyniad newidyn hud, byddwn yn gweld beth mae'r alwad hon yn ei dychwelyd atom:

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

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

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

Gan ddefnyddio canlyniadau rheolau eraill

Gellir galw rheolau yn Checkmarx yn cyfateb i swyddogaethau mewn iaith raglennu reolaidd. Wrth ysgrifennu rheol, mae'n bosibl iawn y byddwch yn defnyddio canlyniadau ymholiadau eraill. Er enghraifft, nid oes angen chwilio am yr holl alwadau dull yn y cod bob tro, ffoniwch y rheol a ddymunir:

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

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

Mae'r dull hwn yn caniatáu ichi fyrhau'r cod a lleihau'r amser gweithredu rheolau yn sylweddol.

Datrys problemau

Logio

Wrth weithio gyda'r offeryn, weithiau nid yw'n bosibl ysgrifennu'r ymholiad a ddymunir ar unwaith a rhaid i chi arbrofi, gan roi cynnig ar wahanol opsiynau. Ar gyfer achos o'r fath, mae'r offeryn yn darparu logio, a elwir fel a ganlyn:

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

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

Ond mae'n werth cofio bod y dull hwn yn derbyn fel mewnbwn yn unig llinell, felly ni fydd yn bosibl arddangos rhestr gyflawn o'r elfennau a ddarganfuwyd o ganlyniad i'r llawdriniaeth gyntaf. Yr ail opsiwn, a ddefnyddir ar gyfer dadfygio, yw aseinio i newidyn hud o bryd i'w gilydd result canlyniad yr ymholiad a gweld beth sy'n digwydd. Nid yw'r dull hwn yn gyfleus iawn; mae angen i chi fod yn siŵr nad oes unrhyw wrthwneud na gweithrediadau gyda hyn yn y cod ar ôl result neu rhowch sylwadau ar y cod isod. Neu gallwch chi, fel fi, anghofio dileu sawl galwad o'r fath o reol barod a meddwl tybed pam nad oes dim yn gweithio.

Ffordd fwy cyfleus yw galw'r dull return gyda'r paramedr gofynnol. Yn yr achos hwn, bydd gweithredu'r rheol yn dod i ben a byddwn yn gallu gweld beth ddigwyddodd o ganlyniad i'r hyn a ysgrifennwyd gennym:

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

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

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

Problem mewngofnodi

Mae sefyllfaoedd pan na allwch gael mynediad at yr offeryn CxAudit (a ddefnyddir i ysgrifennu rheolau). Gall fod llawer o resymau am hyn, gan gynnwys damweiniau, diweddariadau sydyn Windows, BSOD a sefyllfaoedd eraill nas rhagwelwyd sydd y tu hwnt i'n rheolaeth. Yn yr achos hwn, weithiau mae sesiwn anorffenedig yn y gronfa ddata, sy'n eich atal rhag mewngofnodi eto. Er mwyn ei drwsio, mae angen i chi redeg sawl ymholiad:

Ar gyfer Checkmarx cyn 8.6:

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

Ar gyfer Checkmarx ar ôl 8.6:

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

Ysgrifennu rheolau

Nawr rydyn ni'n cyrraedd y rhan fwyaf diddorol. Pan ddechreuwch ysgrifennu rheolau yn CxQL, nid yw'r hyn sydd yn aml yn ddiffygiol gennych yn gymaint o ddogfennaeth â rhai enghreifftiau byw o ddatrys problemau penodol a disgrifio'r broses o sut mae ymholiadau'n gweithio'n gyffredinol.

Byddaf yn ceisio gwneud bywyd ychydig yn haws i'r rhai sy'n dechrau plymio i iaith yr ymholiad a rhoi sawl enghraifft o ddefnyddio Custom Queries i ddatrys rhai problemau. Mae rhai ohonynt yn eithaf cyffredinol a gellir eu defnyddio yn eich cwmni yn ymarferol heb newidiadau, mae eraill yn fwy penodol, ond gellir eu defnyddio hefyd trwy newid y cod i weddu i fanylion eich cymwysiadau.

Felly, dyma'r problemau y daethom ar eu traws amlaf:

Tasg: Mae yna sawl Llif yng nghanlyniadau gweithredu'r rheol ac mae un ohonynt yn nythu un arall, rhaid i chi adael un ohonynt.

ateb: Yn wir, weithiau mae Checkmarx yn dangos sawl llif data a all orgyffwrdd a bod yn fersiwn fyrrach o rai eraill. Mae yna ddull arbennig ar gyfer achosion o'r fath Lleihau Llif. Yn dibynnu ar y paramedr, bydd yn dewis y Llif byrraf neu hiraf:

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

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

Tasg: Ehangwch y rhestr o ddata sensitif y mae'r offeryn yn ymateb iddo

ateb: Mae gan Checkmarx reolau sylfaenol, a defnyddir y canlyniadau gan lawer o ymholiadau eraill. Trwy ategu rhai o'r rheolau hyn â data sy'n benodol i'ch cais, gallwch wella canlyniadau eich sgan ar unwaith. Isod mae enghraifft o reol i'ch rhoi ar ben ffordd:

Rhestr_tros_preifatrwydd_cyffredinol

Gadewch i ni ychwanegu sawl newidyn a ddefnyddir yn ein cymhwysiad i storio gwybodaeth sensitif:

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

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

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

Tasg: Ehangwch y rhestr o newidynnau gyda chyfrineiriau

ateb: Byddwn yn argymell rhoi sylw ar unwaith i'r rheol sylfaenol ar gyfer diffinio cyfrineiriau mewn cod ac ychwanegu ato restr o enwau amrywiol a ddefnyddir yn gyffredin yn eich cwmni.

Cyfrinair_preifatrwydd_rhestr_groes

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

Tasg: Ychwanegu fframweithiau ail-law nad ydynt yn cael eu cefnogi gan Checkmarx

ateb: Mae pob ymholiad yn Checkmarx wedi'i rannu yn ôl iaith, felly mae angen i chi ychwanegu rheolau ar gyfer pob iaith. Isod mae rhai enghreifftiau o reolau o'r fath.

Os defnyddir llyfrgelloedd sy'n ategu neu'n disodli swyddogaethau safonol, gellir eu hychwanegu'n hawdd at y rheol sylfaenol. Yna bydd pawb sy'n ei ddefnyddio yn dysgu ar unwaith am y cyflwyniadau newydd. Er enghraifft, y llyfrgelloedd ar gyfer mewngofnodi Android yw Pren a Loggi. Yn y pecyn sylfaenol, nid oes unrhyw reolau ar gyfer adnabod galwadau nad ydynt yn rhai system, felly os yw cyfrinair neu ddynodwr sesiwn yn mynd i mewn i'r log, ni fyddwn yn gwybod amdano. Gadewch i ni geisio ychwanegu diffiniadau o ddulliau o'r fath at reolau Checkmarx.

Enghraifft cod prawf sy'n defnyddio'r llyfrgell Pren ar gyfer logio:

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

A dyma enghraifft o gais am Checkmarx, a fydd yn caniatáu ichi ychwanegu diffiniad o alw dulliau Pren fel man ymadael ar gyfer data o'r cais:

FindAndroidAllbynnau

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

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

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

A gallwch chi hefyd ychwanegu at y rheol gyfagos, ond mae'r un hon yn ymwneud yn uniongyrchol â mewngofnodi Android:

FindAndroidLog_Allbynnau

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

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

Hefyd, os yw ceisiadau Android yn defnyddio Rheolwr Gwaith ar gyfer gwaith asyncronaidd, mae'n syniad da rhoi gwybod i Checkmarx am hyn hefyd trwy ychwanegu dull o gael data o'r dasg getInputData:

FindAndroidRead

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

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

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

Tasg: Chwilio am ddata sensitif mewn plist ar gyfer prosiectau iOS

ateb: Mae iOS yn aml yn defnyddio ffeiliau arbennig gyda'r estyniad .plist i storio amrywiol newidynnau a gwerthoedd. Ni argymhellir storio cyfrineiriau, tocynnau, allweddi a data sensitif arall yn y ffeiliau hyn, oherwydd gellir eu tynnu o'r ddyfais heb unrhyw broblemau.

Mae gan ffeiliau plist nodweddion nad ydynt yn amlwg i'r llygad noeth, ond sy'n bwysig i Checkmarx. Gadewch i ni ysgrifennu rheol a fydd yn chwilio am y data sydd ei angen arnom a dweud wrthym a oes sôn am gyfrineiriau neu docynnau yn rhywle.

Enghraifft o ffeil o'r fath, sy'n cynnwys tocyn ar gyfer cyfathrebu â'r gwasanaeth 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>

A rheol ar gyfer Checkmarx, sydd â sawl naws y dylid eu hystyried wrth ysgrifennu:

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

Tasg: Dod o Hyd i Wybodaeth yn XML

ateb: Mae gan Checkmarx swyddogaethau cyfleus iawn ar gyfer gweithio gyda XML a chwilio am werthoedd, tagiau, priodoleddau a mwy. Ond, yn anffodus, bu gwall yn y ddogfennaeth ac nid yw un enghraifft yn gweithio oherwydd hynny. Er gwaethaf y ffaith bod y diffyg hwn wedi'i ddileu yn y fersiwn ddiweddaraf o'r ddogfennaeth, byddwch yn ofalus os ydych chi'n defnyddio fersiynau cynharach o ddogfennau.

Dyma enghraifft anghywir o'r ddogfennaeth:

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

O ganlyniad i'r ymgais i weithredu, byddwn yn derbyn gwall sy'n All nid oes dull o'r fath... Ac mae hyn yn wir, gan fod gofod gwrthrych arbennig, ar wahân ar gyfer defnyddio swyddogaethau ar gyfer gweithio gyda XML - cxXPath. Dyma sut olwg sydd ar yr ymholiad cywir i ddod o hyd i osodiad yn Android sy'n caniatáu defnyddio traffig HTTP:

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

Gadewch i ni edrych arno ychydig yn fwy manwl, gan fod y gystrawen ar gyfer pob swyddogaeth yn debyg, ar ôl i chi gyfrifo un, yna does ond angen i chi ddewis yr un sydd ei angen arnoch chi. Felly, yn ddilyniannol yn ôl y paramedrau:

  • "*.xml"- mwgwd o ffeiliau i'w chwilio

  • 8 — id yr iaith y cymhwysir y rheol ar ei chyfer

  • "cleartextTrafficPermitted"— enw priodoledd yn xml

  • "true" —gwerth y nodwedd hon

  • false — defnyddio mynegiant rheolaidd wrth chwilio

  • true - yn golygu y bydd y chwiliad yn cael ei wneud gan anwybyddu achos, hynny yw, achos-ansensitif

Er enghraifft, fe wnaethom ddefnyddio rheol sy'n nodi gosodiadau cysylltiad rhwydwaith anghywir, o safbwynt diogelwch, yn Android sy'n caniatáu cyfathrebu â'r gweinydd trwy'r protocol HTTP. Enghraifft o osodiad sy'n cynnwys priodoledd cleartextTrafficPermitted gydag ystyr 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>

Tasg: Cyfyngu canlyniadau yn ôl enw ffeil/llwybr

ateb: Yn un o'r prosiectau mawr sy'n ymwneud â datblygu cymhwysiad symudol ar gyfer Android, daethom ar draws pethau cadarnhaol ffug o'r rheol sy'n pennu'r gosodiad rhwystr. Y ffaith yw bod y rheol allan o'r blwch chwilio yn y ffeil build.gradle lleoliad sy'n gyfrifol am gymhwyso rheolau obfuscation ar gyfer fersiwn rhyddhau'r cais.

Ond mewn prosiectau mawr weithiau mae ffeiliau plentyn build.gradle, sy'n cyfeirio at y llyfrgelloedd sydd wedi'u cynnwys yn y prosiect. Yr hyn sy'n hynod yw, hyd yn oed os nad yw'r ffeiliau hyn yn nodi'r angen am ddrysu, bydd gosodiadau'r ffeil cydosod rhiant yn cael eu cymhwyso wrth eu llunio.

Felly, y dasg yw torri sbardunau mewn ffeiliau plant sy'n perthyn i lyfrgelloedd. Gellir eu hadnabod trwy bresenoldeb y llinell apply 'com.android.library'.

Cod enghreifftiol o'r ffeil build.gradle, sy'n pennu'r angen am rwystr:

apply plugin: 'com.android.application'

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

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

dependencies {
  ...
}

Ffeil enghreifftiol build.gradle ar gyfer llyfrgell sydd wedi'i chynnwys yn y prosiect nad oes ganddi'r gosodiad hwn:

apply plugin: 'android-library'

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

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

A'r rheol ar gyfer 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);
		}
	}
}

Gall y dull hwn fod yn eithaf cyffredinol a defnyddiol nid yn unig ar gyfer cymwysiadau Android, ond hefyd ar gyfer achosion eraill pan fydd angen i chi benderfynu a yw canlyniad yn perthyn i ffeil benodol.

Tasg: Ychwanegu cefnogaeth ar gyfer llyfrgell trydydd parti os na chefnogir y gystrawen yn llawn

ateb: Mae nifer y fframweithiau amrywiol a ddefnyddir yn y broses o ysgrifennu cod yn syml oddi ar y siartiau. Wrth gwrs, nid yw Checkmarx bob amser yn gwybod am eu bodolaeth, a'n tasg ni yw ei ddysgu i ddeall bod rhai dulliau yn perthyn yn benodol i'r fframwaith hwn. Weithiau caiff hyn ei gymhlethu gan y ffaith bod fframweithiau'n defnyddio enwau swyddogaethau sy'n gyffredin iawn ac mae'n amhosibl pennu'n ddiamwys berthynas galwad benodol â llyfrgell benodol.

Yr anhawster yw nad yw cystrawen llyfrgelloedd o'r fath bob amser yn cael ei gydnabod yn gywir ac mae'n rhaid i chi arbrofi i osgoi cael nifer fawr o bethau cadarnhaol ffug. Mae yna sawl opsiwn i wella cywirdeb sganio a datrys y broblem:

  • Yr opsiwn cyntaf, rydym yn gwybod yn sicr bod y llyfrgell yn cael ei ddefnyddio mewn prosiect penodol a gall gymhwyso'r rheol ar lefel tîm. Ond os yw'r tîm yn penderfynu cymryd agwedd wahanol neu'n defnyddio sawl llyfrgell lle mae enwau swyddogaethau'n gorgyffwrdd, gallwn gael darlun nad yw'n ddymunol iawn o nifer o bethau cadarnhaol ffug.

  • Yr ail opsiwn yw chwilio am ffeiliau lle mae'r llyfrgell yn amlwg wedi'i fewnforio. Gyda'r dull hwn, gallwn fod yn siŵr bod y llyfrgell sydd ei hangen arnom yn cael ei defnyddio'n union yn y ffeil hon.

  • A'r trydydd opsiwn yw defnyddio'r ddau ddull uchod gyda'i gilydd.

Fel enghraifft, gadewch i ni edrych ar lyfrgell adnabyddus mewn cylchoedd cul slic ar gyfer iaith raglennu Scala, sef y swyddogaeth Splicing Gwerthoedd Llythrennol. Yn gyffredinol, i drosglwyddo paramedrau i ymholiad SQL, rhaid i chi ddefnyddio'r gweithredwr $, sy'n amnewid data i ymholiad SQL a ffurfiwyd ymlaen llaw. Hynny yw, mewn gwirionedd, mae'n analog uniongyrchol o Ddatganiad Parod yn Java. Ond, os oes angen i chi lunio ymholiad SQL yn ddeinamig, er enghraifft, os oes angen i chi basio enwau tablau, gallwch ddefnyddio'r gweithredwr #$, a fydd yn amnewid y data yn uniongyrchol i'r ymholiad (bron fel cydgateniad llinynnol).

Enghraifft o god:

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

Nid yw Checkmarx yn gwybod eto sut i ganfod y defnydd o Splicing Literal Values ​​a gweithredwyr sgipiau #$, felly gadewch i ni geisio ei ddysgu i nodi pigiadau SQL posibl ac amlygu'r lleoedd cywir yn y cod:

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

Tasg: Chwiliwch am swyddogaethau bregus a ddefnyddir mewn llyfrgelloedd Ffynhonnell Agored

ateb: Mae llawer o gwmnïau'n defnyddio offer monitro Ffynhonnell Agored (arfer OSA) i ganfod y defnydd o fersiynau bregus o lyfrgelloedd mewn cymwysiadau datblygedig. Weithiau nid yw'n bosibl diweddaru llyfrgell o'r fath i fersiwn ddiogel. Mewn rhai achosion mae cyfyngiadau swyddogaethol, mewn eraill nid oes fersiwn ddiogel o gwbl. Yn yr achos hwn, bydd cyfuniad o arferion SAST ac OSA yn helpu i benderfynu nad yw'r swyddogaethau sy'n arwain at ymelwa ar y bregusrwydd yn cael eu defnyddio yn y cod.

Ond weithiau, yn enwedig wrth ystyried JavaScript, efallai na fydd hon yn dasg gwbl ddibwys. Isod mae ateb, efallai nad yw'n ddelfrydol, ond serch hynny yn gweithio, gan ddefnyddio'r enghraifft o wendidau yn y gydran lodash mewn dulliau template и *set.

Enghreifftiau o god a allai fod yn agored i niwed prawf mewn ffeil 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!'

Ac wrth gysylltu yn uniongyrchol yn 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>

Rydym yn chwilio am ein holl ddulliau bregus, a restrir yn gwendidau:

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

Tasg: Chwilio am dystysgrifau sydd wedi'u hymgorffori yn y rhaglen

ateb: Nid yw'n anghyffredin i gymwysiadau, yn enwedig rhai symudol, ddefnyddio tystysgrifau neu allweddi i gael mynediad at weinyddion amrywiol neu wirio SSL-Pinning. O safbwynt diogelwch, nid storio pethau o'r fath mewn cod yw'r arfer gorau. Gadewch i ni geisio ysgrifennu rheol a fydd yn chwilio am ffeiliau tebyg yn y gadwrfa:

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

Tasg: Dod o hyd i docynnau cyfaddawdu yn y cais

ateb: Yn aml mae angen dirymu tocynnau cyfaddawd neu wybodaeth bwysig arall sy'n bresennol yn y cod. Wrth gwrs, nid yw eu storio y tu mewn i'r cod ffynhonnell yn syniad da, ond mae sefyllfaoedd yn amrywio. Diolch i ymholiadau CxQL, mae dod o hyd i bethau fel hyn yn eithaf hawdd:

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

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

Casgliad

Rwy'n gobeithio y bydd yr erthygl hon yn ddefnyddiol i'r rhai sy'n dechrau eu hadnabod gyda'r offeryn Checkmarx. Efallai y bydd y rhai sydd wedi bod yn ysgrifennu eu rheolau eu hunain ers amser maith hefyd yn gweld rhywbeth defnyddiol yn y canllaw hwn.

Yn anffodus, mae diffyg adnodd ar hyn o bryd lle gellid cael syniadau newydd wrth ddatblygu rheolau ar gyfer Checkmarx. Dyna pam wnaethon ni greu ystorfa ar Github, lle byddwn yn postio ein gwaith fel bod pawb sy’n defnyddio CxQL yn gallu dod o hyd i rywbeth defnyddiol ynddo, a hefyd yn cael y cyfle i rannu eu gwaith gyda’r gymuned. Mae'r ystorfa yn y broses o lenwi a strwythuro cynnwys, felly mae croeso i gyfranwyr!

Diolch am eich sylw!

Ffynhonnell: hab.com

Ychwanegu sylw