Pehea e kākau ai i nā lula no Checkmarx me ka ʻole o ka pupule

E Habr!

I kā mākou hana, pili pinepine kā mākou hui i nā mea hana loiloi code static (SAST). Ma waho o ka pahu hana lākou a pau i ka awelika. ʻOiaʻiʻo, pili ia i ka papahana a me nā ʻenehana i hoʻohana ʻia i loko, a me ka maikaʻi o kēia mau ʻenehana i uhi ʻia e nā lula o ka nānā ʻana. I koʻu manaʻo, ʻo kekahi o nā koʻikoʻi koʻikoʻi i ke koho ʻana i kahi hāmeʻa SAST ʻo ia ka hiki ke hoʻopilikino iā ia i nā kikoʻī o kāu mau noi, ʻo ia hoʻi, kākau a hoʻololi i nā lula loiloi a i ʻole, e like me ka mea i kapa pinepine ʻia, Custom Queries.

Pehea e kākau ai i nā lula no Checkmarx me ka ʻole o ka pupule

Hoʻohana pinepine mākou iā Checkmarx - he mea hōʻike helu helu hoihoi a ikaika. Ma kēia ʻatikala e kamaʻilio wau e pili ana i koʻu ʻike i ke kākau ʻana i nā lula loiloi no ia.

Ka papa o nā mea

komo

I ka hoʻomaka ʻana, makemake wau e paipai i kekahi o nā ʻatikala liʻiliʻi ma Lūkini e pili ana i nā hiʻohiʻona o ke kākau ʻana i nā nīnau no Checkmarx. Ua paʻi ʻia ma Habré i ka hopena o 2019 ma lalo o ke poʻo inoa: "Aloha, Checkmarx!" Pehea e kākau ai i kahi nīnau Checkmarx SAST a loaʻa i nā mea palupalu.

Nānā i nā kikoʻī pehea e kākau ai i nā nīnau mua ma CxQL (Checkmarx Query Language) no kekahi noi hoʻāʻo a hōʻike i nā kumu kumu o ka hana ʻana o nā lula loiloi.

ʻAʻole au e hana hou i ka mea i wehewehe ʻia i loko, ʻoiai e mau ana kekahi mau kuʻuna. Ma kaʻu ʻatikala e hoʻāʻo wau e hōʻuluʻulu i kahi ʻano "hōʻiliʻili ʻana i nā mea ʻono", kahi papa inoa o nā hoʻonā i nā pilikia kūikawā aʻu i hālāwai ai i kaʻu hana me Checkmarx. Pono wau e hoʻopaʻa i koʻu lolo no ka nui o kēia mau pilikia. I kekahi manawa ʻaʻole lawa ka ʻike i loko o ka palapala, a i kekahi manawa he paʻakikī ke hoʻomaopopo pehea e hana ai i ka mea e pono ai. Manaʻo wau ʻaʻole e makehewa koʻu ʻike a me nā pō hiamoe ʻole, a ʻo kēia "hui o nā ʻōlelo aʻoaʻo Custom Queries" e hoʻopakele iā ʻoe i kekahi mau hola a i ʻole nā ​​​​pūnaewele nerve. No laila, e hoʻomaka kākou!

ʻIke nui e pili ana i nā lula

