α αα α!
αα αααα»αααΆαααΆαααααααΎα αααα»αα αα»αααααααΎαα αααΎααααααααααΆαααΆαα½αα§ααααααα·ααΆαααΌααα·αα·αααααααααα (SAST)α α ααααΈαααα’αααα½αααααΆααα’ααααααΎααΆαααΆαααααα ααΆααΆααα·αααΆαα ααΆααΆααα’ααααΊα’αΆαααααααΎαααααα αα·ααα αα αααα·ααααΆαααααΆαααααΎαα αααα»αααΆ ααααΌα ααΆααΆααΎαα αα αααα·ααααΆααΆαααααααααΌαααΆααααααααααααααα αααΆααααααΆααα·ααΆαααΆαααα’ααα»ααααΆα ααΆααααα·ααααααααα»α αααααααα·αα·α ααααααααααΆαααααα»ααα½ααα αααααααΎαααΎαα§ααααα SAST ααΊαααααααΆααααα»αααΆααααααααΆαα ααΆαααααααααΆααααΆαααααααααα·ααΈααααα’ααα αααααΊααααα αα·αααααΆααααααΌαα αααΆααααααΆααα·ααΆα α¬ααΌα ααααα½αααααααΌαααΆαααα α ααΆααΆααΉαααΆααααΆα Custom Queries α
ααΆααΉαααΆαααααα»αααΎαααααΎ Checkmarx αααααΆα’ααααα·ααΆαααΌααα½αα±ααα αΆααα’αΆαααααα αα·αααΆαααΆαααααααΆααα αα αααα»αα’αααααααααααα»αααΉααα·ααΆαα’αααΈαααα·ααααααααααααα»ααααα»αααΆααααααα αααΆααααΆααα·ααΆααααααΆααααΆα
ααΆααΆαααΆαα·ααΆ
-
ααααααΆαααΌαα α’αααΈα αααΆαα
ααΆαα»
ααΎααααΈα
αΆααααααΎα αααα»αα
ααααααΆαα’ααααααα½ααααα»αα
ααααα’ααααααα½αα
ααα½αααΆααΆααΆαα»ααααΈ α’αααΈαααααααα·αααααααΆαααααααααα½ααααααΆαα Checkmarx α ααΆααααΌαααΆαααααα»ααααα
ααΎ Habre αα
α
α»αααααΆα 2019 αααααα
αααααΎαααΆ:
ααΆαα·αα·ααααααα’α·αα’αααΈααααααααααααα½αααααΌααα αααα»α CxQL (Checkmarx Query Language) αααααΆαααααααα·ααΈααΆααααααα½αα ααα½α αα·ααααα αΆαααΈαααααΆαααααΆααΌαααααΆααααααααααα αααΆααααααΆααα·ααΆαααααΎαααΆαα
αααα»αααΉααα·ααα·ααΆαα‘αΎααα·αααΌαα’αααΈαααααΆααα·αααααΆαα αααα»αααΆαα αααααΈααΆα ααα»α ααααααααα½αα ααα½αααΉααα ααααΆαααααααΆααααααα αα αααα»αα’ααααααααααααα»α αααα»αααΉαααααΆααΆαα αααααααΌααααααααα "ααΆααααααΌαααΌααααα" αααααΆαααααΈαααααααααααΆαα αααααααα αΆααΆααααΆααααααααα»αααΆααα½αααααααααα»αα’αα‘α»ααααααααΎααΆαααΆαα½α Checkmarx α αααα»αβααααΌαβααβα α·αααβαα»αβααΆααβααΎβαααα αΆβααΆααβαααα ααααααααα·αααΆαααααααΆααααααααααΆαααα αααα»αα―αααΆααα α αΎααααααααααΆαααααΆαααα·ααΆααααααΈααααααααΎα’αααΈααααααααΌαα αααα»ααααααΉαααΆαααα·ααααααααααααα»α αα·αααααααααααα·ααααααΉααα·αα₯ααααααααααα α αΎα "ααΆααααααΌαααΌααααααααα½αααααΆαααααα½α" αααααΉααα½αααααααααα’αααααΈαααΈαααα α¬αααα·ααΆαααααΆαααΈαααΈα ααΌα ααααααΌαα αΆααααααΎα!
ααααααΆαααΌαα α’αααΈα αααΆαα
ααΆααααΌα ααΌααααα‘ααααΎαααααααα·αααΆααΌαααααΆααα½αα ααα½α αα·αααααΎαααΆαααααΆαααααΎααΆαααΆαα½αα αααΆαα ααΎααααΈαααααΆααααα αααΆααα’αααΈα’αααΈαααααΉαααΎαα‘αΎααααααΆαααααα α αΎαβααβαααααΆαβα―αααΆαβαα·αβαα·ααΆαβα’αααΈβα’αααΈβααΏαβααα α¬βααααΌαβααΆαβααααααααααΆαβαααΆαβααααΆααβαααα»αβαα ααΆααααααααβαααβαα·αβααΆααααα½αβααααΆααα
-
α αααΆααααααΌαααΆαα’αα»ααααααα‘α»αααααααααα’αΆαααααααΎααΆααααααααΆαα»ααααααΆαααααΎαααΎααα αααα αΆααααααΎα (αααα»αααα αααΆααααααα)α α’αααβα’αΆα βαααααΎαβα ααα½αβαααααβααΆαα»αβαα·αβααααα α αΎαβααααβαααα αβαα ααΆααααααααβαα½αααΆβαααΆαβααΆααααΆααβα’αΆαααααβααΎβααααΎαααΆαβααΆααααΆααβααααα’αααα α’αααα’αΆα ααΆααααΆαααα»αααΆαααΆααΆ α¬ααααΎαααΎαααΆααααααααΆαα»ααααααΆααααααααααΈαα½ααα α ααα½αααα αααΆααααααααααααΆαααααααααΏα αα·αααΆαααααΉαααααΌαααααΆααααααα
ααΆαααα‘αΎαααΆααααααααΆαα»ααα αααα»αα ααα»α αααααΆαα Checkmarx
-
α αααΆααααααΌαααΆαααααααα½ααα αααα»αα§ααααααα·ααααα½αα α ααΆ CxAuditα αααααΊααΆαααααα·ααΈαα»αααααΌααααααααααΆαααα αααΆαααΈαααααααααα»αααααΎαααΆα Checkmarx α α§ααααααααααΆαααααααααα·ααααα·ααΆαααΈαα α αααΆααααααααα½α αα·αααΆααα·ααΆαααααααααααΆαααααααααααΆαα’αα»αααααα½α α αΎαα
α ααα»α αααααΆαα CxAudit
-
α αααΆαααα αααα»α Checkmarx ααααΌαααΆααααα ααααΆαααΆααΆ αααααΊααΆααΆααΈαα½ααααΆααααα»ααααα½αααααΆαααααα½αα ααΆααααΆαα αααΆααααΌαα αα½αα ααα½ααααα’αα»ααααααααα·ααα·αααΈααΆααΆ ααΆαααααααΊααΆα’αααΈαααααα α ααΆαααα½αααΌαααααΆαα αααααΆαααααααααΆαα αααΎα αααα½αααΆααΌαααααΆαααΆαααααααααΉαααΆααααααααααααααΆααααα αααΆααααααααααααααΎα
ααΆααααα ααα αααΆααααΆαααΆααΆ
-
α αααΆααααΊ "α’αΆα ααααα·ααααα·ααΆα" αα·α "αα·αα’αΆα ααααα·ααααα·ααΆα" (ααααα·ααααα· αα·ααα·αααααΌαααΆαααααα·ααααα·)α αα·ααααααΆαααααααααΉαααααΌααα ααΆααααα·ααααααααα»α ααα»αααααααααΆααααα α ααα»α ααααΆααααΊααΆααααααααααΆαα’αα»ααααα αααΆαα "α’αΆα ααααα·ααααα·ααΆα" ααΉαααααΌαααΆααααα αΆααα αααα»αααααααααααααα αααα»α UI α αΎαα αααΆαα "αα·αα’αΆα ααααα·ααααα·ααΆα" ααΊααααΌαααΆαααααΎααααΈααααΎαααααααααααα½ααααα αααα»αααααΎααααααααααα»ααααα (ααΆααα·αααΆααααΆααααααΆαα»αααΆααα½αααα»αααααα )
αααααααααααα αααΆαααα ααααααααΎα
-
α’αααα’αΆα αααααΎαα αααΆααααααΈ α¬αααααα/αααααα‘αΎααα·αααΌαα αααΆαααααααΆαααααΆααα ααΎααααΈαααααα αααΆααα‘αΎααα·α α’αααααααΌααααααααααΆαα αααα»ααααααΆα α α»α ααααα»αααααΆα α αΎαααααΎαααΎα "ααα·ααα" ααΈαααΊαα»ααααααΆααα α»αα ααΆααΆααΏαααααΆαααααα»αααΆαα αα αΆααα ααΈαααααΆα αααΆααααααΈαα·αααααΌαααΆααααα αΌααααα»αααΆααααααααΆαα»ααα α αΎααα·ααααααα ααΎααααΈα αΆααααααΎαααααΎαα½αααΆα’αααααααΌαααααΎα±αααα½αααΆααααααα αααα»ααααΊαα»α "αααααα·ααΈαααααααααααΆααααααααΆαα»α" αα αααα»αα§αααααα α αααΆαααααααΆααααααα‘αΎααα·ααααααΆααΆαααααααααααα½ααα αααααΊααααα·αααΎα αααΆααααααα ααΆααΉααα αααααα α αΎαααΉαααααΌαααΆαα’αα»ααααααααΆααα
α§ααΆα αααααα αααΆααααααΈαα αααα»αα ααα»α αααααΆαααααααα·ααΈαααααααααααΆααααααααΆαα»α
-
αααα»αα’αα‘α»ααααααααα·ααααα· "ααΎαααΎ" ααααααΎααααΌαααΆαααΆαααααααα’αΆαααααααΎα’αααΈα α αααΆααβαααβαααααΌαβααααααΆαβααααΌαβααΆαβααααα·ααααα·βαα»αβαα α αΎαβα’αααβαααβααααΎβααΆβααΈααΈαα ααααααβααβααΆαβααααα·ααααα·βααααΌαβααΆαβαα»αβαααα»αβααααΆααβαααααΆαα ααΌα ααααβααααα·αβααΎβααΆβα’αΆα βααααΎβααααααβααβα αααΆααβαααβααΆαβααααΆαα αααβααΆβααα’βααΆαβαααα»αβααΆαβααααΎβααΌα αααα ααΆβααΉαβααΆααβαααααβαααβααααΆβαααααα
-
α αααΆααα’αΆα ααααΌαααΆαα’αα»αααααα ααααα·αααααααααααΆα
-
αααααΆααααααααααααΆααααΌα - ααΉαααααΌαααΆαααααΎαααααΆααααΆααααααααααααααΆαα½αα
-
αα ααααα·ααααα»α (αααα»α) - ααΉαααααΌαααΆαααααΎααΎααααΈααααααααααααα αααα»ααααα»ααααααΆαααααΎαααΎαααα»αααααα
-
αα ααααα·ααααααα - ααΉαααααΌαααΆαα’αα»αααααα αααα»αααααααααΆααααΆαααα½αα
ααΆααααααααααα·ααααα αααΆααααΉαααααΌαααΆαα’αα»αααα
"αα ααΆαα»αααα" αααααΆααα’αααα αΆααααααΎαααααΌα
α αΎααααα»αααΉαα αΆααααααΎαααΆαα½αααΉαααΏααα½αα ααα½αααααααααΆαα±αααααα»αααΆαα ααααα α αΎααααα»αααααΉααααα αΆαααΈαα αα ααααααα½αα ααα½ααααααΉαααααΎα±ααααΈαα·αααΆααααααΆααααα½αα
ααααα·ααααα·ααΆαααΆαα½ααααααΈ
- Π²ΡΡΠΈΡΠ°Π½ΠΈΠ΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· Π΄ΡΡΠ³ΠΎΠ³ΠΎ (list2 - list1)
* ΠΏΠ΅ΡΠ΅ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ ΡΠΏΠΈΡΠΊΠΎΠ² (list1 * list2)
+ ΡΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠΏΠΈΡΠΊΠΎΠ² (list1 + list2)
& (Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΎΠ΅ Π) - ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ ΡΠΏΠΈΡΠΊΠΈ ΠΏΠΎ ΡΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΡ (list1 & list2), Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ½ΠΎ ΠΏΠ΅ΡΠ΅ΡΠ΅ΡΠ΅Π½ΠΈΡ (list1 * list2)
| (Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΠΠΠ) - ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ ΡΠΏΠΈΡΠΊΠΈ ΠΏΠΎ ΡΠΈΡΠΎΠΊΠΎΠΌΡ ΠΏΠΎΠΈΡΠΊΡ (list1 | list2)
Π‘ΠΎ ΡΠΏΠΈΡΠΊΠ°ΠΌΠΈ Π½Π΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ: ^ && || % /
ααΆαα»αααααΆαααααΎαααΆααα’ααα
αα
αααα»αααΆααΆαααααΆαααααα α’αααα’αΆα
ααα½αααΆααααααΈααααΆαα»ααΆααα’ααααα Checkmarx ααΆααααααα’ααααααααΆα (ααααα’αααα αα»αααΆα ααααΆαα αα·ααΈααΆαααααααα)α αααααΊααΆα
ααααααα½αα
ααα½αααααααα»αααα’αΆα
α
αΌαααΆαααΆαααα All
. αααααΊααΎααααΈαααααααααααα»αααααΆααααααααΆααααΆαα searchMe
α§ααΆα ααα α’αααα’αΆα
αααααααααΆααααααααΆαααααα»αααααΆαααααΎαααΆααα’ααα
// Π’Π°ΠΊΠΎΠΉ Π·Π°ΠΏΡΠΎΡ Π²ΡΠ΄Π°ΡΡ Π²ΡΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ
result = All;
// Π’Π°ΠΊΠΎΠΉ Π·Π°ΠΏΡΠΎΡ Π²ΡΠ΄Π°ΡΡ Π²ΡΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ, Π² ΠΈΠΌΠ΅Π½ΠΈ ΠΊΠΎΡΠΎΡΡΡ
ΠΏΡΠΈΡΡΡΡΡΠ²ΡΠ΅Ρ βsearchMeβ
result = All.FindByName("searchMe");
ααα»ααααααααα·αααΎα’αααααααΌαααΆααααααααααΆααΆααΆααααααααααααααααΆααα ααα»αααα½αα ααα½ααα·αααααΌαααΆααα½ααααα αΌααααα»αααΆαααααα (α§ααΆα ααα groovy αα αααα»ααααααα Android) α’αααα’αΆα αααααΈαααα αααααα»ααααααΎαααΆααααα’ααααα½αα
result = AllMembers.All.FindByName("searchMe");
αα»αααΆααααααΆααααΆααα·ααΆαααα αΌα
αα»αααΆαααΆαααααααααΌαααΆαααααΎααααΆαααααα»αα αααΆααααΆα αααΎα α αΎααααααΊααΆαααααΉααααααααΌα αα½αααα’ααααααααααααΆα
// ΠΠ°ΠΊΠΈΠ΅ Π΄Π°Π½Π½ΡΠ΅ second Π²Π»ΠΈΡΡΡ Π½Π° first.
// ΠΡΡΠ³ΠΈΠΌΠΈ ΡΠ»ΠΎΠ²Π°ΠΌΠΈ - Π’Π (second) ΡΡΠΎ Π²Π»ΠΈΡΠ΅Ρ Π½Π° ΠΠΠΠ― (first).
result = first.DataInfluencedBy(second);
// ΠΠ°ΠΊΠΈΠ΅ Π΄Π°Π½Π½ΡΠ΅ first Π²Π»ΠΈΡΡΡ Π½Π° second.
// ΠΡΡΠ³ΠΈΠΌΠΈ ΡΠ»ΠΎΠ²Π°ΠΌΠΈ - Π― (first) Π²Π»ΠΈΡΡ Π½Π° Π’Π (second).
result = first.DataInfluencingOn(second);
ααα½αααΆααααααα―αααΆα/ααααΌα
ααΆααα»αααααααααΆα αααΎααααα’αΆα ααα½αααΆαααΈαααααααααααα½α (αααααα―αααΆααααααΆαααααΎα ααααα’ααααα ααΌα ααααααΎααααΈααααΎααΌα ααααααΆα α’αααααααΌαα αΌααα ααΆαααααααααααααααα· LinePragma α αΎαααααα»αααααΎαααααΌαααΆαααΉαααΆαααΈααΆαααα ααΆααααα»αααΆα
// ΠΠ»Ρ ΠΏΡΠΈΠΌΠ΅ΡΠ° Π½Π°ΠΉΠ΄Π΅ΠΌ Π²ΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄Ρ
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);
ααΆααΊααΆααααααααααΆαα»ααααα»αα
α·ααααααα FileName
αα·αααΆααΆαααααΌααα
ααΆααα―αααΆα αααααΆαααΎαααΆαααααΎαα·ααΈααΆααααα GetFirstGraph
.
ααααααααααα·ααααα·
ααΆαα’ααααα·ααααα
ααΆααααα»α CxQL result
ααααααα‘ααααααααααααΆαα’αα»ααααα
αααΆααααΆααΆαααααααα’ααααααααα’αααα ααΆααααΌαααΆαα
αΆααααααΎαααααΆαα α αΎαα’αααα’αΆα
αααααααααααααααα·αααααααα
αααα»αααΆ ααααΆααααααΌα αα·ααααααα’αα½αααΆαα
αααα’αααααααΎααΆαα ααα»ααααααααα·αααΎαα·αααΆαααΆαα
αΆααααΆαααα
α’αααααα α¬αα»αααΆααα
αααα»αα
αααΆααααα return
- ααααααααααα·ααααα·ααΉααααααααΆααΌαααα
αααα½αααΆααααααααΉααα·ααααααα’αααΈααααΎααα·αααΆααααααααααΆαααααα·ααααα·αα α αΎαααΉααα αααααααΆαα·α αα α
// ΠΠ°Ρ
ΠΎΠ΄ΠΈΠΌ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ foo
CxList libraries = All.FindByName("foo");
ααα»αααααααααΆααααααααααααααααα·ααααα·αα ααααααα’αααααααααα ααΎαααΉαααΎαα’αααΈαααααΆαα α ααααααα‘ααααααΎααα·αα
// ΠΠ°Ρ
ΠΎΠ΄ΠΈΠΌ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ foo
CxList libraries = All.FindByName("foo");
// ΠΡΠ²ΠΎΠ΄ΠΈΠΌ, ΠΊΠ°ΠΊ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΏΡΠ°Π²ΠΈΠ»Π°
result = libraries
// ΠΠ»ΠΈ Π΅ΡΠ΅ ΠΊΠΎΡΠΎΡΠ΅
result = All.FindByName("foo");
ααΆαααααΎααααΆααααααααααα αααΆααααααααααα
α αααΆαααα αααα»α Checkmarx α’αΆα ααααΌαααΆαααα α ααΆααααααααααΆαα ααΉααα»αααΆααα αααα»αααΆααΆααααααααααα·ααΈααααααΆα αα ααααααααα αααΆαα α’αααα’αΆα ααααΎαααααααααααα½αααααααααα α§ααΆα ααα αα·αα αΆαααΆα ααααααααααΆαα α ααΆααα·ααΈααΆααα’αααααα»αααΌαααΆαααααααααα ααααΆααααα α αααα½ααααα ααααΆαα
// ΠΠΎΠ»ΡΡΠ°Π΅ΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π΄ΡΡΠ³ΠΎΠ³ΠΎ ΠΏΡΠ°Π²ΠΈΠ»Π°
CxList methods = Find_Methods();
// ΠΡΠ΅ΠΌ Π²Π½ΡΡΡΠΈ ΠΌΠ΅ΡΠΎΠ΄ foo.
// ΠΡΠΎΡΠΎΠΉ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ false ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΠΈΡΠ΅ΠΌ Π±Π΅Π· ΡΡΠ²ΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ ΠΊ ΡΠ΅Π³ΠΈΡΡΡΡ
result = methods.FindByShortName("foo", false);
αα·ααΈααΆααααααααα’αα»ααααΆαα±ααα’αααααΆαααααααααΌα αα·αααΆααααααααααααααΆα’αα»ααααα αααΆαααααΆαααααΆααα
αααααααΆααααα αΆ
ααΆαααΆααααΎ
αα αααααααΎααΆαααΆαα½αα§ααααα αααααααααΆαα·αα’αΆα αα αα½α αααααα»αααΆαααααααααα½ααααα ααααΆαααααΆαα α αΎαα’αααααααΌααααα·ααααααααααααΆααΆααααααΎαααααααα αααααΆααααααΈαααααα α§ααααααααααααΌαααΆαααΆααααΎ αααααααΌαααΆαααα α ααΆααΌα ααΆαααααα:
// ΠΠ°Ρ
ΠΎΠ΄ΠΈΠΌ ΡΡΠΎ-ΡΠΎ
CxList toLog = All.FindByShortName("log");
// Π€ΠΎΡΠΌΠΈΡΡΠ΅ΠΌ ΡΡΡΠΎΠΊΡ ΠΈ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌ Π² Π»ΠΎΠ³
cxLog.WriteDebugMessage (βnumber of DOM elements =β + All.Count);
ααα»ααααααΆααΆααααααα
αα
αΆαααΆαα·ααΈααΆααααααααααα½αααααααΆααΆααααα
αΌαααα»αααααα ααααα’ααααααΌα
ααααααΆααΉααα·αα’αΆα
αααα αΆααααααΈααααααααααΆαα»αααααΆαααααΎαααΆααααααααααααα·ααααα·ααΆαααααΌαα‘αΎαα αααααΎαααΈααΈααααααααΌαααΆαααααΎαααααΆααααΆαααααΆααααα α»αααΊααααΌαααααααα
α’ααααααααααααΈααααα½ααα
ααααα½αα result
αααααααααααα½α αα·αααΎαααΆααΆαα’αααΈααΎαα‘αΎαα αα·ααΈααΆαααααααααα·αααΆααααα½ααα α’αααααααΌαααααααΆααααΆαα·αααΆαααΆαααα·ααα α¬ααααα·ααααα·ααΆαααΆαα½αααΆαα
αααα»αααΌααααααΆααααΈ result
α¬ααααΆαααα Comment ααΌαααΆααααααα α¬α’αααα’αΆα
ααΌα
ααΆαααα»α ααααα
αα»αααΆαα α
ααΌαααααααααααα
ααααΈα
αααΆαααααααααααα½α
ααΆααααα
α αΎααααααααΆα ααα»α’αααΈααΆαααΆααααΆαα’αααΈααααΎαααΆαα
αααααααΆαααΆααααα½αααΆαααΊα α
αα·ααΈααΆααααα return
ααΆαα½αααΉααααΆαααΆαααααααααααααΌαααΆαα αααα»αααααΈααα ααΆαα’αα»ααααα
αααΆααααΉααααα
αα α αΎαααΎαααΉαα’αΆα
ααΉαααΆα’αααΈαααααΆαααΎαα‘αΎαααΆααααααααα’αααΈαααααΎαααΆααααααα
// ΠΠ°Ρ
ΠΎΠ΄ΠΈΠΌ ΡΡΠΎ-ΡΠΎ
CxList toLog = All.FindByShortName("log");
// ΠΡΠ²ΠΎΠ΄ΠΈΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ
return toLog
//ΠΡΠ΅, ΡΡΠΎ Π½Π°ΠΏΠΈΡΠ°Π½ΠΎ Π΄Π°Π»ΡΡΠ΅ Π½Π΅ Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΎ
result = All.DataInfluencedBy(toLog)
αααα αΆβα αΌα
ααΆαααααΆαααΆααα ααααααα’ααααα·αα’αΆα α αΌαααααΎα§ααααα CxAudit (αααααααΌαααΆαααααΎααΎααααΈαααααα αααΆαα)α ααΆα’αΆα ααΆαα ααα»ααααΆα αααΎααααααΆαααααα αΆααα αα½αααΆααααΆαααΆαα ααΆαα’αΆαααααααΈαααΌααααΆαα BSOD αα·αααααΆαααΆαααααα·αααΆαααΎαααΎααα»αααΆαα»ααααααααααααα α½αααΈααΆααααααααααααααααΎαα αααα»αααααΈααα αα½αααΆαααΆαααααααααα·αααΆαααααα αααα αααα»αααΌαααααΆααα·αααααα αααααΆααΆααα’αααααΈααΆαα αΌααααααααα ααΎααααΈαα½ααα»αααΆ α’αααααααΌαααααΎαααΆααααα½αααΆα αααΎαα
αααααΆαα Checkmarx αα»α 8.6α
// ΠΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ, ΡΡΠΎ Π΅ΡΡΡ Π·Π°Π»ΠΎΠ³ΠΈΠ½Π΅Π½ΡΠ΅ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΠΈ, Π²ΡΠΏΠΎΠ»Π½ΠΈΠ² Π·Π°ΠΏΡΠΎΡ Π² ΠΠ
SELECT COUNT(*) FROM [CxDB].[dbo].LoggedinUser WHERE [ClientType] = 6;
// ΠΡΠ»ΠΈ ΡΡΠΎ-ΡΠΎ Π΅ΡΡΡ, Π° Π½Π° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅ Π΄Π°ΠΆΠ΅ Π΅ΡΠ»ΠΈ ΠΈ Π½Π΅Ρ, ΠΏΠΎΠΏΡΠΎΠ±ΠΎΠ²Π°ΡΡ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ Π·Π°ΠΏΡΠΎΡ
DELETE FROM [CxDB].[dbo].LoggedinUser WHERE [ClientType] = 6;
αααααΆαα Checkmarx αααααΆααααΈ 8.6α
// ΠΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ, ΡΡΠΎ Π΅ΡΡΡ Π·Π°Π»ΠΎΠ³ΠΈΠ½Π΅Π½ΡΠ΅ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΠΈ, Π²ΡΠΏΠΎΠ»Π½ΠΈΠ² Π·Π°ΠΏΡΠΎΡ Π² ΠΠ
SELECT COUNT(*) FROM LoggedinUser WHERE (ClientType = 'Audit');
// ΠΡΠ»ΠΈ ΡΡΠΎ-ΡΠΎ Π΅ΡΡΡ, Π° Π½Π° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅ Π΄Π°ΠΆΠ΅ Π΅ΡΠ»ΠΈ ΠΈ Π½Π΅Ρ, ΠΏΠΎΠΏΡΠΎΠ±ΠΎΠ²Π°ΡΡ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ Π·Π°ΠΏΡΠΎΡ
DELETE FROM [CxDB].[dbo].LoggedinUser WHERE (ClientType = 'Audit');
α αααΆααααααα
α₯α‘αΌααααααΎααα ααααααααααααα½αα±ααα αΆααα’αΆαααααααααα»αα αα αααα’αααα αΆααααααΎααααααα αααΆαααα αααα»α CxQL α’αααΈαααα’ααααααααααααααΊαα·αααΆαα―αααΆαα αααΎαααΌα α§ααΆα αααααααααααΆααααααααΆααααα αΆαα½αα ααα½α αα·αααΆααα·αααααΆα’αααΈααααΎαααΆαααααααα·ααααα·ααΆααααα½αααΆααΌαα α
αααα»αααΉαααααΆααΆαααααΎα±ααααΈαα·αααΆααααααΆααααα½ααααααΆααα’ααααααα αΆααααααΎαα αΌααα αααα»αααΆααΆαααα½α α αΎααααααα§ααΆα ααααα½αα ααα½αααααΆαααααΎααααΆαα Custom Queries ααΎααααΈαααααααΆααααα αΆααΆααααΆααα αα½αααΆαα½αα ααα½αααΆαααααααααΌαα α αΎαα’αΆα ααααΎααααΆαααααα»ααααα»αα αα»αααααα’αααααΆααααααΆαα’αα»αααααααααααΆαααΆαααααΆααααααΌα αααααααααΆαααααααααΆααααΆααααΆα ααα»αααααα½αααααα’αΆα ααααΎααααΆααααΆααααααΆαααααΆααααααΌαααΌαα±αααααααααα ααΉαααααααααΆααααΆαααααααααα·ααΈααααα’αααα
ααΌα αααα αααααΆαααα αΆαααααΎααα½ααααααααΉαααΆαααααα»αα
ααΆααα·α αα α ααΆαααα αΌαααΆα αααΎααα αααα»αααααααααααΆαααααα·ααααα·α αααΆαα α αΎααα½ααααα»αα αααααα½αααααΊααΆαααα»ααααα½ααααααααα α’αααααααΌααααα»ααα½ααααα»αα αααααα½αααα
ααΆαααααααααΆα: ααΆααΆααα·αααΆαα ααααααα Checkmarx αααα αΆαααα αΌααα·ααααααααΆα αααΎααααα’αΆα αααα½αααΎααααΆ αα·αααΆααααααααΈααααα’ααααααα ααΆααα·ααΈααΆααααααα·ααααααααΆααααααΈαααααα ααΆαααααααααα αΌαα α’αΆαααααααΎαααΆαααΆαααααα ααΆααΉαααααΎαααΎαααα αΌαααααΈαααα»α α¬ααααααα»αα
// ΠΡΡΠ°Π²ΠΈΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»ΠΈΠ½Π½ΡΠ΅ Flow
result = result.ReduceFlow(CxList.ReduceFlowType.ReduceSmallFlow);
// ΠΡΡΠ°Π²ΠΈΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΊΠΎΡΠΎΡΠΊΠΈΠ΅ Flow
result = result.ReduceFlow(CxList.ReduceFlowType.ReduceBigFlow);
ααΆααα·α αα α αααααΈααααααΈαα·αααααααααΎααααα§αααααααΆαααααα·αααα
ααΆαααααααααΆα: Checkmarx ααΆαα αααΆααααΆααΌαααααΆα αααααααααααααΌαααΆαααααΎααααΆααααααααα½αααΆα αααΎααααα αααααΆααααααααααααααΌαα αααΆααααΆααααααα½αα ααα½αααΆαα½αααΉααα·ααααααααΆααααΆααα αααααααααα·ααΈααααα’ααα α’αααα’αΆα αααααα’αααααααααααααααα’αααααααΆααα ααΆαβαααααβαααβααΆβα αααΆααβα§ααΆα αααβααΎααααΈβα±ααβα’αααβα αΆααβααααΎαα
αααααΈααΌαα _α―αααααΆα_ααΆααααααααααΆα
αααααααααα’αααααΆα αααΎααααααααΎαααα»ααααααα·ααΈααααααΎαααΎααααΈαααααΆαα»αααααααΆααααΎαα
// ΠΠΎΠ»ΡΡΠ°Π΅ΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡΠ°Π²ΠΈΠ»Π°
result = base.General_privacy_violation_list();
// ΠΡΠ΅ΠΌ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΏΠΎΠΏΠ°Π΄Π°ΡΡ ΠΏΠΎΠ΄ ΠΏΡΠΎΡΡΡΠ΅ ΡΠ΅Π³ΡΠ»ΡΡΠ½ΡΠ΅ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡ. ΠΠΎΠΆΠ½ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΡ Ρ
Π°ΡΠ°ΠΊΡΠ΅ΡΠ½ΡΠΌΠΈ Π΄Π»Ρ Π²Π°Ρ ΠΏΠ°ΡΡΠ΅ΡΠ½Π°ΠΌΠΈ.
CxList personalList = All.FindByShortNames(new List<string> {
"*securityToken*", "*sessionId*"}, false);
// ΠΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΠΊ ΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΌΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ
result.Add(personalList);
ααΆααα·α αα α αααααΈααααααΈα’ααααααααααΎααΆααααααααΆαα
ααΆαααααααααΆα: αααα»αααΉααααααα’αα»ααΆαααααααΆααα±ααααα α·ααααα»αααΆααααΎα αααΆααααΆααΌαααααΆααααααΆααααΆααααααααΆααααααααΆαααα αααα»αααΌα α αΎααααααααα ααΆααΌααααααΈαααααα’ααααααααααΌαααΆαααααΎααΆααΌαα αα αααα»ααααα»αα αα»αααααα’αααα
ααααααααΆαα_α―ααα_ααΆαααααΆα_αααααΈ
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);
}
}
ααΆααα·α αα α ααααααααααααααααααααΆαααααΎααααα·αααααΌαααΆαααΆααααααα Checkmarx
ααΆαααααααααΆα: αααα½αααΆααα’αααα αααα»α Checkmarx ααααΌαααΆααααα ααααΆαααΆααΆ ααΌα ααααα’αααααααΌαααααααα αααΆαααααααΆααααΆααΆααΈαα½ααα ααΆαααααααααααΊααΆα§ααΆα ααααα½αα ααα½αααα αααΆααααααααα
ααααα·αααΎαααααΆαααααααΌαααΆαααααΎααααΆαααααααααααααααα α¬αααα½ααα»αααΆααααααααΆα ααααα½αααΆα’αΆα ααααΌαααΆααααααααααΆαααΆααααα½ααα αααα»αα αααΆααααΌαααααΆαα αααααΆααααα’ααααααααααααΆαααααααΎααΆααΉαααΉαααααΆααα’αααΈααΆαααααΆαααααΈα ααΆα§ααΆα ααα αααααΆααααααααΆααα αΌααααααααα Android ααΊ Timber αα·α Loggi α αα αααα»ααααα ααααΌαααααΆα αα·αααΆαα αααΆαααααααΆαααααααα’ααααααααΆαααΆαα α ααΌαααααααααα·ααααααΆαααααααααα ααΌα ααααααααα·αααΎααΆααααααααΆαα α¬α§ααααααααααααααα αΌαααααααααα ααα» ααΎαααΉααα·αααΉαα’αααΈααΆααα α αΌαααΎαααααΆααΆααααααααα·ααααααααα·ααΈααΆααααααααααααα ααΉαα αααΆαα Checkmarx α
ααΆαααααα§ααΆα αααααΌααααααααΎαααααΆααα Timber αααααΆααααΆααααααααΆα
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");
}
}
α αΎααααααΊααΆα§ααΆα αααααααααΎαααααΆαα Checkmarx αααααΉαα’αα»ααααΆαα±ααα’ααααααααααα·αααααααααΆαα α αα·ααΈααΆααααα Timber ααΆα ααα»α α αααααααΆαααα·ααααααααΈαααααα·ααΈα
ααααααααααααα Android
// ΠΠΎΠ»ΡΡΠ°Π΅ΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡΠ°Π²ΠΈΠ»Π°
result = base.Find_Android_Outputs();
// ΠΠΎΠΏΠΎΠ»Π½ΡΠ΅ΠΌ Π²ΡΠ·ΠΎΠ²Π°ΠΌΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΏΡΠΈΡ
ΠΎΠ΄ΡΡ ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Timber
CxList timber = All.FindByExactMemberAccess("Timber.*") +
All.FindByShortName("Timber").GetMembersOfTarget();
// ΠΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΠΊ ΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΌΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ
result.Add(timber);
α αΎαβα’αααβααβα’αΆα βααααααβαα βααΉαβα αααΆααβαααβαα βαα·αβααΆαβααα ααα»ααααβααΆβααΆααααβααααΆααβααΉαβααΆαβα αΌαβαααααααα Androidα
ααααααα AndroidLog_Outputs
// ΠΠΎΠ»ΡΡΠ°Π΅ΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡΠ°Π²ΠΈΠ»Π°
result = base.Find_Android_Log_Outputs();
// ΠΠΎΠΏΠΎΠ»Π½ΡΠ΅ΠΌ Π²ΡΠ·ΠΎΠ²Π°ΠΌΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΏΡΠΈΡ
ΠΎΠ΄ΡΡ ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Timber
result.Add(
All.FindByExactMemberAccess("Timber.*") +
All.FindByShortName("Timber").GetMembersOfTarget()
);
αααααααααα·αααΎαααααα·ααΈ Android ααααΎ getInputData
:
ααααααα AndroidRead
// ΠΠΎΠ»ΡΡΠ°Π΅ΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡΠ°Π²ΠΈΠ»Π°
result = base.Find_Android_Read();
// ΠΠΎΠΏΠΎΠ»Π½ΡΠ΅ΠΌ Π²ΡΠ·ΠΎΠ²ΠΎΠΌ ΡΡΠ½ΠΊΡΠΈΠΈ getInputData, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π² WorkManager
CxList getInputData = All.FindByShortName("getInputData");
// ΠΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΠΊ ΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΌΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ
result.Add(getInputData.GetMembersOfTarget());
ααΆααα·α αα α αααα»αααααααααα·αααααααααΎααα αααα»ααααααΈαααααΆαααααααα iOS
ααΆαααααααααΆα: iOS ααΆααΉαααΆααααααΎα―αααΆααα·ααααααααΆαααααααααααα .plist ααΎααααΈαααααΆαα»αα’ααα αα·ααααααααααααα ααΆααααααΆαα»αααΆααααααααΆαα ααΌααΉα αα αα·ααα·αααααααααΎααααααααααα αααα»αα―αααΆαααΆααααααα·αααααΌαααΆαααααΆααα ααααααα½αααα’αΆα ααΆαααα ααααΈα§ααααααααααααΆααααα αΆα
α―αααΆα Plist ααΆααααααααα·αααααααα·αα αααΆααααααααααααα ααα»ααααααΆαααΆααααααΆααα αααα Checkmarx α α αΌαααΎααααααα αααΆαααααααΉαααααααααα·αααααααααααΎαααααΌαααΆα α αΎαααααΆααααΎαααααα·αααΎααΆααααααααΆαα α¬αααααΆαααααΆααααααΌαααΆαααΎαα‘αΎααα ααααααααΆαα½αα
α§ααΆα αααααα―αααΆααααααααααααΆααααααΆαααααΆαααααααΆααααΆαααααΆααααααααΆαα½αααααΆαααααααααααΆααααααα
<?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>
αα·αα αααΆαααααααΆαα Checkmarx αααααΆα nuances ααΆα αααΎαααααα½αααααΌααααααα·α αΆαααΆαα ααααααααα
// ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΏΡΠ°Π²ΠΈΠ»Π° ΠΏΠΎ ΠΏΠΎΠΈΡΠΊΡ ΡΠ°ΠΉΠ»ΠΎΠ² 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);
ααΆααα·α αα α αααααααααααααΆααα αααα»α XML
ααΆαααααααααΆα: Checkmarx ααΆααα»αααΆαααΆααααα½ααααααΆααααααΎααΆαααΆαα½α XML αα·αααΆααααααααααααα ααααΆα αα»ααααααα αα·αα’αααΈαααΆα αααΎααααα ααα»ααααααΆα’αα»αα ααΆαααα α»ααα αααα»αα―αααΆα αααααΆαααΆαα·αααααΎαααΆαα§ααΆα ααααααα½αα αααααΈααΆααΆααα·ααααααΆαα·ααΆαααΆααααααααΌαααΆααα»αα αααα αααα»αααααα α»ααααααααα―αααΆαααααα ααΌαααααααααααααα·αααΎα’αααααααΎαααααα»αααα―αααΆαα
αααααΆα§ααΆα ααααα·αααααΉαααααΌαααΈα―αααΆαα
// ΠΠΎΠ΄ ΡΠ°Π±ΠΎΡΠ°ΡΡ Π½Π΅ Π±ΡΠ΄Π΅Ρ
result = All.FindXmlAttributesByNameAndValue("*.app", 8, βidβ, "error- section", false, true);
ααΆααααααααααΆαααα»ααααααααα·ααααα· ααΎαααΉαααα½αααΆαααα α»ααααα All
αα·αααΆααα·ααΈααΆααααααααααααα... α αΎααααααΆααΆααα·α αααααΆαααΆααΆαα
αααααααααα»αα·αααααΆα
ααααα‘αααααααΆααααααΎαα»αααΆααααααΆααααααΎααΆαααΆαα½α XML - cxXPath
. αααβααΆβα’αααΈβαααβαααα½αβααααΉαααααΌαβααΎαβαα
βααΌα
βααΆβααΎααααΈβαααααβααβααΆαβαααααβαααα»αβααααααααβααααα·ααααα·ααΆα Android αααβα’αα»ααααΆαβα±ααβααααΎβα
ααΆα
ααα HTTPα
// ΠΡΠ°Π²ΠΈΠ»ΡΠ½ΡΠΉ Π²Π°ΡΠΈΠ°Π½Ρ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ cxXPath
result = cxXPath.FindXmlAttributesByNameAndValue("*.xml", 8, "cleartextTrafficPermitted", "true", false, true);
ααΌααααα‘ααααΎαααΆα±αααααα’α·αααααα·α αααααααΆααααααααααααααααΆαααα»αααΆαααΆααα’ααααΊααααααααααΆ αααααΆααααΈα’αααααΆαααααΎααα½ααα½α α’αααααααΆααααααααΌαααααΎαααΎααα½ααααα’αααααααΌαααΆαα ααΌα ααααααΆαααααΆαααααααααααα ααΆααααΆαααΆααααααα
-
"*.xml"
- αααΆααααα―αααΆααααααααΌαααααααα -
8
- ααααααααΆααααΆααΆαααα αααΆααααααΌαααΆαα’αα»αααα -
"cleartextTrafficPermitted"
- ααααααα»ααααααααααα»α xml -
"true"
- ααααααααα»ααααααααααα -
false
- ααΆαααααΎααααΆααααααααααααααΆαα αααααααααα -
true
β ααΆααααααΆααΆααααααααααΉαααααΌαααΆαα’αα»ααααααααα·αα’αΎααΎααααΈ αααααΊαα·ααααααΆααα’ααααααΌα αα
ααΆα§ααΆα ααα ααΎαααΆαααααΎα
αααΆααααααααααα’ααααααααΆααα·αααααΉαααααΌα ααΆααααααααα»ααααα·ααΆα ααΆααααααααΆααααααΆαααααααΆααα
αααα»α Android αααα’αα»ααααΆαα±ααααααΆααααααααΆαα½ααααΆαααΈαααααΆαααααα·ααΈααΆα HTTP α α§ααΆα αααααααΆαααααααααααΆααα»ααααααα cleartextTrafficPermitted
ααΆαα½αααΉαα’αααααα 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>
ααΆααα·α αα α αααααααααααααααααααα―αααΆα/ααααΌα
ααΆαααααααααΆα: αα
αααα»ααααααααααα½αααΆααααααΉαααΆαα’αα·αααααααααααα·ααΈααΌαααααααααααΆαα Android ααΎαααΆααα½ααααααααΆααα·αααααΆααα·ααα·αααα
αααΆααααααααααααΆααααααααΆαα
ααααΌαα
αααααα ααΆααα·αααΊααΆα
αααΆααα
ααααΈαααα’ααααααααααααα»αα―αααΆα build.gradle
ααΆαααααααααααα½ααα»αααααΌαα
ααααααΆαα’αα»ααααα
αααΆααααααΆαααααΆαααααααΆααααααα
ααααααΆααααααααα·ααΈα
ααα»αααααα
αααα»ααααααααα α αα½αααΆαααΆαα―αααΆααα»ααΆα build.gradle
ααααααα
ααΎαααααΆαααααααα½ααααα
αΌααααα»αααααααα ααΆααα·ααααααααΊααΆ αααααΈααΆα―αααΆαααΆααααααα·ααααα αΆαααΈαααααΌαααΆααααααΆααααΆαααααΆααααααα ααΆααααααααα―αααΆαααα‘αΎαααααΉαααααΌαααΆαα’αα»ααααααα‘α»ααααα
αααααα
ααΌα
αααα ααΆααα·α
αα
ααΊααΆααααααΆα
ααααααΉααα
αααα»αα―αααΆαααΌααααααΆαααααα·αααα·αααααααααΆαααα αα½αααα’αΆα
ααααΌαααΆααααααα’ααααααααΆααααααααααΆααααααααΆαα apply 'com.android.library'
.
ααΌαα§ααΆα αααααΈα―αααΆα build.gradle
αααααααααααααΌαααΆααααααΆααααΆααααα
ααα‘αα
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "24.0.2"
defaultConfig {
...
}
buildTypes {
release {
minifyEnabled true
...
}
}
}
dependencies {
...
}
α―αααΆαα§ααΆα ααα build.gradle
αααααΆαααααααΆαααααααα½ααααα
αΌααααα»αααααααααααα·αααΆαααΆαααααααααα
apply plugin: 'android-library'
dependencies {
compile 'com.android.support:support-v4:18.0.+'
}
android {
compileSdkVersion 14
buildToolsVersion '17.0.0'
...
}
αα·αα αααΆαααααααΆαα 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);
}
}
}
αα·ααΈααΆααααααααα’αΆα ααΆαααααααααΆααα αα·αααΆααααααααααα·αααααΉααααααααΆαααααααα·ααΈ Android ααα»ααααααα ααα»ααααααΆαααααααΆααααααΈααααααααααααα αα ααααααα’αααααααΌααααααααΆααΎααααααααΆαααααα·αααα·ααααα―αααΆαααΆααααΆαααααα¬ααα
ααΆααα·α αα α ααααααααΆαααΆαααααααααΆαααααααΆαααααΆααΈααΈααΈ ααααα·αααΎααΆααααααααααααα·αααααΌαααΆαααΆααααααΆαααααα»α
ααΆαααααααααΆα: α ααα½αααααααααααααααααααααααααΌαααΆαααααΎαααα»αααααΎαααΆαααααΆααααααααΌαααΊααααΆααααα ααααΈααΆααΆαα ααΆααΆααα·αααΆαα Checkmarx αα·ααααααααΉαα’αααΈα’αααα·ααΆααααααα½ααααα α αΎαααΆααα·α αα ααααααΎαααΊααααααααΆα±αααααααΆαα·ααΈααΆαααααααΆααααΆααααΆαααααα·αααα·ααααααααααααααααα αααααααααΆααΆαααΆααααα»αααααΆααααααΆααα·ααααααΆαααααααααααααΎααααααα»αααΆααααααΆααΏαααααααΆαααα»αα αΎαααΆαα·αα’αΆα αα αα½α αααααα»αααΆααααααααααα·αα αααΆααααΆααααΌαααααΆααααααααααΆαα α αα αααααΆαααααΆααααΆαααα½αα
ααΆαααααΆαααΊααΆααΆααααααααααααααααααΆααααααααααα·ααααααααααΌαααΆαααα½αααααΆααααααΉαααααΌαααα αΎαα’αααααααΌααα·αααααααΎααααΈαααααΆαααΆαααα½αααΆαα ααα½αααα αααΎααααα·αααααΆααα·ααα·αα ααΆααααααΎαααΆα αααΎαααΎααααΈαααααα’ααΆαααααΉαααααΌαααααΆαααααα αα·ααααααααΆααααα αΆα
-
αααααΎαααΈαα½α ααΎαααΉαα αααΆααααΆαααααΆαααααααΌαααΆαααααΎααααΆαααααα»αααααααααΆααααΆαααα½α α αΎαα’αΆα α’αα»ααααα αααΆαααα ααααα·ααααα»αα ααα»ααααααααα·αααΎαααα»ααααααα α α·ααααααα·ααΈααΆαααααααααα α¬ααααΎαααααΆαααααΆα αααΎααααααααααα»αααΆααααα½αααΎααααΆααα ααΎαα’αΆα ααα½αααΆαααΌαααΆααα·ααα·ααααα·αααααΆααα·ααα·αααΆα αααΎα
-
αααααΎαααΈααΈαααΊαααααααα―αααΆαααααααααΆαααααααΌαααΆαααΆαα αΌααααΆαα αααΆααα ααΆαα½αααΉααα·ααΈααΆαααααααα ααΎαα’αΆα ααααΆααααΆαααααΆααααααααΎαααααΌαααΆαααΊααααΌαααΆαααααΎααααΆαααααΆααα·αααααΆαααα αααα»αα―αααΆααααα
-
α αΎααααααΎαααΈααΈααΊααααΌαααααΎαα·ααΈααΆαααααααΆααααΈαααΆαααΎααΆαα½αααααΆα
ααΆα§ααΆα ααα ααΌααααα‘ααααΎααααααΆααααααααααΈαααα»αααααααααΌα
α
ααα’αα $
ααααααα½ααα·αααααααα
αααα»ααααα½α SQL αααααΆαααααΎαα»αααΆαα»αα αααβααΊβααΆαβαα·αβαα
ααΆβααΊβααΆ analogue ααααΆααβααβααα
ααααΈβαααααααΆαααβαααβααΆαβαααα
αβαα
βαααα»α Java α ααα»ααααααααα·αααΎα’αααααααΌαααΆααααααΎα SQL query ααΆααααα ααΆα§ααΆα ααα ααααα·αααΎα’αααααααΌαααΆαααααααΆαααααααααΆααΆα α’αααα’αΆα
ααααΎ operator #$
αααααΉααααα½ααα·αααααααααααααΆαααα
αααα»ααααα½α (ααααΎαααααΌα
ααΆααΆαααααΆααααααα’αααα)α
ααΌαααααΌα
// Π ΠΎΠ±ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ - Π·Π½Π°ΡΠ΅Π½ΠΈΡ, ΠΊΠΎΠ½ΡΡΠΎΠ»ΠΈΡΡΠ΅ΠΌΡΠ΅ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΌ
val table = "coffees"
sql"select * from #$table where name = $name".as[Coffee].headOption
Checkmarx αα·αααΆααααΉαααΈααααααααΎαααΆαααααΎααααΆαα Splicing Literal Values ββαα·αααααααααα·ααααα·αα #$
ααΌα
αααα α
αΌαααΎαααααΆααΆαααααααααΆα±αααααααα’ααααααααΆαααΆαα
αΆαα SQL αααααΆααααααΆαα»αα αα·αααααα
αααααααααααααΉαααααΌααα
αααα»αααΌαα
// ΠΠ°Ρ
ΠΎΠ΄ΠΈΠΌ Π²ΡΠ΅ ΠΈΠΌΠΏΠΎΡΡΡ
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));
}
ααΆααα·α αα α ααααααααα»αααΆααααααΆαααααααααααααΆαααααΎαα αααα»ααααααΆααααααααααΎαα αα
ααΆαααααααααΆα: αααα»αα αα»αααΆα αααΎαααααΎα§ααααααααα½ααα·αα·ααααααααααΎαα αα (ααΆαα’αα»αααα OSA) ααΎααααΈααααΎαααΆαααααΎααααΆαααααααααααΆαααααααααααααααΆααααα αααα»ααααααα·ααΈαααααΆααααααΎαα αααααααααΆαα·αα’αΆα ααααΎαα αα α»ααααααααΆααααααΆααααααααααα ααΆαααααα»ααααα·ααΆαααΆαααα αααα»αβααααΈβααααβααΆαβααααα·αβαα»αααΆα α αΎαβααααβαααβαα·αβααΆαβααααβαα»ααααα·ααΆαβααΆααβααβαααα αααα»αααααΈααα ααΆααα½ααααα αΌαααααΆααααΆαα’αα»αααα SAST αα·α OSA ααΉααα½ααααααααΆαα»αααΆααααααΆααα αααααΆαααααααααααα ααααΆαααΆαααααααααα·αααααΌαααΆαααααΎαα αααα»αααΌααααααα
ααα»ααααααααααα ααΆαα·ααααα
ααααα·α
αΆαααΆ JavaScript ααααααα ααααΆαα·ααααααΆαα·α
αα
ααΆαααΌα
ααΆα
ααΆαααααα»ααααααα ααΆαααααααααααΊααΆαααααααααΆα αααα ααααΆαα·αααα ααα»αααα ααα»αααααααααΆαααΆαααΆααααααΎαααΆααααααααΎααααΆααα§ααΆα αααααααΆαααΆαααααααααα
αααα»ααααΆαααΆαα» lodash
αα
αααα»ααα·ααΈααΆααααα template
ΠΈ *set
.
α§ααΆα αααααααΆαααααΎαααααααΌααααααΆαααααααααα αααα»αα―αααΆα 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!'
α αΎααα αααααααΆαααααααααΆαααααα»α 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>
ααΎααααα»αααααααααα·ααΈααΆααααααααααΆααααααααααΆααα’ααααααααΎα αααααααΌαααΆαααΆααααα»ααααααΈααΆαααΆααααααααα
// ΠΡΠ΅ΠΌ Π²ΡΠ΅ ΡΡΡΠΎΠΊΠΈ: Π² ΠΊΠΎΡΠΎΡΡΡ
Π²ΡΡΡΠ΅ΡΠ°Π΅ΡΡΡ ΡΡΡΠΎΠΊΠ° 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));
ααΆααα·α αα α αααα»αααααααααα·ααααΆαααααααααααΆααααααααα αααα»ααααααα·ααΈ
ααΆαααααααααΆα: ααΆαα·ααααααΆααΏαα ααααααααααααΆαααααααα·ααΈ ααΆαα·αααααΌααααααα αααα»αααΆαααααΎαα·ααααΆαααααα α¬ααααΎααααΈα αΌαααααΎαααΆαααΈααααααααα α¬αααααααααΆαα SSL-Pinningα ααΆααααααααα»ααααα·ααΆα ααΆααααααΆαα»ααααααααααααα αααα»αααΌααα·ααααααΆααΆαα’αα»ααααααα’αααα»ααααααα αααααααΆααΆααααααα αααΆαααααααΉααααααααα―αααΆαααααααααααΆαα αααα»αααααΆααα
// ΠΠ°ΠΉΠ΄Π΅ΠΌ Π²ΡΠ΅ ΡΠ΅ΡΡΠΈΡΠΈΠΊΠ°ΡΡ ΠΏΠΎ ΠΌΠ°ΡΠΊΠ΅ ΡΠ°ΠΉΠ»Π°
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;
ααΆααα·α αα α ααααααααααααΆαααααΆαααααααααΌαααΆααααααααααα½ααα αααα»ααααααα·ααΈ
ααΆαααααααααΆα: ααΆααΏαα ααΆα αΆαααΆα ααααα»αααΆαααα αΌαααΌααΉααααααααΌαααΆααααααααααα½α α¬ααααααΆαααααΆααααααααααααααααΆααα αααα»αααΌαα ααΆααΆααα·αααΆαα ααΆααααααΆαα»ααα½αααΆαα αααα»αααΌαααααααα·ααααααΆαααα·αααα’αα ααα»ααααααααΆαααΆααααααααα½αα ααΌαα’ααα»αα αααααααα½α CxQL ααΆααααααααααΏαααΌα αααααΊααΆααααα½αααΆααα
// ΠΠΎΠ»ΡΡΠ°Π΅ΠΌ Π²ΡΠ΅ ΡΡΡΠΎΠΊΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡΡ Π² ΠΊΠΎΠ΄Π΅
CxList strings = base.Find_Strings();
// ΠΡΠ΅ΠΌ ΡΡΠ΅Π΄ΠΈ Π²ΡΠ΅Ρ
ΡΡΡΠΎΠΊ Π½ΡΠΆΠ½ΠΎΠ΅ Π½Π°ΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅. Π ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΡΠΎΠΊΠ΅Π½ Π² Π²ΠΈΠ΄Π΅ ΡΡΡΠΎΠΊΠΈ "qwerty12345"
result = strings.FindByShortName("qwerty12345");
ααα ααααΈααααα·ααααΆα
αααα»ααααααΉαααΆα’ααααααααααΉαααΆααααααααααααααΆααα’αααααααααα»αα αΆααααααΎαααααΆααααααΆααΆαα½αα§ααααα Checkmarx α αααα ααβααΆβα’αααβαααβααΆαβαααααβα αααΆααβααααΆααβαααα½αβααΆβααΌαβααβα αΎαβααβααΉαβααβααΎαβα’αααΈβαααβααΆαβααααααααβαααα»αβααΆαααααΆαβαααβαααα
ααΆα’αα»αα αα
αα
α»ααααααααΆαααΆαααααααΆαααααΆα ααααααα·αααααΈαα’αΆα
ααααΌαααΆααααααΌααααα»αα’αα‘α»αααααααααΎαα
αααΆαααααααΆαα Checkmarx α αααα αΎαααΆααΌαα ααα»αααααΎαααΆααααααΎα
ααΌααα·αα·αααααΎα!
ααααα: www.habr.com