ʻO ka mua, e nānā kākou i kekahi mau manaʻo kumu a me ke kaʻina hana me nā lula, no ka hoʻomaopopo maikaʻi ʻana i nā mea e hiki mai ana. A no ka mea ʻaʻole ʻōlelo ka palapala i kekahi mea e pili ana i kēia a i hoʻolaha nui ʻia i loko o ka hale, ʻaʻole kūpono loa.

  1. Hoʻohana ʻia nā lula ma ka nānā ʻana ma muli o ka preset i koho ʻia ma ka hoʻomaka (kahi o nā lula hana). Hiki iā ʻoe ke hana i kahi helu palena ʻole o nā preset, a pehea e hoʻonohonoho ai iā lākou e pili ana i nā kikoʻī o kāu kaʻina hana. Hiki iā ʻoe ke hui iā lākou ma ka ʻōlelo a i ʻole koho i nā preset no kēlā me kēia papahana. Hoʻopili ka helu o nā lula hana i ka wikiwiki a me ka pololei o ka nānā ʻana.

    Pehea e kākau ai i nā lula no Checkmarx me ka ʻole o ka pupuleKa hoʻonohonoho ʻana i ka Preset ma ke kikowaena Checkmarx

  2. Hoʻoponopono ʻia nā lula ma kahi mea hana kūikawā i kapa ʻia ʻo CxAuditor. He polokalamu papapihi kēia e pili ana i kahi kikowaena e holo ana iā Checkmarx. ʻElua mau ʻano hana o kēia mea hana: hoʻoponopono i nā lula a me ka nānā ʻana i nā hopena o kahi scan i hana mua ʻia.

    Pehea e kākau ai i nā lula no Checkmarx me ka ʻole o ka pupuleCxAudit interface

  3. Hoʻokaʻawale ʻia nā lula ma Checkmarx e ka ʻōlelo, ʻo ia hoʻi, aia kēlā me kēia ʻōlelo i kāna mau nīnau ponoʻī. Aia kekahi mau lula maʻamau e pili ana me ka ʻole o ka ʻōlelo, ʻo ia ka mea i kapa ʻia nā nīnau kumu. No ka hapa nui, pili nā nīnau maʻamau i ka ʻimi ʻana i ka ʻike e hoʻohana ai nā lula ʻē aʻe.

    Pehea e kākau ai i nā lula no Checkmarx me ka ʻole o ka pupuleKa mahele ana i na rula ma ka olelo

  4. ʻO nā lula he "Hoʻokō" a me "Non-Executable" (Hoʻokō a ʻAʻole Hoʻokō ʻia). ʻAʻole pololei ka inoa, i koʻu manaʻo, akā ʻo ia ka mea. ʻO ka laina lalo, ʻo ka hopena o ka hoʻokō ʻana i nā lula "Executable" e hōʻike ʻia i nā hopena scan i ka UI, a pono nā lula "Non-Executable" e hoʻohana i kā lākou hopena i nā noi ʻē aʻe (ma ke ʻano, he hana wale nō).

    Pehea e kākau ai i nā lula no Checkmarx me ka ʻole o ka pupuleHoʻoholo i ke ʻano lula i ka wā e hana ai

  5. Hiki iā ʻoe ke hana i nā lula hou a i ʻole hoʻohui/kākau hou i nā lula i loaʻa. No ke kākau hou ʻana i kahi lula, pono ʻoe e ʻimi iā ia ma ka lāʻau, kaomi ʻākau a koho i ka "Override" mai ka papa kuhikuhi. He mea nui e hoʻomanaʻo ma aneʻi ʻaʻole i hoʻokomo mua ʻia nā lula hou i nā preset a ʻaʻole ikaika. No ka hoʻomaka ʻana e hoʻohana iā lākou pono ʻoe e hoʻāla iā lākou i ka papa kuhikuhi "Preset Manager" i ka mea kani. Hoʻopaʻa ʻia nā lula i kākau hou ʻia i ko lākou mau hoʻonohonoho, ʻo ia hoʻi, inā ʻeleʻele ka lula, e mau nō ia a e hoʻohana koke ʻia.

    Pehea e kākau ai i nā lula no Checkmarx me ka ʻole o ka pupuleKa laʻana o kahi lula hou ma ka Preset Manager interface

  6. I ka wā o ka hoʻokō ʻana, kūkulu ʻia kahi "lāʻau" o nā noi, e pili ana i ka mea. Hoʻokō mua ʻia nā lula e hōʻiliʻili i ka ʻike, a ʻo ka poʻe e hoʻohana ana i ka lua. Hoʻopili ʻia ka hopena hoʻokō, no laila inā hiki ke hoʻohana i nā hopena o kahi lula e kū nei, a laila ʻoi aku ka maikaʻi o ka hana ʻana, e hōʻemi kēia i ka manawa scanning.

  7. Hiki ke hoʻohana i nā lula ma nā pae like ʻole:

  • No ka ʻōnaehana holoʻokoʻa - e hoʻohana ʻia no ka nānā ʻana i kekahi papahana

  • Ma ka pae kime (Team) - e hoʻohana wale ʻia e nānā i nā papahana ma ka hui i koho ʻia.

  • Ma ka papahana papahana - E hoʻohanaʻia i kahi papahana kūikawā

    Pehea e kākau ai i nā lula no Checkmarx me ka ʻole o ka pupuleE hoʻoholo ana i ka pae e hoʻohana ʻia ai ka lula

ʻO ka "Dictionary" no ka poʻe hoʻomaka

A e hoʻomaka wau me kekahi mau mea i nīnau iaʻu, a e hōʻike pū wau i kekahi mau ʻenehana e hoʻomaʻamaʻa nui i ke ola.

Nā hana me nā papa inoa

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

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

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

Loaʻa nā mea a pau

I loko o ka ʻōlelo scanned, hiki iā ʻoe ke kiʻi i kahi papa inoa o nā mea āpau a Checkmarx i ʻike ai (nā kaula, nā hana, nā papa, nā ʻano, a me nā mea ʻē aʻe). ʻO kēia kekahi wahi o nā mea i hiki ke komo ma o All. ʻO ia hoʻi, e ʻimi i kahi mea me kahi inoa kikoʻī searchMe, hiki iā ʻoe ke ʻimi, no ka laʻana, ma ka inoa ma nā mea āpau i loaʻa:

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

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

Akā, inā pono ʻoe e ʻimi i ka ʻōlelo ʻē aʻe no kekahi kumu ʻaʻole i hoʻokomo ʻia i ka scan (no ka laʻana, groovy i kahi papahana Android), hiki iā ʻoe ke hoʻonui i kā mākou wahi kikoʻī ma o kahi loli:

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

Nā hana no ka nānā ʻana i ke kahe

Hoʻohana ʻia kēia mau hana i nā lula he nui a eia kahi palapala hoʻopunipuni liʻiliʻi o kā lākou manaʻo:

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

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

Loaʻa i ka inoa file / ala

Nui nā hiʻohiʻona i hiki ke loaʻa mai nā hopena o kahi nīnau (ka inoa o ka faila i loaʻa ai ke komo ʻana, string, etc.), akā ʻaʻole ʻōlelo ka palapala pehea e loaʻa ai a hoʻohana. No laila, i mea e hana ai i kēia, pono ʻoe e komo i ka waiwai LinePragma a ʻo nā mea a mākou e pono ai e loaʻa i loko.

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

Pono e hoʻomanaʻo i kēlā FileName loaʻa maoli ke ala i ka faila, ʻoiai ua hoʻohana mākou i ke ʻano GetFirstGraph.

Ka hopena hoʻokō

Aia kahi hoʻololi kūikawā i loko o CxQL result, e hoʻihoʻi i ka hopena o ka hoʻokō ʻana i kāu lula kākau. Hoʻomaka koke ʻia a hiki iā ʻoe ke kākau i nā hopena waena i loko, hoʻololi a hoʻomaʻemaʻe iā lākou i kāu hana. Akā, inā ʻaʻohe hāʻawi i kēia hoʻololi a i ʻole hana i loko o ka lula return- ʻaʻole mau ka hopena hoʻokō.

ʻAʻole e hoʻihoʻi mai kēia nīnau i kekahi mea iā mākou ma muli o ka hoʻokō ʻana a nele mau:

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

Akā, i ka hāʻawi ʻana i ka hopena hoʻokō i ka hopena hoʻololi kilokilo, e ʻike mākou i ke ʻano o kēia kelepona iā mākou:

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

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

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

Ke hoʻohana nei i nā hopena o nā lula ʻē aʻe

Hiki ke kapa ʻia nā lula ma Checkmarx e like me nā hana ma ka ʻōlelo papahana maʻamau. Ke kākau nei i lula, hiki iā ʻoe ke hoʻohana i nā hopena o nā nīnau ʻē aʻe. No ka laʻana, ʻaʻohe pono e ʻimi i nā kelepona ʻano āpau i ke code i kēlā me kēia manawa, e kāhea wale i ke kānāwai i makemake ʻia:

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

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

Hiki i kēia ala ke hoʻopōkole i ke code a hoʻemi nui i ka manawa hoʻokō kānāwai.

ʻO ka hopena o nā pilikia

Ke kālai lāʻau

I ka hanaʻana me ka mea hana, i kekahi manawaʻaʻole hiki ke kākau koke i ka nīnau i makemakeʻia a ponoʻoe e ho'āʻo, e ho'āʻo i nā koho likeʻole. No kēlā hihia, hāʻawi ka mea hana i ka logging, i kapa ʻia penei:

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

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

Akā, pono e hoʻomanaʻo ʻia e ʻae wale ʻia kēia ʻano ma ke ʻano he komo kaula, no laila ʻaʻole hiki ke hōʻike i kahi papa inoa piha o nā mea i loaʻa ma muli o ka hana mua. ʻO ka lua o ka koho, i hoʻohana ʻia no ka debugging, ʻo ia ka hāʻawi ʻana i kahi hoʻololi kilokilo i kēlā me kēia manawa result ka hopena o ka nīnau a ʻike i ka hopena. ʻAʻole maʻalahi kēia ala; pono ʻoe e hōʻoia ʻaʻohe overrides a i ʻole nā ​​​​hana me kēia ma ke code ma hope. result a i ʻole e ʻōlelo wale i ke code ma lalo nei. A i ʻole hiki iā ʻoe, e like me aʻu, poina e wehe i nā kelepona like ʻole mai kahi lula i mākaukau a noʻonoʻo no ke aha ʻaʻohe mea e hana.

ʻO kahi ala maʻalahi ke kāhea ʻana i ke ʻano return me ka palena i makemakeia. I kēia hihia, e pau ka hoʻokō ʻana i ka lula a hiki iā mākou ke ʻike i ka mea i hana ʻia ma muli o nā mea a mākou i kākau ai:

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

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

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

Pilikia komo

Aia nā kūlana i hiki ʻole iā ʻoe ke komo i ka mea hana CxAudit (i hoʻohana ʻia e kākau i nā lula). Nui nā kumu no kēia, e like me nā ulia, nā hōʻano hou o Windows, BSOD a me nā kūlana ʻike ʻole ʻē aʻe ma waho o kā mākou mana. I kēia hihia, i kekahi manawa aia kahi hālāwai i hoʻopau ʻole ʻia i ka waihona, kahi e pale ai iā ʻoe mai ke komo hou ʻana. No ka hoʻoponopono ʻana, pono ʻoe e holo i kekahi mau nīnau:

No Checkmarx ma mua o 8.6:

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

No Checkmarx ma hope o 8.6:

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

Nā kānāwai kākau

I kēia manawa hiki mākou i ka ʻāpana hoihoi loa. Ke hoʻomaka ʻoe e kākau i nā lula ma CxQL, ʻo ka mea āu e nele pinepine ai, ʻaʻole ia ka nui o nā palapala e like me kekahi mau hiʻohiʻona ola o ka hoʻoponopono ʻana i kekahi mau pilikia a me ka wehewehe ʻana i ke kaʻina o ka hana ʻana o nā nīnau ma ka laulā.

E ho'āʻo wau e hoʻomāmā iki i ke ola no ka poʻe e hoʻomaka ana e luʻu i ka ʻōlelo nīnau a hāʻawi i kekahi mau laʻana o ka hoʻohana ʻana i nā nīnau pilikino e hoʻoponopono i kekahi mau pilikia. ʻO kekahi o lākou he maʻamau a hiki ke hoʻohana ʻia i kāu ʻoihana me ka ʻole o nā loli, ʻoi aku ka kikoʻī o nā mea ʻē aʻe, akā hiki ke hoʻohana ʻia ma ka hoʻololi ʻana i ke code e kūpono i nā kikoʻī o kāu mau noi.

No laila, eia nā pilikia a mākou i hālāwai pinepine ai:

He hana: Nui nā kahe i nā hopena o ka hoʻokō ʻana i ka lula a ʻo kekahi o lākou he nesting o kekahi, pono ʻoe e haʻalele i kekahi o lākou.

pāʻoihana: ʻOiaʻiʻo, i kekahi manawa hōʻike ʻo Checkmarx i kekahi mau kahe ʻikepili i uhi ʻia a he mana pōkole o nā mea ʻē aʻe. Aia kekahi ala kūikawā no ia mau hihia ReduceFlow. Ma muli o ka palena, e koho ʻo ia i ka Flow pōkole a lōʻihi loa:

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

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

He hana: E hoʻonui i ka papa inoa o nā ʻikepili koʻikoʻi kahi e hana ai ka mea hana

pāʻoihana: Loaʻa iā Checkmarx nā lula maʻamau, nā hopena i hoʻohana ʻia e nā nīnau ʻē aʻe he nui. Ma ka hoʻohui ʻana i kekahi o kēia mau lula me ka ʻikepili kikoʻī i kāu noi, hiki iā ʻoe ke hoʻomaikaʻi koke i kāu mau hopena scan. Aia ma lalo kahi laʻana lula e hoʻomaka ai:

General_privacy_violation_list

E hoʻohui i kekahi mau ʻano hoʻololi i hoʻohana ʻia i kā mākou noi no ka mālama ʻana i ka ʻike koʻikoʻi:

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

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

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

He hana: E hoʻonui i ka papa inoa o nā mea hoʻololi me nā ʻōlelo huna

pāʻoihana: Manaʻo wau e hoʻolohe koke i ke kānāwai kumu no ka wehewehe ʻana i nā ʻōlelo huna ma ke code a hoʻohui i ia i kahi papa inoa o nā inoa hoʻololi i hoʻohana mau ʻia i kāu hui.

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

He hana: Hoʻohui i nā hoʻohana i kākoʻo ʻole ʻia e Checkmarx

pāʻoihana: Ua māhele ʻia nā nīnau a pau ma Checkmarx e ka ʻōlelo, no laila pono ʻoe e hoʻohui i nā lula no kēlā me kēia ʻōlelo. Aia ma lalo iho kekahi mau laʻana o ia mau lula.

Inā hoʻohana ʻia nā hale waihona puke e hoʻokō a hoʻololi paha i ka hana maʻamau, hiki ke hoʻohui maʻalahi iā lākou i ke kānāwai kumu. A laila e aʻo koke nā mea hoʻohana e pili ana i nā hoʻolauna hou. ʻO kahi laʻana, ʻo nā hale waihona puke no ka hoʻopaʻa inoa ʻana i ka Android ʻo Timber a me Loggi. I loko o ka pūʻolo maʻamau, ʻaʻohe kānāwai no ka ʻike ʻana i nā kelepona ʻole ʻōnaehana, no laila inā komo ka ʻōlelo huna a i ʻole ka ʻike manawa i ka log, ʻaʻole mākou e ʻike e pili ana. E ho'āʻo kākou e hoʻohui i nā wehewehe o ia ʻano hana i nā lula Checkmarx.

Hoʻāʻo code code e hoʻohana ana i ka waihona Timber no ka hoʻopaʻa inoa ʻana:

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 eia kahi hiʻohiʻona o kahi noi no Checkmarx, e ʻae iā ʻoe e hoʻohui i kahi wehewehe o ke kāhea ʻana i nā ala Timber ma ke ʻano he puka puka no ka ʻikepili mai ka noi.

E huli i AndroidOutputs

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

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

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

A hiki iā ʻoe ke hoʻohui i ka lula pili, akā pili pololei kēia i ka hoʻopaʻa ʻana i ka Android:

E huli i AndroidLog_Outputs

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

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

Eia kekahi, inā hoʻohana nā polokalamu Android Luna Hana no ka hana asynchronous, he mea maikaʻi e hoʻomaopopo hou iā Checkmarx e pili ana i kēia ma ka hoʻohui ʻana i kahi ala no ka loaʻa ʻana o ka ʻikepili mai ka hana. getInputData:

FindAndroidRead

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

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

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

He hana: Ke ʻimi nei i ka ʻikepili koʻikoʻi ma ka plist no nā papahana iOS

pāʻoihana: Hoʻohana pinepine ʻo iOS i nā faila kūikawā me ka hoʻonui .plist e mālama i nā ʻano like ʻole a me nā waiwai. ʻAʻole ʻōlelo ʻia ka mālama ʻana i nā huaʻōlelo, nā hōʻailona, ​​​​nā kī a me nā ʻikepili koʻikoʻi ʻē aʻe i kēia mau faila, no ka mea hiki ke unuhi ʻia mai ka hāmeʻa me ka pilikia ʻole.

Loaʻa i nā faila Plist nā hiʻohiʻona i ʻike ʻole ʻia e ka maka ʻōlohelohe, akā he mea nui iā Checkmarx. E kākau kākou i kānāwai e ʻimi ai i ka ʻikepili a mākou e pono ai a e haʻi mai inā ʻōlelo ʻia nā huaʻōlelo a i ʻole nā ​​hōʻailona ma kahi.

He laʻana o ia faila, aia kahi hōʻailona no ke kamaʻilio ʻana me ka lawelawe hope:

<?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 he lula no Checkmarx, he nui nā nuances e pono e noʻonoʻo ʻia i ke kākau ʻana:

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

He hana: Ke ʻimi nei i ka ʻike ma XML

pāʻoihana: Loaʻa iā Checkmarx nā hana maʻalahi no ka hana ʻana me XML a me ka ʻimi ʻana i nā waiwai, nā hōʻailona, ​​​​nā ʻano a me nā mea hou aku. Akā, ʻo ka mea pōʻino, aia kahi hewa i ka palapala ma muli o ka hana ʻole o kahi hiʻohiʻona hoʻokahi. ʻOiai ua hoʻopau ʻia kēia hemahema i ka mana hou loa o ka palapala, e makaʻala inā ʻoe e hoʻohana i nā mana mua o nā palapala.

Eia kekahi laʻana hewa ʻole mai ka palapala.

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

Ma muli o ka ho'āʻo hoʻokō, e loaʻa iā mākou kahi hewa i kēlā All ʻaʻohe ʻano hana like ... A he ʻoiaʻiʻo kēia, no ka mea, aia kahi kikoʻī kūikawā, kahi kaʻawale no ka hoʻohana ʻana i nā hana no ka hana ʻana me XML - cxXPath. ʻO kēia ke ʻano o ka nīnau kūpono e ʻike ai i kahi hoʻonohonoho ma Android e ʻae ai i ka hoʻohana ʻana o HTTP traffic:

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

E nānā hou aku kākou iā ia, no ka mea, ua like ka syntax no nā hana a pau, ma hope o kou ʻike ʻana i kekahi, a laila pono ʻoe e koho i ka mea āu e pono ai. No laila, e like me nā ʻāpana:

  • "*.xml"- mask o nā faila e ʻimi ʻia

  • 8 - id o ka ʻōlelo i hoʻohana ʻia ai ke kānāwai

  • "cleartextTrafficPermitted"- inoa inoa ma xml

  • "true" — ka waiwai o keia ano

  • false - ka hoʻohana ʻana i ka ʻōlelo maʻamau i ka wā e ʻimi ai

  • true - 'o ia ho'i, e hana 'ia ka huli me ka nānā 'ole i ka hihia, 'o ia ho'i, 'a'ohe hihia

Ma keʻano he laʻana, ua hoʻohana mākou i kahi lula e hōʻike ana i ka hewa, mai kahi ʻike palekana, nā hoʻonohonoho pili pūnaewele ma Android e ʻae i ke kamaʻilio me ke kikowaena ma o ka protocol HTTP. Laʻana o kahi hoʻonohonoho i loaʻa kahi ʻano cleartextTrafficPermitted me ke ano 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>

He hana: E kaupalena i nā hualoaʻa ma ka inoa faila/ala

pāʻoihana: Ma kekahi o nā papahana nui e pili ana i ka hoʻomohala ʻana i kahi polokalamu kelepona no Android, ua hālāwai mākou i nā hopena maikaʻi ʻole o ke kānāwai e hoʻoholo ai i ka hoʻonohonoho obfuscation. ʻO ka ʻoiaʻiʻo, ʻo ka lula ma waho o ka pahu e ʻimi i ka faila build.gradle kahi hoʻonohonoho kuleana no ka hoʻopili ʻana i nā lula obfuscation no ka mana hoʻokuʻu o ka noi.

Akā i nā papahana nui i kekahi manawa aia nā faila keiki build.gradle, e pili ana i nā hale waihona puke i loko o ka papahana. ʻO ka mea ʻokoʻa ʻoiai inā ʻaʻole hōʻike kēia mau faila i ka pono o ka obfuscation, e hoʻopili ʻia nā hoʻonohonoho o ka faila hui makua i ka wā o ka hōʻuluʻulu ʻana.

No laila, ʻo ka hana ka ʻoki ʻana i nā mea hoʻoiho i nā faila keiki no nā hale waihona puke. Hiki ke ʻike ʻia lākou ma ke alo o ka laina apply 'com.android.library'.

Laʻana code mai ka faila build.gradle, ka mea e hoʻoholo ai i ka pono o ka obfuscation:

apply plugin: 'com.android.application'

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

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

dependencies {
  ...
}

Laʻana waihona build.gradle no kahi waihona i hoʻokomo ʻia i loko o ka pāhana i loaʻa ʻole kēia hoʻonohonoho:

apply plugin: 'android-library'

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

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

A ʻo ke kānāwai no 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);
		}
	}
}

Hiki i kēia ala ke lilo i ke ao holoʻokoʻa a pono ʻaʻole wale no nā noi Android, akā no nā hihia ʻē aʻe inā pono ʻoe e hoʻoholo inā pili ka hopena i kahi faila kikoʻī.

He hana: Hoʻohui i ke kākoʻo no kahi waihona ʻaoʻao ʻekolu inā ʻaʻole kākoʻo piha ʻia ka syntax

pāʻoihana: ʻO ka helu o nā ʻano hana like ʻole i hoʻohana ʻia i ke kaʻina o ke kākau ʻana i nā code ma waho o nā pakuhi. ʻOiaʻiʻo, ʻaʻole ʻike mau ʻo Checkmarx i ko lākou ola ʻana, a ʻo kā mākou hana ʻo ke aʻo ʻana iā ia e hoʻomaopopo i kekahi mau ʻano pili i kēia ʻano. I kekahi manawa paʻakikī kēia i ka hoʻohana ʻana o nā frameworks i nā inoa hana maʻamau a hiki ʻole ke hoʻoholo pono ʻole i ka pilina o kahi kelepona i kahi waihona kikoʻī.

ʻO ka paʻakikī, ʻaʻole ʻike mau ʻia ka syntax o ia mau hale waihona puke a pono ʻoe e hoʻāʻo e pale i ka loaʻa ʻana o ka nui o nā hopena hoʻopunipuni. Nui nā koho e hoʻomaikaʻi ai i ka pololei scanning a hoʻoponopono i ka pilikia:

  • ʻO ka koho mua, ʻike maopopo mākou ua hoʻohana ʻia ka waihona i kahi papahana kikoʻī a hiki ke hoʻohana i ka lula ma ka pae kime. Akā inā hoʻoholo ka hui e hana i kahi ala ʻē aʻe a hoʻohana paha i kekahi mau hale waihona puke kahi i uhi ʻia ai nā inoa hana, hiki iā mākou ke kiʻi i kahi kiʻi ʻoluʻolu ʻole o nā hopena maikaʻi ʻole.

  • ʻO ka koho ʻelua ʻo ka ʻimi ʻana i nā faila kahi i lawe ʻia mai ai ka waihona. Me kēia ala, hiki iā mākou ke maopopo ua hoʻohana pono ʻia ka waihona a mākou e pono ai i kēia faila.

  • A ʻo ke kolu o ka koho, ʻo ia ka hoʻohana pū ʻana i nā ala ʻelua ma luna.

No ka laʻana, e nānā kākou i kahi hale waihona puke kaulana i nā pōʻai haiki lohi no ka ʻōlelo hoʻolālā Scala, ʻo ia hoʻi, ka hana Hoʻopili ʻana i nā Waiwai ʻŌlelo. Ma keʻano laulā, e hāʻawi i nā ʻāpana i kahi nīnau SQL, pono ʻoe e hoʻohana i ka mea hoʻohana $, ka mea e hoʻololi i ka ʻikepili i kahi hulina SQL i hana mua ʻia. ʻO ia, ʻoiaʻiʻo, he analogue pololei ia o ka Prepared Statement ma Java. Akā, inā pono ʻoe e kūkulu ikaika i kahi nīnau SQL, no ka laʻana, inā pono ʻoe e kau i nā inoa papa, hiki iā ʻoe ke hoʻohana i ka mea hoʻohana. #$, e hoʻololi pololei i ka ʻikepili i loko o ka nīnau (kokoke e like me ka concatenation string).

Laʻana code:

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

ʻAʻole ʻike ʻo Checkmarx i ka ʻike ʻana i ka hoʻohana ʻana o Splicing Literal Values ​​a skips operators #$, no laila e ho'āʻo kāua e aʻo iā ia e ʻike i nā hoʻokele SQL hiki ke hōʻike i nā wahi kūpono i ke code:

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

He hana: E ʻimi i nā hana nawaliwali i hoʻohana ʻia ma nā hale waihona puke Open-Source

pāʻoihana: Nui nā hui e hoʻohana ana i nā hāmeʻa nānā Open-Source (OSA practice) no ka ʻike ʻana i ka hoʻohana ʻana i nā ʻano haʻahaʻa o nā hale waihona puke i nā noi i kūkulu ʻia. I kekahi manawa ʻaʻole hiki ke hoʻololi i kēlā waihona i kahi mana palekana. I kekahi mau hihia aia nā palena hana, ma nā mea ʻē aʻe, ʻaʻohe mana palekana. I kēia hihia, ʻo ka hui pū ʻana o nā hana SAST a me OSA e kōkua i ka hoʻoholo ʻana ʻaʻole i hoʻohana ʻia nā hana e alakaʻi ai i ka hoʻohana ʻana i ka nāwaliwali i ke code.

Akā i kekahi manawa, ʻoi aku ka nui o ka noʻonoʻo ʻana iā JavaScript, ʻaʻole paha he hana koʻikoʻi kēia. Aia ma lalo kahi hopena, ʻaʻole paha i kūpono, akā naʻe e hana ana, me ka hoʻohana ʻana i ka laʻana o nā nāwaliwali o ka ʻāpana. lodash ma nā ʻano hana template и *set.

Nā hiʻohiʻona o ka hoʻāʻo ʻana i nā code hiki ke pilikia ma kahi faila 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!'

A i ka hoʻopili pololei ʻana i ka 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>

Ke ʻimi nei mākou i kā mākou mau ʻano pilikia āpau, i helu ʻia i loko o nā nāwaliwali:

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

He hana: Ke ʻimi nei i nā palapala hōʻoia i hoʻokomo ʻia i loko o ka noi

pāʻoihana: ʻAʻole ia he mea maʻamau no nā noi, ʻoi aku hoʻi i nā kelepona, e hoʻohana i nā palapala hōʻoia a i ʻole nā ​​kī e komo i nā kikowaena like ʻole a hōʻoia paha i ka SSL-Pinning. Mai kahi hiʻohiʻona palekana, ʻo ka mālama ʻana i ia mau mea ma ke code ʻaʻole ia ka hana maikaʻi loa. E hoʻāʻo kāua e kākau i kahi lula e ʻimi ai i nā faila like i loko o ka waihona:

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

He hana: Ke ʻimi nei i nā hōʻailona i hoʻopaʻa ʻia ma ka noi

pāʻoihana: Pono pinepine e hoʻopau i nā hōʻailona i hoʻopaʻa ʻia a i ʻole nā ​​​​ʻike koʻikoʻi ʻē aʻe i loaʻa i ke code. ʻOiaʻiʻo, ʻaʻole maikaʻi ka mālama ʻana iā lākou i loko o ke code kumu, akā ʻokoʻa nā kūlana. Mahalo i nā nīnau CxQL, maʻalahi ka loaʻa ʻana o nā mea e like me kēia:

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

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

hopena

Manaʻo wau e lilo kēia ʻatikala i mea pono i ka poʻe e hoʻomaka ana e kamaʻilio me ka mea hana Checkmarx. Malia paha e ʻike ka poʻe i kākau i kā lākou mau lula no ka manawa lōʻihi i kahi mea pono i kēia alakaʻi.

ʻO ka mea pōʻino, aia i kēia manawa ka nele o kahi kumuwaiwai kahi e hōʻiliʻili ai i nā manaʻo hou i ka wā o ka hoʻomohala ʻana i nā lula no Checkmarx. No laila mākou i hana ai waihona ma Github, kahi mākou e kau ai i kā mākou hana i hiki i nā mea a pau e hoʻohana iā CxQL ke loaʻa i kahi mea pono i loko, a loaʻa pū kekahi manawa e kaʻana like i kā lākou hana me ke kaiāulu. Aia ka waihona i ka hoʻopiha ʻana a me ka hoʻonohonoho ʻana i nā ʻike, no laila, mahalo ʻia nā mea kōkua!

Nā mea hou aku!

Source: www.habr.com

Pākuʻi i ka manaʻo hoʻopuka